diff --git a/src/vs/platform/electron/electron-main/electronMainService.ts b/src/vs/platform/electron/electron-main/electronMainService.ts index d51d4b65d3e..706563a76b7 100644 --- a/src/vs/platform/electron/electron-main/electronMainService.ts +++ b/src/vs/platform/electron/electron-main/electronMainService.ts @@ -6,13 +6,15 @@ import { IElectronService } from 'vs/platform/electron/node/electron'; import { IWindowsMainService, ICodeWindow } from 'vs/platform/windows/electron-main/windows'; import { MessageBoxOptions, MessageBoxReturnValue, shell } from 'electron'; +import { ILifecycleMainService } from 'vs/platform/lifecycle/electron-main/lifecycleMainService'; export class ElectronMainService implements IElectronService { _serviceBrand: undefined; constructor( - @IWindowsMainService private readonly windowsMainService: IWindowsMainService + @IWindowsMainService private readonly windowsMainService: IWindowsMainService, + @ILifecycleMainService private readonly lifecycleMainService: ILifecycleMainService ) { } @@ -43,5 +45,9 @@ export class ElectronMainService implements IElectronService { shell.showItemInFolder(path); } + async relaunch(options?: { addArgs?: string[], removeArgs?: string[] }): Promise { + return this.lifecycleMainService.relaunch(options); + } + //#endregion } diff --git a/src/vs/platform/electron/node/electron.ts b/src/vs/platform/electron/node/electron.ts index 8257bf0eee2..a7b455222dc 100644 --- a/src/vs/platform/electron/node/electron.ts +++ b/src/vs/platform/electron/node/electron.ts @@ -20,4 +20,5 @@ export interface IElectronService { // OS showItemInFolder(path: string): Promise; + relaunch(options?: { addArgs?: string[], removeArgs?: string[] }): Promise; } diff --git a/src/vs/platform/environment/node/argvHelper.ts b/src/vs/platform/environment/node/argvHelper.ts index f656fa743b8..1dd2f688934 100644 --- a/src/vs/platform/environment/node/argvHelper.ts +++ b/src/vs/platform/environment/node/argvHelper.ts @@ -7,7 +7,7 @@ import * as assert from 'assert'; import { firstIndex } from 'vs/base/common/arrays'; import { localize } from 'vs/nls'; import { ParsedArgs } from '../common/environment'; -import { MIN_MAX_MEMORY_SIZE_MB } from 'vs/platform/files/common/files'; +import { MIN_MAX_MEMORY_SIZE_MB } from 'vs/platform/files/node/files'; import { parseArgs, ErrorReporter, OPTIONS } from 'vs/platform/environment/node/argv'; function parseAndValidate(cmdLineArgs: string[], reportWarnings: boolean): ParsedArgs { diff --git a/src/vs/platform/files/common/files.ts b/src/vs/platform/files/common/files.ts index ad80919e113..04788f62ec1 100644 --- a/src/vs/platform/files/common/files.ts +++ b/src/vs/platform/files/common/files.ts @@ -754,9 +754,6 @@ export enum FileKind { ROOT_FOLDER } -export const MIN_MAX_MEMORY_SIZE_MB = 2048; -export const FALLBACK_MAX_MEMORY_SIZE_MB = 4096; - /** * A hint to disable etag checking for reading/writing. */ diff --git a/src/vs/platform/files/node/files.ts b/src/vs/platform/files/node/files.ts new file mode 100644 index 00000000000..bbb85376228 --- /dev/null +++ b/src/vs/platform/files/node/files.ts @@ -0,0 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +export const MIN_MAX_MEMORY_SIZE_MB = 2048; +export const FALLBACK_MAX_MEMORY_SIZE_MB = 4096; diff --git a/src/vs/platform/windows/common/windows.ts b/src/vs/platform/windows/common/windows.ts index 8d713a46ec6..fed621d02fe 100644 --- a/src/vs/platform/windows/common/windows.ts +++ b/src/vs/platform/windows/common/windows.ts @@ -133,7 +133,6 @@ export interface IWindowsService { onWindowTitleDoubleClick(windowId: number): Promise; setDocumentEdited(windowId: number, flag: boolean): Promise; quit(): Promise; - relaunch(options: { addArgs?: string[], removeArgs?: string[] }): Promise; // macOS Native Tabs newWindowTab(): Promise; diff --git a/src/vs/platform/windows/common/windowsIpc.ts b/src/vs/platform/windows/common/windowsIpc.ts index a17937f4455..417f1183f69 100644 --- a/src/vs/platform/windows/common/windowsIpc.ts +++ b/src/vs/platform/windows/common/windowsIpc.ts @@ -104,7 +104,6 @@ export class WindowsChannel implements IServerChannel { case 'openNewWindow': return this.service.openNewWindow(arg); case 'openExtensionDevelopmentHostWindow': return this.service.openExtensionDevelopmentHostWindow(arg[0], arg[1]); case 'getWindows': return this.service.getWindows(); - case 'relaunch': return this.service.relaunch(arg[0]); case 'whenSharedProcessReady': return this.service.whenSharedProcessReady(); case 'toggleSharedProcess': return this.service.toggleSharedProcess(); case 'quit': return this.service.quit(); diff --git a/src/vs/platform/windows/electron-browser/windowsService.ts b/src/vs/platform/windows/electron-browser/windowsService.ts index 92808158543..b7694f79b39 100644 --- a/src/vs/platform/windows/electron-browser/windowsService.ts +++ b/src/vs/platform/windows/electron-browser/windowsService.ts @@ -176,10 +176,6 @@ export class WindowsService implements IWindowsService { return this.channel.call('quit'); } - relaunch(options: { addArgs?: string[], removeArgs?: string[] }): Promise { - return this.channel.call('relaunch', [options]); - } - whenSharedProcessReady(): Promise { return this.channel.call('whenSharedProcessReady'); } diff --git a/src/vs/platform/windows/electron-main/windowsService.ts b/src/vs/platform/windows/electron-main/windowsService.ts index 6cdde7c3da8..d4ec3525c66 100644 --- a/src/vs/platform/windows/electron-main/windowsService.ts +++ b/src/vs/platform/windows/electron-main/windowsService.ts @@ -11,7 +11,6 @@ import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/ import { shell, crashReporter, app, Menu } from 'electron'; import { Event } from 'vs/base/common/event'; import { IURLService, IURLHandler } from 'vs/platform/url/common/url'; -import { ILifecycleMainService } from 'vs/platform/lifecycle/electron-main/lifecycleMainService'; import { IWindowsMainService, ISharedProcess, ICodeWindow } from 'vs/platform/windows/electron-main/windows'; import { IRecentlyOpened, IRecent } from 'vs/platform/history/common/history'; import { IHistoryMainService } from 'vs/platform/history/electron-main/historyMainService'; @@ -45,7 +44,6 @@ export class WindowsService extends Disposable implements IWindowsService, IURLH @IWindowsMainService private readonly windowsMainService: IWindowsMainService, @IEnvironmentService private readonly environmentService: IEnvironmentService, @IURLService urlService: IURLService, - @ILifecycleMainService private readonly lifecycleMainService: ILifecycleMainService, @IHistoryMainService private readonly historyMainService: IHistoryMainService, @ILogService private readonly logService: ILogService ) { @@ -359,12 +357,6 @@ export class WindowsService extends Disposable implements IWindowsService, IURLH this.windowsMainService.quit(); } - async relaunch(options: { addArgs?: string[], removeArgs?: string[] }): Promise { - this.logService.trace('windowsService#relaunch'); - - this.lifecycleMainService.relaunch(options); - } - async whenSharedProcessReady(): Promise { this.logService.trace('windowsService#whenSharedProcessReady'); diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index a389464b265..e160a83ca76 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -428,12 +428,6 @@ export class SimpleWindowsService implements IWindowsService { return Promise.resolve(); } - relaunch(_options: { addArgs?: string[], removeArgs?: string[] }): Promise { - window.location.reload(); - - return Promise.resolve(); - } - whenSharedProcessReady(): Promise { return Promise.resolve(); } diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionProfileService.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionProfileService.ts index 9fea9c45b5a..6a2048ac72c 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionProfileService.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensionProfileService.ts @@ -12,7 +12,7 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { StatusbarAlignment, IStatusbarService, IStatusbarEntryAccessor, IStatusbarEntry } from 'vs/platform/statusbar/common/statusbar'; import { IExtensionHostProfileService, ProfileSessionState } from 'vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { IWindowsService } from 'vs/platform/windows/common/windows'; +import { IElectronService } from 'vs/platform/electron/node/electron'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { randomPort } from 'vs/base/node/ports'; import product from 'vs/platform/product/common/product'; @@ -46,7 +46,7 @@ export class ExtensionHostProfileService extends Disposable implements IExtensio @IExtensionService private readonly _extensionService: IExtensionService, @IEditorService private readonly _editorService: IEditorService, @IInstantiationService private readonly _instantiationService: IInstantiationService, - @IWindowsService private readonly _windowsService: IWindowsService, + @IElectronService private readonly _electronService: IElectronService, @IDialogService private readonly _dialogService: IDialogService, @IStatusbarService private readonly _statusbarService: IStatusbarService, ) { @@ -122,7 +122,7 @@ export class ExtensionHostProfileService extends Disposable implements IExtensio secondaryButton: nls.localize('cancel', "Cancel") }).then(res => { if (res.confirmed) { - this._windowsService.relaunch({ addArgs: [`--inspect-extensions=${randomPort()}`] }); + this._electronService.relaunch({ addArgs: [`--inspect-extensions=${randomPort()}`] }); } }); } diff --git a/src/vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor.ts b/src/vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor.ts index c52e1372a2b..f830027784b 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor.ts @@ -24,7 +24,8 @@ import { RunOnceScheduler } from 'vs/base/common/async'; import { clipboard } from 'electron'; import { EnablementState } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; -import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows'; +import { IWindowService } from 'vs/platform/windows/common/windows'; +import { IElectronService } from 'vs/platform/electron/node/electron'; import { writeFile } from 'vs/base/node/pfs'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { memoize } from 'vs/base/common/decorators'; @@ -536,7 +537,7 @@ export class DebugExtensionHostAction extends Action { constructor( @IDebugService private readonly _debugService: IDebugService, - @IWindowsService private readonly _windowsService: IWindowsService, + @IElectronService private readonly _electronService: IElectronService, @IDialogService private readonly _dialogService: IDialogService, @IExtensionService private readonly _extensionService: IExtensionService, ) { @@ -555,7 +556,7 @@ export class DebugExtensionHostAction extends Action { secondaryButton: nls.localize('cancel', "Cancel") }); if (res.confirmed) { - this._windowsService.relaunch({ addArgs: [`--inspect-extensions=${randomPort()}`] }); + this._electronService.relaunch({ addArgs: [`--inspect-extensions=${randomPort()}`] }); } } diff --git a/src/vs/workbench/contrib/files/browser/editors/textFileEditor.ts b/src/vs/workbench/contrib/files/browser/editors/textFileEditor.ts index 6afa675b8e6..7174fe0929b 100644 --- a/src/vs/workbench/contrib/files/browser/editors/textFileEditor.ts +++ b/src/vs/workbench/contrib/files/browser/editors/textFileEditor.ts @@ -16,16 +16,15 @@ import { EditorOptions, TextEditorOptions, IEditorCloseEvent } from 'vs/workbenc import { BinaryEditorModel } from 'vs/workbench/common/editor/binaryEditorModel'; import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; -import { FileOperationError, FileOperationResult, FileChangesEvent, IFileService, FALLBACK_MAX_MEMORY_SIZE_MB, MIN_MAX_MEMORY_SIZE_MB } from 'vs/platform/files/common/files'; +import { FileOperationError, FileOperationResult, FileChangesEvent, IFileService } from 'vs/platform/files/common/files'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { ScrollType } from 'vs/editor/common/editorCommon'; -import { IWindowsService, IWindowService } from 'vs/platform/windows/common/windows'; +import { IWindowService } from 'vs/platform/windows/common/windows'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroupsService, IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService'; import { CancellationToken } from 'vs/base/common/cancellation'; @@ -56,8 +55,6 @@ export class TextFileEditor extends BaseTextEditor { @IThemeService themeService: IThemeService, @IEditorGroupsService editorGroupService: IEditorGroupsService, @ITextFileService textFileService: ITextFileService, - @IWindowsService private readonly windowsService: IWindowsService, - @IPreferencesService private readonly preferencesService: IPreferencesService, @IWindowService windowService: IWindowService, @IExplorerService private readonly explorerService: IExplorerService ) { @@ -167,63 +164,48 @@ export class TextFileEditor extends BaseTextEditor { // Readonly flag textEditor.updateOptions({ readOnly: textFileModel.isReadonly() }); } catch (error) { - - // In case we tried to open a file inside the text editor and the response - // indicates that this is not a text file, reopen the file through the binary - // editor. - if ((error).textFileOperationResult === TextFileOperationResult.FILE_IS_BINARY) { - return this.openAsBinary(input, options); - } - - // Similar, handle case where we were asked to open a folder in the text editor. - if ((error).fileOperationResult === FileOperationResult.FILE_IS_DIRECTORY) { - this.openAsFolder(input); - - throw new Error(nls.localize('openFolderError', "File is a directory")); - } - - // Offer to create a file from the error if we have a file not found and the name is valid - if ((error).fileOperationResult === FileOperationResult.FILE_NOT_FOUND && isValidBasename(basename(input.getResource()))) { - throw createErrorWithActions(toErrorMessage(error), { - actions: [ - new Action('workbench.files.action.createMissingFile', nls.localize('createFile', "Create File"), undefined, true, async () => { - await this.textFileService.create(input.getResource()); - - return this.editorService.openEditor({ - resource: input.getResource(), - options: { - pinned: true // new file gets pinned by default - } - }); - }) - ] - }); - } - - if ((error).fileOperationResult === FileOperationResult.FILE_EXCEED_MEMORY_LIMIT) { - const memoryLimit = Math.max(MIN_MAX_MEMORY_SIZE_MB, +this.configurationService.getValue(undefined, 'files.maxMemoryForLargeFilesMB') || FALLBACK_MAX_MEMORY_SIZE_MB); - - throw createErrorWithActions(toErrorMessage(error), { - actions: [ - new Action('workbench.window.action.relaunchWithIncreasedMemoryLimit', nls.localize('relaunchWithIncreasedMemoryLimit', "Restart with {0} MB", memoryLimit), undefined, true, () => { - return this.windowsService.relaunch({ - addArgs: [ - `--max-memory=${memoryLimit}` - ] - }); - }), - new Action('workbench.window.action.configureMemoryLimit', nls.localize('configureMemoryLimit', 'Configure Memory Limit'), undefined, true, () => { - return this.preferencesService.openGlobalSettings(undefined, { query: 'files.maxMemoryForLargeFilesMB' }); - }) - ] - }); - } - - // Otherwise make sure the error bubbles up - throw error; + this.handleSetInputError(error, input, options); } } + protected handleSetInputError(error: Error, input: FileEditorInput, options: EditorOptions | undefined): void { + + // In case we tried to open a file inside the text editor and the response + // indicates that this is not a text file, reopen the file through the binary + // editor. + if ((error).textFileOperationResult === TextFileOperationResult.FILE_IS_BINARY) { + return this.openAsBinary(input, options); + } + + // Similar, handle case where we were asked to open a folder in the text editor. + if ((error).fileOperationResult === FileOperationResult.FILE_IS_DIRECTORY) { + this.openAsFolder(input); + + throw new Error(nls.localize('openFolderError', "File is a directory")); + } + + // Offer to create a file from the error if we have a file not found and the name is valid + if ((error).fileOperationResult === FileOperationResult.FILE_NOT_FOUND && isValidBasename(basename(input.getResource()))) { + throw createErrorWithActions(toErrorMessage(error), { + actions: [ + new Action('workbench.files.action.createMissingFile', nls.localize('createFile', "Create File"), undefined, true, async () => { + await this.textFileService.create(input.getResource()); + + return this.editorService.openEditor({ + resource: input.getResource(), + options: { + pinned: true // new file gets pinned by default + } + }); + }) + ] + }); + } + + // Otherwise make sure the error bubbles up + throw error; + } + private openAsBinary(input: FileEditorInput, options: EditorOptions | undefined): void { input.setForceOpenAsBinary(); diff --git a/src/vs/workbench/contrib/files/browser/files.contribution.ts b/src/vs/workbench/contrib/files/browser/files.contribution.ts index 19fcd5b0acb..4b609dc4174 100644 --- a/src/vs/workbench/contrib/files/browser/files.contribution.ts +++ b/src/vs/workbench/contrib/files/browser/files.contribution.ts @@ -18,7 +18,6 @@ import { VIEWLET_ID, SortOrderConfiguration, FILE_EDITOR_INPUT_ID, IExplorerServ import { FileEditorTracker } from 'vs/workbench/contrib/files/browser/editors/fileEditorTracker'; import { SaveErrorHandler } from 'vs/workbench/contrib/files/browser/saveErrorHandler'; import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput'; -import { TextFileEditor } from 'vs/workbench/contrib/files/browser/editors/textFileEditor'; import { BinaryFileEditor } from 'vs/workbench/contrib/files/browser/editors/binaryFileEditor'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; @@ -99,17 +98,6 @@ registry.registerWorkbenchAction( ); // Register file editors -Registry.as(EditorExtensions.Editors).registerEditor( - new EditorDescriptor( - TextFileEditor, - TextFileEditor.ID, - nls.localize('textFileEditor', "Text File Editor") - ), - [ - new SyncDescriptor(FileEditorInput) - ] -); - Registry.as(EditorExtensions.Editors).registerEditor( new EditorDescriptor( BinaryFileEditor, @@ -339,7 +327,8 @@ configurationRegistry.registerConfiguration({ 'files.maxMemoryForLargeFilesMB': { 'type': 'number', 'default': 4096, - 'markdownDescription': nls.localize('maxMemoryForLargeFilesMB', "Controls the memory available to VS Code after restart when trying to open large files. Same effect as specifying `--max-memory=NEWSIZE` on the command line.") + 'markdownDescription': nls.localize('maxMemoryForLargeFilesMB', "Controls the memory available to VS Code after restart when trying to open large files. Same effect as specifying `--max-memory=NEWSIZE` on the command line."), + included: platform.isNative }, 'files.simpleDialog.enable': { 'type': 'boolean', diff --git a/src/vs/workbench/contrib/files/browser/files.web.contribution.ts b/src/vs/workbench/contrib/files/browser/files.web.contribution.ts new file mode 100644 index 00000000000..44d91d66b91 --- /dev/null +++ b/src/vs/workbench/contrib/files/browser/files.web.contribution.ts @@ -0,0 +1,24 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as nls from 'vs/nls'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { EditorInput } from 'vs/workbench/common/editor'; +import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput'; +import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; +import { IEditorRegistry, EditorDescriptor, Extensions as EditorExtensions } from 'vs/workbench/browser/editor'; +import { TextFileEditor } from 'vs/workbench/contrib/files/browser/editors/textFileEditor'; + +// Register file editor +Registry.as(EditorExtensions.Editors).registerEditor( + new EditorDescriptor( + TextFileEditor, + TextFileEditor.ID, + nls.localize('textFileEditor', "Text File Editor") + ), + [ + new SyncDescriptor(FileEditorInput) + ] +); diff --git a/src/vs/workbench/contrib/files/electron-browser/files.contribution.ts b/src/vs/workbench/contrib/files/electron-browser/files.contribution.ts new file mode 100644 index 00000000000..d5d18ac24ea --- /dev/null +++ b/src/vs/workbench/contrib/files/electron-browser/files.contribution.ts @@ -0,0 +1,24 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as nls from 'vs/nls'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { EditorInput } from 'vs/workbench/common/editor'; +import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput'; +import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; +import { IEditorRegistry, EditorDescriptor, Extensions as EditorExtensions } from 'vs/workbench/browser/editor'; +import { NativeTextFileEditor } from 'vs/workbench/contrib/files/electron-browser/textFileEditor'; + +// Register file editor +Registry.as(EditorExtensions.Editors).registerEditor( + new EditorDescriptor( + NativeTextFileEditor, + NativeTextFileEditor.ID, + nls.localize('textFileEditor', "Text File Editor") + ), + [ + new SyncDescriptor(FileEditorInput) + ] +); diff --git a/src/vs/workbench/contrib/files/electron-browser/textFileEditor.ts b/src/vs/workbench/contrib/files/electron-browser/textFileEditor.ts new file mode 100644 index 00000000000..bb715358319 --- /dev/null +++ b/src/vs/workbench/contrib/files/electron-browser/textFileEditor.ts @@ -0,0 +1,80 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as nls from 'vs/nls'; +import { TextFileEditor } from 'vs/workbench/contrib/files/browser/editors/textFileEditor'; +import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput'; +import { EditorOptions } from 'vs/workbench/common/editor'; +import { FileOperationError, FileOperationResult, IFileService } from 'vs/platform/files/common/files'; +import { MIN_MAX_MEMORY_SIZE_MB, FALLBACK_MAX_MEMORY_SIZE_MB } from 'vs/platform/files/node/files'; +import { createErrorWithActions } from 'vs/base/common/errorsWithActions'; +import { toErrorMessage } from 'vs/base/common/errorMessage'; +import { Action } from 'vs/base/common/actions'; +import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { IStorageService } from 'vs/platform/storage/common/storage'; +import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; +import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; +import { IWindowService } from 'vs/platform/windows/common/windows'; +import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences'; +import { IExplorerService } from 'vs/workbench/contrib/files/common/files'; +import { IElectronService } from 'vs/platform/electron/node/electron'; + +/** + * An implementation of editor for file system resources. + */ +export class NativeTextFileEditor extends TextFileEditor { + + constructor( + @ITelemetryService telemetryService: ITelemetryService, + @IFileService fileService: IFileService, + @IViewletService viewletService: IViewletService, + @IInstantiationService instantiationService: IInstantiationService, + @IWorkspaceContextService contextService: IWorkspaceContextService, + @IStorageService storageService: IStorageService, + @ITextResourceConfigurationService configurationService: ITextResourceConfigurationService, + @IEditorService editorService: IEditorService, + @IThemeService themeService: IThemeService, + @IEditorGroupsService editorGroupService: IEditorGroupsService, + @ITextFileService textFileService: ITextFileService, + @IElectronService private readonly electronService: IElectronService, + @IPreferencesService private readonly preferencesService: IPreferencesService, + @IWindowService windowService: IWindowService, + @IExplorerService explorerService: IExplorerService + ) { + super(telemetryService, fileService, viewletService, instantiationService, contextService, storageService, configurationService, editorService, themeService, editorGroupService, textFileService, windowService, explorerService); + } + + protected handleSetInputError(error: Error, input: FileEditorInput, options: EditorOptions | undefined): void { + + // Allow to restart with higher memory limit if the file is too large + if ((error).fileOperationResult === FileOperationResult.FILE_EXCEED_MEMORY_LIMIT) { + const memoryLimit = Math.max(MIN_MAX_MEMORY_SIZE_MB, +this.configurationService.getValue(undefined, 'files.maxMemoryForLargeFilesMB') || FALLBACK_MAX_MEMORY_SIZE_MB); + + throw createErrorWithActions(toErrorMessage(error), { + actions: [ + new Action('workbench.window.action.relaunchWithIncreasedMemoryLimit', nls.localize('relaunchWithIncreasedMemoryLimit', "Restart with {0} MB", memoryLimit), undefined, true, () => { + return this.electronService.relaunch({ + addArgs: [ + `--max-memory=${memoryLimit}` + ] + }); + }), + new Action('workbench.window.action.configureMemoryLimit', nls.localize('configureMemoryLimit', 'Configure Memory Limit'), undefined, true, () => { + return this.preferencesService.openGlobalSettings(undefined, { query: 'files.maxMemoryForLargeFilesMB' }); + }) + ] + }); + } + + // Fallback to handling in super type + super.handleSetInputError(error, input, options); + } +} diff --git a/src/vs/workbench/contrib/localizations/browser/localizations.contribution.ts b/src/vs/workbench/contrib/localizations/browser/localizations.contribution.ts index 97316f9b4a2..c54cfc05fc8 100644 --- a/src/vs/workbench/contrib/localizations/browser/localizations.contribution.ts +++ b/src/vs/workbench/contrib/localizations/browser/localizations.contribution.ts @@ -20,7 +20,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import Severity from 'vs/base/common/severity'; import { IJSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditing'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { IWindowsService } from 'vs/platform/windows/common/windows'; +import { IHostService } from 'vs/workbench/services/host/browser/host'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { VIEWLET_ID as EXTENSIONS_VIEWLET_ID, IExtensionsViewlet } from 'vs/workbench/contrib/extensions/common/extensions'; @@ -39,7 +39,7 @@ export class LocalizationWorkbenchContribution extends Disposable implements IWo @INotificationService private readonly notificationService: INotificationService, @IJSONEditingService private readonly jsonEditingService: IJSONEditingService, @IEnvironmentService private readonly environmentService: IEnvironmentService, - @IWindowsService private readonly windowsService: IWindowsService, + @IHostService private readonly hostService: IHostService, @IStorageService private readonly storageService: IStorageService, @IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService, @IExtensionGalleryService private readonly galleryService: IExtensionGalleryService, @@ -80,7 +80,7 @@ export class LocalizationWorkbenchContribution extends Disposable implements IWo label: updateAndRestart ? localize('yes', "Yes") : localize('restart now', "Restart Now"), run: () => { const updatePromise = updateAndRestart ? this.jsonEditingService.write(this.environmentService.localeResource, [{ key: 'locale', value: locale }], true) : Promise.resolve(undefined); - updatePromise.then(() => this.windowsService.relaunch({}), e => this.notificationService.error(e)); + updatePromise.then(() => this.hostService.restart(), e => this.notificationService.error(e)); } }], { @@ -170,7 +170,7 @@ export class LocalizationWorkbenchContribution extends Disposable implements IWo label: translations['installAndRestart'], run: () => { logUserReaction('installAndRestart'); - this.installExtension(extensionToInstall).then(() => this.windowsService.relaunch({})); + this.installExtension(extensionToInstall).then(() => this.hostService.restart()); } }; diff --git a/src/vs/workbench/contrib/localizations/browser/localizationsActions.ts b/src/vs/workbench/contrib/localizations/browser/localizationsActions.ts index 52369547475..cd04dd6149c 100644 --- a/src/vs/workbench/contrib/localizations/browser/localizationsActions.ts +++ b/src/vs/workbench/contrib/localizations/browser/localizationsActions.ts @@ -9,7 +9,7 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { ILocalizationsService, LanguageType } from 'vs/platform/localizations/common/localizations'; import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; import { IJSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditing'; -import { IWindowsService } from 'vs/platform/windows/common/windows'; +import { IHostService } from 'vs/workbench/services/host/browser/host'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { language } from 'vs/base/common/platform'; import { firstIndex } from 'vs/base/common/arrays'; @@ -26,7 +26,7 @@ export class ConfigureLocaleAction extends Action { @ILocalizationsService private readonly localizationService: ILocalizationsService, @IQuickInputService private readonly quickInputService: IQuickInputService, @IJSONEditingService private readonly jsonEditingService: IJSONEditingService, - @IWindowsService private readonly windowsService: IWindowsService, + @IHostService private readonly hostService: IHostService, @INotificationService private readonly notificationService: INotificationService, @IViewletService private readonly viewletService: IViewletService, @IDialogService private readonly dialogService: IDialogService @@ -74,7 +74,7 @@ export class ConfigureLocaleAction extends Action { }); if (restart.confirmed) { - this.windowsService.relaunch({}); + this.hostService.restart(); } } } catch (e) { diff --git a/src/vs/workbench/contrib/performance/electron-browser/startupProfiler.ts b/src/vs/workbench/contrib/performance/electron-browser/startupProfiler.ts index 0509b63e0d3..e4039966c6e 100644 --- a/src/vs/workbench/contrib/performance/electron-browser/startupProfiler.ts +++ b/src/vs/workbench/contrib/performance/electron-browser/startupProfiler.ts @@ -11,7 +11,6 @@ import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import product from 'vs/platform/product/common/product'; -import { IWindowsService } from 'vs/platform/windows/common/windows'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { PerfviewInput } from 'vs/workbench/contrib/performance/electron-browser/perfviewEditor'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; @@ -23,7 +22,6 @@ import { IElectronService } from 'vs/platform/electron/node/electron'; export class StartupProfiler implements IWorkbenchContribution { constructor( - @IWindowsService private readonly _windowsService: IWindowsService, @IDialogService private readonly _dialogService: IDialogService, @IEnvironmentService private readonly _environmentService: IEnvironmentService, @ITextModelService private readonly _textModelResolverService: ITextModelService, @@ -95,13 +93,13 @@ export class StartupProfiler implements IWorkbenchContribution { secondaryButton: undefined }).then(() => { // now we are ready to restart - this._windowsService.relaunch({ removeArgs }); + this._electronService.relaunch({ removeArgs }); }); }); } else { // simply restart - this._windowsService.relaunch({ removeArgs }); + this._electronService.relaunch({ removeArgs }); } }); }); diff --git a/src/vs/workbench/contrib/relauncher/common/relauncher.contribution.ts b/src/vs/workbench/contrib/relauncher/browser/relauncher.contribution.ts similarity index 97% rename from src/vs/workbench/contrib/relauncher/common/relauncher.contribution.ts rename to src/vs/workbench/contrib/relauncher/browser/relauncher.contribution.ts index 2ea826a64e4..688ea065c5c 100644 --- a/src/vs/workbench/contrib/relauncher/common/relauncher.contribution.ts +++ b/src/vs/workbench/contrib/relauncher/browser/relauncher.contribution.ts @@ -6,7 +6,8 @@ import { IDisposable, dispose, Disposable, toDisposable } from 'vs/base/common/lifecycle'; import { IWorkbenchContributionsRegistry, IWorkbenchContribution, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; import { Registry } from 'vs/platform/registry/common/platform'; -import { IWindowsService, IWindowService, IWindowsConfiguration } from 'vs/platform/windows/common/windows'; +import { IWindowService, IWindowsConfiguration } from 'vs/platform/windows/common/windows'; +import { IHostService } from 'vs/workbench/services/host/browser/host'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { localize } from 'vs/nls'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; @@ -39,7 +40,7 @@ export class SettingsChangeRelauncher extends Disposable implements IWorkbenchCo private debugConsoleWordWrap: boolean | undefined; constructor( - @IWindowsService private readonly windowsService: IWindowsService, + @IHostService private readonly hostService: IHostService, @IWindowService private readonly windowService: IWindowService, @IConfigurationService private readonly configurationService: IConfigurationService, @IEnvironmentService private readonly envService: IEnvironmentService, @@ -117,7 +118,7 @@ export class SettingsChangeRelauncher extends Disposable implements IWorkbenchCo isNative ? localize('restart', "&&Restart") : localize('restartWeb', "&&Reload"), - () => this.windowsService.relaunch(Object.create(null)) + () => this.hostService.restart() ); } } diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts index 5985f801f2c..8c65cc8e949 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts @@ -25,7 +25,8 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows'; +import { IWindowService } from 'vs/platform/windows/common/windows'; +import { IHostService } from 'vs/workbench/services/host/browser/host'; import { IExtensionService, toExtension } from 'vs/workbench/services/extensions/common/extensions'; import { ExtensionHostProcessManager } from 'vs/workbench/services/extensions/common/extensionHostProcessManager'; import { ExtensionIdentifier, IExtension, ExtensionType, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; @@ -379,8 +380,8 @@ export class ExtensionService extends AbstractExtensionService implements IExten label: nls.localize('relaunch', "Relaunch VS Code"), run: () => { this._instantiationService.invokeFunction((accessor) => { - const windowsService = accessor.get(IWindowsService); - windowsService.relaunch({}); + const hostService = accessor.get(IHostService); + hostService.restart(); }); } }] diff --git a/src/vs/workbench/services/host/browser/browserHostService.ts b/src/vs/workbench/services/host/browser/browserHostService.ts index a452c20287c..50d2b4d49df 100644 --- a/src/vs/workbench/services/host/browser/browserHostService.ts +++ b/src/vs/workbench/services/host/browser/browserHostService.ts @@ -15,6 +15,10 @@ export class BrowserHostService implements IHostService { readonly windowCount = Promise.resolve(1); //#endregion + + async restart(): Promise { + window.location.reload(); + } } registerSingleton(IHostService, BrowserHostService, true); diff --git a/src/vs/workbench/services/host/browser/host.ts b/src/vs/workbench/services/host/browser/host.ts index 735b21869e9..f865bc96950 100644 --- a/src/vs/workbench/services/host/browser/host.ts +++ b/src/vs/workbench/services/host/browser/host.ts @@ -19,4 +19,6 @@ export interface IHostService { readonly windowCount: Promise; //#endregion + + restart(): Promise; } diff --git a/src/vs/workbench/services/host/electron-browser/desktopHostService.ts b/src/vs/workbench/services/host/electron-browser/desktopHostService.ts index 833310b965c..acdef58cb7d 100644 --- a/src/vs/workbench/services/host/electron-browser/desktopHostService.ts +++ b/src/vs/workbench/services/host/electron-browser/desktopHostService.ts @@ -18,6 +18,10 @@ export class DesktopHostService implements IHostService { get windowCount() { return this.electronService.windowCount(); } //#endregion + + restart(): Promise { + return this.electronService.relaunch(); + } } registerSingleton(IHostService, DesktopHostService, true); diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index 4ed07ea15ed..f3ae4daea12 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -1461,10 +1461,6 @@ export class TestWindowsService implements IWindowsService { return Promise.resolve(); } - relaunch(_options: { addArgs?: string[], removeArgs?: string[] }): Promise { - return Promise.resolve(); - } - whenSharedProcessReady(): Promise { return Promise.resolve(); } @@ -1636,4 +1632,8 @@ export class TestHostService implements IHostService { _serviceBrand: undefined; windowCount = Promise.resolve(1); + + restart(): Promise { + return Promise.resolve(); + } } diff --git a/src/vs/workbench/workbench.common.main.ts b/src/vs/workbench/workbench.common.main.ts index 8b65d5e4942..f51d0394c53 100644 --- a/src/vs/workbench/workbench.common.main.ts +++ b/src/vs/workbench/workbench.common.main.ts @@ -196,7 +196,7 @@ import 'vs/workbench/contrib/terminal/browser/terminalQuickOpen'; import 'vs/workbench/contrib/terminal/browser/terminalPanel'; // Relauncher -import 'vs/workbench/contrib/relauncher/common/relauncher.contribution'; +import 'vs/workbench/contrib/relauncher/browser/relauncher.contribution'; // Tasks import 'vs/workbench/contrib/tasks/browser/task.contribution'; diff --git a/src/vs/workbench/workbench.desktop.main.ts b/src/vs/workbench/workbench.desktop.main.ts index 7369bc83800..0f8210140cd 100644 --- a/src/vs/workbench/workbench.desktop.main.ts +++ b/src/vs/workbench/workbench.desktop.main.ts @@ -103,6 +103,7 @@ import 'vs/workbench/contrib/stats/electron-browser/stats.contribution'; import 'vs/workbench/contrib/splash/electron-browser/partsSplash.contribution'; // Explorer +import 'vs/workbench/contrib/files/electron-browser/files.contribution'; import 'vs/workbench/contrib/files/electron-browser/fileActions.contribution'; // Debug diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index be0ad2cf0b1..5d5d863d8bb 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -81,6 +81,9 @@ registerSingleton(IUserDataSyncService, UserDataSyncService); //#region --- workbench contributions +// Explorer +import 'vs/workbench/contrib/files/browser/files.web.contribution'; + // Preferences import 'vs/workbench/contrib/preferences/browser/keyboardLayoutPicker';