mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-24 01:25:37 -05:00
Merge from vscode 5e80bf449c995aa32a59254c0ff845d37da11b70 (#9317)
This commit is contained in:
@@ -24,7 +24,7 @@ import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IStateService } from 'vs/platform/state/node/state';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IURLService, IOpenURLOptions } from 'vs/platform/url/common/url';
|
||||
import { IURLService } from 'vs/platform/url/common/url';
|
||||
import { URLHandlerChannelClient, URLHandlerRouter } from 'vs/platform/url/common/urlIpc';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { NullTelemetryService, combinedAppender, LogAppender } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
@@ -73,10 +73,10 @@ import { IDiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsSer
|
||||
import { ExtensionHostDebugBroadcastChannel } from 'vs/platform/debug/common/extensionHostDebugIpc';
|
||||
import { IElectronMainService, ElectronMainService } from 'vs/platform/electron/electron-main/electronMainService';
|
||||
import { ISharedProcessMainService, SharedProcessMainService } from 'vs/platform/ipc/electron-main/sharedProcessMainService';
|
||||
import { assign } from 'vs/base/common/objects';
|
||||
import { IDialogMainService, DialogMainService } from 'vs/platform/dialogs/electron-main/dialogs';
|
||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||
import { parseArgs, OPTIONS } from 'vs/platform/environment/node/argv';
|
||||
import { coalesce } from 'vs/base/common/arrays';
|
||||
|
||||
export class CodeApplication extends Disposable {
|
||||
|
||||
@@ -395,7 +395,7 @@ export class CodeApplication extends Disposable {
|
||||
const windows = appInstantiationService.invokeFunction(accessor => this.openFirstWindow(accessor, electronIpcServer, sharedProcessClient));
|
||||
|
||||
// Post Open Windows Tasks
|
||||
appInstantiationService.invokeFunction(this.afterWindowOpen.bind(this));
|
||||
appInstantiationService.invokeFunction(accessor => this.afterWindowOpen(accessor));
|
||||
|
||||
// Tracing: Stop tracing after windows are ready if enabled
|
||||
if (this.environmentService.args.trace) {
|
||||
@@ -575,9 +575,8 @@ export class CodeApplication extends Disposable {
|
||||
electronIpcServer.registerChannel('logger', loggerChannel);
|
||||
sharedProcessClient.then(client => client.registerChannel('logger', loggerChannel));
|
||||
|
||||
const windowsMainService = this.windowsMainService = accessor.get(IWindowsMainService);
|
||||
|
||||
// ExtensionHost Debug broadcast service
|
||||
const windowsMainService = this.windowsMainService = accessor.get(IWindowsMainService);
|
||||
electronIpcServer.registerChannel(ExtensionHostDebugBroadcastChannel.ChannelName, new ElectronExtensionHostDebugBroadcastChannel(windowsMainService));
|
||||
|
||||
// Signal phase: ready (services set)
|
||||
@@ -586,47 +585,67 @@ export class CodeApplication extends Disposable {
|
||||
// Propagate to clients
|
||||
this.dialogMainService = accessor.get(IDialogMainService);
|
||||
|
||||
// Create a URL handler to open file URIs in the active window
|
||||
// Check for initial URLs to handle from protocol link invocations
|
||||
const environmentService = accessor.get(IEnvironmentService);
|
||||
const pendingWindowOpenablesFromProtocolLinks: IWindowOpenable[] = [];
|
||||
const pendingProtocolLinksToHandle = coalesce([
|
||||
|
||||
// Windows/Linux: protocol handler invokes CLI with --open-url
|
||||
...environmentService.args['open-url'] ? environmentService.args._urls || [] : [],
|
||||
|
||||
// macOS: open-url events
|
||||
...((<any>global).getOpenUrls() || []) as string[]
|
||||
].map(pendingUrlToHandle => {
|
||||
try {
|
||||
return URI.parse(pendingUrlToHandle);
|
||||
} catch (error) {
|
||||
return undefined;
|
||||
}
|
||||
})).filter(pendingUriToHandle => {
|
||||
// filter out any protocol link that wants to open as window so that
|
||||
// we open the right set of windows on startup and not restore the
|
||||
// previous workspace too.
|
||||
const windowOpenable = this.getWindowOpenableFromProtocolLink(pendingUriToHandle);
|
||||
if (windowOpenable) {
|
||||
pendingWindowOpenablesFromProtocolLinks.push(windowOpenable);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
// Create a URL handler to open file URIs in the active window
|
||||
const app = this;
|
||||
urlService.registerHandler({
|
||||
async handleURL(uri: URI, options?: IOpenURLOptions): Promise<boolean> {
|
||||
async handleURL(uri: URI): Promise<boolean> {
|
||||
|
||||
// Catch file/remote URLs
|
||||
if ((uri.authority === Schemas.file || uri.authority === Schemas.vscodeRemote) && !!uri.path) {
|
||||
const cli = assign(Object.create(null), environmentService.args);
|
||||
const urisToOpen: IWindowOpenable[] = [];
|
||||
// Check for URIs to open in window
|
||||
const windowOpenableFromProtocolLink = app.getWindowOpenableFromProtocolLink(uri);
|
||||
if (windowOpenableFromProtocolLink) {
|
||||
windowsMainService.open({
|
||||
context: OpenContext.API,
|
||||
cli: { ...environmentService.args },
|
||||
urisToOpen: [windowOpenableFromProtocolLink],
|
||||
gotoLineMode: true
|
||||
});
|
||||
|
||||
// File path
|
||||
if (uri.authority === Schemas.file) {
|
||||
// we configure as fileUri, but later validation will
|
||||
// make sure to open as folder or workspace if possible
|
||||
urisToOpen.push({ fileUri: URI.file(uri.fsPath) });
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Remote path
|
||||
else {
|
||||
// Example conversion:
|
||||
// From: vscode://vscode-remote/wsl+ubuntu/mnt/c/GitDevelopment/monaco
|
||||
// To: vscode-remote://wsl+ubuntu/mnt/c/GitDevelopment/monaco
|
||||
const secondSlash = uri.path.indexOf(posix.sep, 1 /* skip over the leading slash */);
|
||||
if (secondSlash !== -1) {
|
||||
const authority = uri.path.substring(1, secondSlash);
|
||||
const path = uri.path.substring(secondSlash);
|
||||
const remoteUri = URI.from({ scheme: Schemas.vscodeRemote, authority, path, query: uri.query, fragment: uri.fragment });
|
||||
// If we have not yet handled the URI and we have no window opened (macOS only)
|
||||
// we first open a window and then try to open that URI within that window
|
||||
if (isMacintosh && windowsMainService.getWindowCount() === 0) {
|
||||
const [window] = windowsMainService.open({
|
||||
context: OpenContext.API,
|
||||
cli: { ...environmentService.args },
|
||||
forceEmpty: true,
|
||||
gotoLineMode: true
|
||||
});
|
||||
|
||||
if (hasWorkspaceFileExtension(path)) {
|
||||
urisToOpen.push({ workspaceUri: remoteUri });
|
||||
} else {
|
||||
urisToOpen.push({ folderUri: remoteUri });
|
||||
}
|
||||
}
|
||||
}
|
||||
await window.ready();
|
||||
|
||||
if (urisToOpen.length > 0) {
|
||||
windowsMainService.open({ context: OpenContext.API, cli, urisToOpen, gotoLineMode: true });
|
||||
|
||||
return true;
|
||||
}
|
||||
return urlService.open(uri);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -638,37 +657,13 @@ export class CodeApplication extends Disposable {
|
||||
const activeWindowRouter = new StaticRouter(ctx => activeWindowManager.getActiveClientId().then(id => ctx === id));
|
||||
const urlHandlerRouter = new URLHandlerRouter(activeWindowRouter);
|
||||
const urlHandlerChannel = electronIpcServer.getChannel('urlHandler', urlHandlerRouter);
|
||||
const multiplexURLHandler = new URLHandlerChannelClient(urlHandlerChannel);
|
||||
|
||||
// On Mac, Code can be running without any open windows, so we must create a window to handle urls,
|
||||
// if there is none
|
||||
if (isMacintosh) {
|
||||
urlService.registerHandler({
|
||||
async handleURL(uri: URI, options?: IOpenURLOptions): Promise<boolean> {
|
||||
if (windowsMainService.getWindowCount() === 0) {
|
||||
const cli = { ...environmentService.args };
|
||||
const [window] = windowsMainService.open({ context: OpenContext.API, cli, forceEmpty: true, gotoLineMode: true });
|
||||
|
||||
await window.ready();
|
||||
|
||||
return urlService.open(uri);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Register the multiple URL handler
|
||||
urlService.registerHandler(multiplexURLHandler);
|
||||
urlService.registerHandler(new URLHandlerChannelClient(urlHandlerChannel));
|
||||
|
||||
// Watch Electron URLs and forward them to the UrlService
|
||||
const args = this.environmentService.args;
|
||||
const urls = args['open-url'] ? args._urls : [];
|
||||
const urlListener = new ElectronURLListener(urls || [], urlService, windowsMainService, this.environmentService);
|
||||
this._register(urlListener);
|
||||
this._register(new ElectronURLListener(pendingProtocolLinksToHandle, urlService, windowsMainService, this.environmentService));
|
||||
|
||||
// Open our first window
|
||||
const args = this.environmentService.args;
|
||||
const macOpenFiles: string[] = (<any>global).macOpenFiles;
|
||||
const context = !!process.env['VSCODE_CLI'] ? OpenContext.CLI : OpenContext.DESKTOP;
|
||||
const hasCliArgs = args._.length;
|
||||
@@ -677,6 +672,19 @@ export class CodeApplication extends Disposable {
|
||||
const noRecentEntry = args['skip-add-to-recently-opened'] === true;
|
||||
const waitMarkerFileURI = args.wait && args.waitMarkerFilePath ? URI.file(args.waitMarkerFilePath) : undefined;
|
||||
|
||||
// check for a pending window to open from URI
|
||||
// e.g. when running code with --open-uri from
|
||||
// a protocol handler
|
||||
if (pendingWindowOpenablesFromProtocolLinks.length > 0) {
|
||||
return windowsMainService.open({
|
||||
context,
|
||||
cli: args,
|
||||
urisToOpen: pendingWindowOpenablesFromProtocolLinks,
|
||||
gotoLineMode: true,
|
||||
initialStartup: true
|
||||
});
|
||||
}
|
||||
|
||||
// new window if "-n" or "--remote" was used without paths
|
||||
if ((args['new-window'] || args.remote) && !hasCliArgs && !hasFolderURIs && !hasFileURIs) {
|
||||
return windowsMainService.open({
|
||||
@@ -698,7 +706,6 @@ export class CodeApplication extends Disposable {
|
||||
urisToOpen: macOpenFiles.map(file => this.getWindowOpenableFromPathSync(file)),
|
||||
noRecentEntry,
|
||||
waitMarkerFileURI,
|
||||
gotoLineMode: false,
|
||||
initialStartup: true
|
||||
});
|
||||
}
|
||||
@@ -716,6 +723,40 @@ export class CodeApplication extends Disposable {
|
||||
});
|
||||
}
|
||||
|
||||
private getWindowOpenableFromProtocolLink(uri: URI): IWindowOpenable | undefined {
|
||||
if (!uri.path) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// File path
|
||||
if (uri.authority === Schemas.file) {
|
||||
// we configure as fileUri, but later validation will
|
||||
// make sure to open as folder or workspace if possible
|
||||
return { fileUri: URI.file(uri.fsPath) };
|
||||
}
|
||||
|
||||
// Remote path
|
||||
else if (uri.authority === Schemas.vscodeRemote) {
|
||||
// Example conversion:
|
||||
// From: vscode://vscode-remote/wsl+ubuntu/mnt/c/GitDevelopment/monaco
|
||||
// To: vscode-remote://wsl+ubuntu/mnt/c/GitDevelopment/monaco
|
||||
const secondSlash = uri.path.indexOf(posix.sep, 1 /* skip over the leading slash */);
|
||||
if (secondSlash !== -1) {
|
||||
const authority = uri.path.substring(1, secondSlash);
|
||||
const path = uri.path.substring(secondSlash);
|
||||
const remoteUri = URI.from({ scheme: Schemas.vscodeRemote, authority, path, query: uri.query, fragment: uri.fragment });
|
||||
|
||||
if (hasWorkspaceFileExtension(path)) {
|
||||
return { workspaceUri: remoteUri };
|
||||
} else {
|
||||
return { folderUri: remoteUri };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private getWindowOpenableFromPathSync(path: string): IWindowOpenable {
|
||||
try {
|
||||
const fileStat = statSync(path);
|
||||
@@ -734,6 +775,7 @@ export class CodeApplication extends Disposable {
|
||||
}
|
||||
|
||||
private afterWindowOpen(accessor: ServicesAccessor): void {
|
||||
|
||||
// Signal phase: after window open
|
||||
this.lifecycleMainService.phase = LifecycleMainPhase.AfterWindowOpen;
|
||||
|
||||
@@ -763,7 +805,7 @@ class ElectronExtensionHostDebugBroadcastChannel<TContext> extends ExtensionHost
|
||||
super();
|
||||
}
|
||||
|
||||
call(ctx: TContext, command: string, arg?: any): Promise<any> {
|
||||
async call(ctx: TContext, command: string, arg?: any): Promise<any> {
|
||||
if (command === 'openExtensionDevelopmentHostWindow') {
|
||||
const env = arg[1];
|
||||
const pargs = parseArgs(arg[0], OPTIONS);
|
||||
@@ -775,7 +817,6 @@ class ElectronExtensionHostDebugBroadcastChannel<TContext> extends ExtensionHost
|
||||
userEnv: Object.keys(env).length > 0 ? env : undefined
|
||||
});
|
||||
}
|
||||
return Promise.resolve();
|
||||
} else {
|
||||
return super.call(ctx, command, arg);
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@ export function validatePaths(args: ParsedArgs): ParsedArgs {
|
||||
args._ = [];
|
||||
}
|
||||
|
||||
// Normalize paths and watch out for goto line mode
|
||||
if (!args['remote']) {
|
||||
// Normalize paths and watch out for goto line mode
|
||||
const paths = doValidatePaths(args._, args.goto);
|
||||
args._ = paths;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user