diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/commands.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/commands.test.ts index bb5b6d2699391..42e2f6a125a4d 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/commands.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/commands.test.ts @@ -119,6 +119,9 @@ suite('vscode API - commands', () => { await commands.executeCommand('vscode.open', uri, ViewColumn.One); assert.strictEqual(window.activeTextEditor?.viewColumn, ViewColumn.One); + await commands.executeCommand('vscode.open', uri.toString(), ViewColumn.Two); // call with string instead of URI + assert.strictEqual(window.activeTextEditor?.viewColumn, ViewColumn.Two); + let e1: Error | undefined = undefined; try { await commands.executeCommand('vscode.open'); diff --git a/src/vs/workbench/api/common/extHostApiCommands.ts b/src/vs/workbench/api/common/extHostApiCommands.ts index 1d83460acc312..0d8e1b4335b54 100644 --- a/src/vs/workbench/api/common/extHostApiCommands.ts +++ b/src/vs/workbench/api/common/extHostApiCommands.ts @@ -379,7 +379,7 @@ const newCommands: ApiCommand[] = [ new ApiCommand( 'vscode.open', '_workbench.open', 'Opens the provided resource in the editor. Can be a text or binary file, or an http(s) URL. If you need more control over the options for opening a text file, use vscode.window.showTextDocument instead.', [ - ApiCommandArgument.Uri, + ApiCommandArgument.UriOrString, new ApiCommandArgument('columnOrOptions', 'Either the column in which to open or editor options, see vscode.TextDocumentShowOptions', v => v === undefined || typeof v === 'number' || typeof v === 'object', v => !v ? v : typeof v === 'number' ? [typeConverters.ViewColumn.from(v), undefined] : [typeConverters.ViewColumn.from(v.viewColumn), typeConverters.TextEditorOpenOptions.from(v)] diff --git a/src/vs/workbench/api/common/extHostCommands.ts b/src/vs/workbench/api/common/extHostCommands.ts index 0d9833554e901..385949ff62684 100644 --- a/src/vs/workbench/api/common/extHostCommands.ts +++ b/src/vs/workbench/api/common/extHostCommands.ts @@ -390,6 +390,7 @@ export class CommandsConverter { export class ApiCommandArgument { static readonly Uri = new ApiCommandArgument('uri', 'Uri of a text document', v => URI.isUri(v), v => v); + static readonly UriOrString = new ApiCommandArgument('uriOrString', 'Uri-instance or string', v => URI.isUri(v) || typeof v === 'string', v => v); static readonly Position = new ApiCommandArgument('position', 'A position in a text document', v => extHostTypes.Position.isPosition(v), extHostTypeConverter.Position.from); static readonly Range = new ApiCommandArgument('range', 'A range in a text document', v => extHostTypes.Range.isRange(v), extHostTypeConverter.Range.from); static readonly Selection = new ApiCommandArgument('selection', 'A selection in a text document', v => extHostTypes.Selection.isSelection(v), extHostTypeConverter.Selection.from); diff --git a/src/vs/workbench/browser/parts/editor/editorCommands.ts b/src/vs/workbench/browser/parts/editor/editorCommands.ts index 2fd082d335912..23ecce07fe070 100644 --- a/src/vs/workbench/browser/parts/editor/editorCommands.ts +++ b/src/vs/workbench/browser/parts/editor/editorCommands.ts @@ -27,7 +27,7 @@ import { CommandsRegistry, ICommandHandler, ICommandService } from 'vs/platform/ import { MenuRegistry, MenuId, registerAction2, Action2 } from 'vs/platform/actions/common/actions'; import { CATEGORIES } from 'vs/workbench/common/actions'; import { ActiveGroupEditorsByMostRecentlyUsedQuickAccess } from 'vs/workbench/browser/parts/editor/editorQuickAccess'; -import { IOpenerService } from 'vs/platform/opener/common/opener'; +import { IOpenerService, matchesScheme } from 'vs/platform/opener/common/opener'; import { EditorResolution, IEditorOptions, IResourceEditorInput, ITextEditorOptions } from 'vs/platform/editor/common/editor'; import { Schemas } from 'vs/base/common/network'; import { SideBySideEditorInput } from 'vs/workbench/common/editor/sideBySideEditorInput'; @@ -492,22 +492,23 @@ function registerOpenEditorAPICommands(): void { } }); - CommandsRegistry.registerCommand(API_OPEN_EDITOR_COMMAND_ID, async function (accessor: ServicesAccessor, resourceArg: UriComponents, columnAndOptions?: [EditorGroupColumn?, ITextEditorOptions?], label?: string, context?: IOpenEvent) { + CommandsRegistry.registerCommand(API_OPEN_EDITOR_COMMAND_ID, async function (accessor: ServicesAccessor, resourceArg: UriComponents | string, columnAndOptions?: [EditorGroupColumn?, ITextEditorOptions?], label?: string, context?: IOpenEvent) { const editorService = accessor.get(IEditorService); const editorGroupService = accessor.get(IEditorGroupsService); const openerService = accessor.get(IOpenerService); const pathService = accessor.get(IPathService); - const resource = URI.revive(resourceArg); + const resourceOrString = typeof resourceArg === 'string' ? resourceArg : URI.revive(resourceArg); const [columnArg, optionsArg] = columnAndOptions ?? []; // use editor options or editor view column or resource scheme // as a hint to use the editor service for opening directly - if (optionsArg || typeof columnArg === 'number' || resource.scheme === Schemas.untitled) { + if (optionsArg || typeof columnArg === 'number' || matchesScheme(resourceOrString, Schemas.untitled)) { const [options, column] = mixinContext(context, optionsArg, columnArg); + const resource = URI.isUri(resourceOrString) ? resourceOrString : URI.parse(resourceOrString); let input: IResourceEditorInput | IUntitledTextResourceEditorInput; - if (resource.scheme === Schemas.untitled && resource.path.length > 1) { + if (matchesScheme(resource, Schemas.untitled) && resource.path.length > 1) { // special case for untitled: we are getting a resource with meaningful // path from an extension to use for the untitled editor. as such, we // have to assume it as an associated resource to use when saving. we @@ -524,13 +525,13 @@ function registerOpenEditorAPICommands(): void { } // do not allow to execute commands from here - else if (resource.scheme === 'command') { + else if (matchesScheme(resourceOrString, Schemas.command)) { return; } // finally, delegate to opener service else { - await openerService.open(resource, { openToSide: context?.sideBySide, editorOptions: context?.editorOptions }); + await openerService.open(resourceOrString, { openToSide: context?.sideBySide, editorOptions: context?.editorOptions }); } });