diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index b3832d12ec4..1623761f656 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -86,6 +86,7 @@ import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cance import { IExtensionUrlTrustService } from 'vs/platform/extensionManagement/common/extensionUrlTrust'; import { ExtensionUrlTrustService } from 'vs/platform/extensionManagement/node/extensionUrlTrustService'; import { once } from 'vs/base/common/functional'; +import { getRemoteAuthority } from 'vs/platform/remote/common/remoteHosts'; /** * The main VS Code application. There will only ever be one instance, @@ -757,7 +758,8 @@ export class CodeApplication extends Disposable { context: OpenContext.API, cli: { ...environmentService.args }, forceEmpty: true, - gotoLineMode: true + gotoLineMode: true, + remoteAuthority: getRemoteAuthority(uri) }); await window.ready(); @@ -792,6 +794,7 @@ export class CodeApplication extends Disposable { const hasFileURIs = !!args['file-uri']; const noRecentEntry = args['skip-add-to-recently-opened'] === true; const waitMarkerFileURI = args.wait && args.waitMarkerFilePath ? URI.file(args.waitMarkerFilePath) : undefined; + const remoteAuthority = args.remote || undefined; // check for a pending window to open from URI // e.g. when running code with --open-uri from @@ -815,7 +818,8 @@ export class CodeApplication extends Disposable { forceEmpty: true, noRecentEntry, waitMarkerFileURI, - initialStartup: true + initialStartup: true, + remoteAuthority }); } @@ -840,7 +844,8 @@ export class CodeApplication extends Disposable { noRecentEntry, waitMarkerFileURI, gotoLineMode: args.goto, - initialStartup: true + initialStartup: true, + remoteAuthority }); } diff --git a/src/vs/platform/launch/electron-main/launchMainService.ts b/src/vs/platform/launch/electron-main/launchMainService.ts index c613f990407..2a28c9ee659 100644 --- a/src/vs/platform/launch/electron-main/launchMainService.ts +++ b/src/vs/platform/launch/electron-main/launchMainService.ts @@ -119,14 +119,16 @@ export class LaunchMainService implements ILaunchMainService { let usedWindows: ICodeWindow[] = []; const waitMarkerFileURI = args.wait && args.waitMarkerFilePath ? URI.file(args.waitMarkerFilePath) : undefined; + const remoteAuthority = args.remote || undefined; // Special case extension development if (!!args.extensionDevelopmentPath) { - this.windowsMainService.openExtensionDevelopmentHostWindow(args.extensionDevelopmentPath, { context, cli: args, userEnv, waitMarkerFileURI }); + this.windowsMainService.openExtensionDevelopmentHostWindow(args.extensionDevelopmentPath, { context, cli: args, userEnv, waitMarkerFileURI, remoteAuthority }); } // Start without file/folder arguments else if (!args._.length && !args['folder-uri'] && !args['file-uri']) { + let openNewWindow = false; // Force new window @@ -163,7 +165,8 @@ export class LaunchMainService implements ILaunchMainService { userEnv, forceNewWindow: true, forceEmpty: true, - waitMarkerFileURI + waitMarkerFileURI, + remoteAuthority }); } @@ -175,7 +178,7 @@ export class LaunchMainService implements ILaunchMainService { usedWindows = [lastActive]; } else { - usedWindows = this.windowsMainService.open({ context, cli: args, forceEmpty: true }); + usedWindows = this.windowsMainService.open({ context, cli: args, forceEmpty: true, remoteAuthority }); } } } @@ -193,7 +196,8 @@ export class LaunchMainService implements ILaunchMainService { addMode: args.add, noRecentEntry: !!args['skip-add-to-recently-opened'], waitMarkerFileURI, - gotoLineMode: args.goto + gotoLineMode: args.goto, + remoteAuthority }); } diff --git a/src/vs/platform/native/electron-main/nativeHostMainService.ts b/src/vs/platform/native/electron-main/nativeHostMainService.ts index 9007e3216da..60915434baa 100644 --- a/src/vs/platform/native/electron-main/nativeHostMainService.ts +++ b/src/vs/platform/native/electron-main/nativeHostMainService.ts @@ -161,7 +161,8 @@ export class NativeHostMainService extends Disposable implements INativeHostMain addMode: options.addMode, gotoLineMode: options.gotoLineMode, noRecentEntry: options.noRecentEntry, - waitMarkerFileURI: options.waitMarkerFileURI + waitMarkerFileURI: options.waitMarkerFileURI, + remoteAuthority: options.remoteAuthority }); } } @@ -309,7 +310,8 @@ export class NativeHostMainService extends Disposable implements INativeHostMain contextWindowId: windowId, cli: this.environmentMainService.args, urisToOpen: openable, - forceNewWindow: options.forceNewWindow + forceNewWindow: options.forceNewWindow, + remoteAuthority: undefined // always local }); } @@ -521,7 +523,7 @@ export class NativeHostMainService extends Disposable implements INativeHostMain //#region macOS Touchbar async newWindowTab(): Promise { - this.windowsMainService.open({ context: OpenContext.API, cli: this.environmentMainService.args, forceNewTabbedWindow: true, forceEmpty: true }); + this.windowsMainService.open({ context: OpenContext.API, cli: this.environmentMainService.args, forceNewTabbedWindow: true, forceEmpty: true, remoteAuthority: this.environmentMainService.args.remote || undefined }); } async showPreviousWindowTab(): Promise { diff --git a/src/vs/platform/windows/common/windows.ts b/src/vs/platform/windows/common/windows.ts index 02aeb30e0bc..65f5ba315c5 100644 --- a/src/vs/platform/windows/common/windows.ts +++ b/src/vs/platform/windows/common/windows.ts @@ -19,6 +19,7 @@ export const WindowMinimumSize = { export interface IBaseOpenWindowsOptions { readonly forceReuseWindow?: boolean; + readonly remoteAuthority?: string; } export interface IOpenWindowOptions extends IBaseOpenWindowsOptions { @@ -48,7 +49,6 @@ export interface IOpenedWindow { } export interface IOpenEmptyWindowOptions extends IBaseOpenWindowsOptions { - readonly remoteAuthority?: string; } export type IWindowOpenable = IWorkspaceToOpen | IFolderToOpen | IFileToOpen; diff --git a/src/vs/platform/windows/electron-main/windows.ts b/src/vs/platform/windows/electron-main/windows.ts index 96f92d28946..2ac9b935845 100644 --- a/src/vs/platform/windows/electron-main/windows.ts +++ b/src/vs/platform/windows/electron-main/windows.ts @@ -197,6 +197,7 @@ export interface IOpenConfiguration extends IBaseOpenConfiguration { readonly gotoLineMode?: boolean; readonly initialStartup?: boolean; readonly noRecentEntry?: boolean; + readonly remoteAuthority?: string; } export interface IOpenEmptyConfiguration extends IBaseOpenConfiguration { } diff --git a/src/vs/platform/windows/electron-main/windowsMainService.ts b/src/vs/platform/windows/electron-main/windowsMainService.ts index f68cf41be11..e23a4b15dc3 100644 --- a/src/vs/platform/windows/electron-main/windowsMainService.ts +++ b/src/vs/platform/windows/electron-main/windowsMainService.ts @@ -160,16 +160,12 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic openEmptyWindow(openConfig: IOpenEmptyConfiguration, options?: IOpenEmptyWindowOptions): ICodeWindow[] { let cli = this.environmentMainService.args; - const remote = options?.remoteAuthority; - if (cli && (cli.remote !== remote)) { - cli = { ...cli, remote }; - } - + const remoteAuthority = options?.remoteAuthority; const forceEmpty = true; const forceReuseWindow = options?.forceReuseWindow; const forceNewWindow = !forceReuseWindow; - return this.open({ ...openConfig, cli, forceEmpty, forceNewWindow, forceReuseWindow }); + return this.open({ ...openConfig, cli, forceEmpty, forceNewWindow, forceReuseWindow, remoteAuthority }); } open(openConfig: IOpenConfiguration): ICodeWindow[] { @@ -507,7 +503,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic emptyToOpen++; } - const remoteAuthority = filesToOpen ? filesToOpen.remoteAuthority : (openConfig.cli && openConfig.cli.remote || undefined); + const remoteAuthority = filesToOpen ? filesToOpen.remoteAuthority : openConfig.remoteAuthority; for (let i = 0; i < emptyToOpen; i++) { addUsedWindow(this.doOpenEmpty(openConfig, openFolderInNewWindow, remoteAuthority, filesToOpen), !!filesToOpen); @@ -650,7 +646,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic private doExtractPathsFromAPI(openConfig: IOpenConfiguration): IPathToOpen[] { const pathsToOpen: IPathToOpen[] = []; - const pathResolveOptions: IPathResolveOptions = { gotoLineMode: openConfig.gotoLineMode }; + const pathResolveOptions: IPathResolveOptions = { gotoLineMode: openConfig.gotoLineMode, remoteAuthority: openConfig.remoteAuthority }; for (const pathToOpen of coalesce(openConfig.urisToOpen || [])) { const path = this.resolveOpenable(pathToOpen, pathResolveOptions); @@ -1060,11 +1056,12 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic } } - let authority = ''; + let authority = openConfig.remoteAuthority; for (const extensionDevelopmentPath of extensionDevelopmentPaths) { if (extensionDevelopmentPath.match(/^[a-zA-Z][a-zA-Z0-9\+\-\.]+:/)) { const url = URI.parse(extensionDevelopmentPath); - if (url.scheme === Schemas.vscodeRemote) { + const remoteAuhtority = getRemoteAuthority(url); + if (remoteAuhtority) { if (authority) { if (url.authority !== authority) { this.logService.error('more than one extension development path authority'); @@ -1086,7 +1083,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic return false; } - return uri.authority === authority; + return getRemoteAuthority(uri) === authority; }); folderUris = folderUris.filter(folderUriStr => { @@ -1095,7 +1092,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic return false; } - return folderUri ? folderUri.authority === authority : false; + return folderUri ? getRemoteAuthority(folderUri) === authority : false; }); fileUris = fileUris.filter(fileUriStr => { @@ -1104,18 +1101,14 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic return false; } - return fileUri ? fileUri.authority === authority : false; + return fileUri ? getRemoteAuthority(fileUri) === authority : false; }); openConfig.cli._ = cliArgs; openConfig.cli['folder-uri'] = folderUris; openConfig.cli['file-uri'] = fileUris; - // if there are no files or folders cli args left, use the "remote" cli argument const noFilesOrFolders = !cliArgs.length && !folderUris.length && !fileUris.length; - if (noFilesOrFolders && authority) { - openConfig.cli.remote = authority; - } // Open it const openArgs: IOpenConfiguration = { @@ -1125,7 +1118,8 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic forceEmpty: noFilesOrFolders, userEnv: openConfig.userEnv, noRecentEntry: true, - waitMarkerFileURI: openConfig.waitMarkerFileURI + waitMarkerFileURI: openConfig.waitMarkerFileURI, + remoteAuthority: authority }; return this.open(openArgs); diff --git a/src/vs/workbench/contrib/files/browser/fileCommands.ts b/src/vs/workbench/contrib/files/browser/fileCommands.ts index 73bc376a362..e31fb3176ba 100644 --- a/src/vs/workbench/contrib/files/browser/fileCommands.ts +++ b/src/vs/workbench/contrib/files/browser/fileCommands.ts @@ -34,7 +34,6 @@ import { IEditorGroupsService, GroupsOrder, IEditorGroup } from 'vs/workbench/se import { ILabelService } from 'vs/platform/label/common/label'; import { basename, joinPath, isEqual } from 'vs/base/common/resources'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { UNTITLED_WORKSPACE_NAME } from 'vs/platform/workspaces/common/workspaces'; import { coalesce } from 'vs/base/common/arrays'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; @@ -44,6 +43,7 @@ import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/ur import { isPromiseCanceledError } from 'vs/base/common/errors'; import { toAction } from 'vs/base/common/actions'; import { EditorOverride } from 'vs/platform/editor/common/editor'; +import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; // Commands @@ -91,7 +91,7 @@ export const NEW_UNTITLED_FILE_LABEL = nls.localize('newUntitledFile', "New Unti export const openWindowCommand = (accessor: ServicesAccessor, toOpen: IWindowOpenable[], options?: IOpenWindowOptions) => { if (Array.isArray(toOpen)) { const hostService = accessor.get(IHostService); - const environmentService = accessor.get(IEnvironmentService); + const environmentService = accessor.get(IWorkbenchEnvironmentService); // rewrite untitled: workspace URIs to the absolute path on disk toOpen = toOpen.map(openable => { @@ -103,6 +103,9 @@ export const openWindowCommand = (accessor: ServicesAccessor, toOpen: IWindowOpe return openable; }); + if (environmentService.remoteAuthority) { + options = { ...(options || {}), remoteAuthority: environmentService.remoteAuthority }; + } hostService.openWindow(toOpen, options); }