mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-23 10:08:49 +01:00
Reworking external opener implementation to allow configured openers to be called directly without a canOpen check
If the user has configured a specific external uri opener, we should always try to use that without first calling `canOpen` to filter down the list of openers. This change also adds `ExternalUriOpenerEnablement` which allows an opener to mark itself as the preferred opener for a given uri. If only a single preferred opener is returned, it will be used automatically for that uri (although user configuration can override this)
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import * as modes from 'vs/editor/common/modes';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import type * as vscode from 'vscode';
|
||||
import { ExtHostUriOpenersShape, IMainContext, MainContext, MainThreadUriOpenersShape } from './extHost.protocol';
|
||||
@@ -54,35 +55,23 @@ export class ExtHostUriOpeners implements ExtHostUriOpenersShape {
|
||||
});
|
||||
}
|
||||
|
||||
async $getOpenersForUri(uriComponents: UriComponents, token: CancellationToken): Promise<readonly string[]> {
|
||||
async $canOpenUri(id: string, uriComponents: UriComponents, token: CancellationToken): Promise<modes.ExternalUriOpenerEnablement> {
|
||||
const entry = this._openers.get(id);
|
||||
if (!entry) {
|
||||
throw new Error(`Unknown opener with id: ${id}`);
|
||||
}
|
||||
|
||||
const uri = URI.revive(uriComponents);
|
||||
|
||||
const promises = Array.from(this._openers.entries())
|
||||
.map(async ([id, { schemes, opener, }]): Promise<string | undefined> => {
|
||||
if (!schemes.has(uri.scheme)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
try {
|
||||
if (await opener.canOpenExternalUri(uri, token)) {
|
||||
return id;
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
// noop
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
|
||||
return (await Promise.all(promises)).filter(handle => typeof handle === 'string') as string[];
|
||||
const result = await entry.opener.canOpenExternalUri(uri, token);
|
||||
return result ? result : modes.ExternalUriOpenerEnablement.Disabled;
|
||||
}
|
||||
|
||||
async $openUri(id: string, context: { resolveUri: UriComponents, sourceUri: UriComponents }, token: CancellationToken): Promise<void> {
|
||||
async $openUri(id: string, context: { resolvedUri: UriComponents, sourceUri: UriComponents }, token: CancellationToken): Promise<void> {
|
||||
const entry = this._openers.get(id);
|
||||
if (!entry) {
|
||||
throw new Error(`Unknown opener id: '${id}'`);
|
||||
}
|
||||
return entry.opener.openExternalUri(URI.revive(context.resolveUri), {
|
||||
return entry.opener.openExternalUri(URI.revive(context.resolvedUri), {
|
||||
sourceUri: URI.revive(context.sourceUri)
|
||||
}, token);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user