mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-27 20:13:32 +01:00
retry command exec when having arguments, when contributes, and not yet activated, #80338
This commit is contained in:
@@ -8,6 +8,7 @@ import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { ExtHostContext, MainThreadCommandsShape, ExtHostCommandsShape, MainContext, IExtHostContext } from '../common/extHost.protocol';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
import { revive } from 'vs/base/common/marshalling';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
|
||||
@extHostNamedCustomer(MainContext.MainThreadCommands)
|
||||
export class MainThreadCommands implements MainThreadCommandsShape {
|
||||
@@ -19,6 +20,7 @@ export class MainThreadCommands implements MainThreadCommandsShape {
|
||||
constructor(
|
||||
extHostContext: IExtHostContext,
|
||||
@ICommandService private readonly _commandService: ICommandService,
|
||||
@IExtensionService private readonly _extensionService: IExtensionService,
|
||||
) {
|
||||
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostCommands);
|
||||
|
||||
@@ -70,10 +72,14 @@ export class MainThreadCommands implements MainThreadCommandsShape {
|
||||
}
|
||||
}
|
||||
|
||||
$executeCommand<T>(id: string, args: any[]): Promise<T | undefined> {
|
||||
async $executeCommand<T>(id: string, args: any[], retry: boolean): Promise<T | undefined> {
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
args[i] = revive(args[i], 0);
|
||||
}
|
||||
if (retry && args.length > 0 && !CommandsRegistry.getCommand(id)) {
|
||||
await this._extensionService.activateByEvent(`onCommand:${id}`);
|
||||
throw new Error('$executeCommand:retry');
|
||||
}
|
||||
return this._commandService.executeCommand<T>(id, ...args);
|
||||
}
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ export interface MainThreadClipboardShape extends IDisposable {
|
||||
export interface MainThreadCommandsShape extends IDisposable {
|
||||
$registerCommand(id: string): void;
|
||||
$unregisterCommand(id: string): void;
|
||||
$executeCommand<T>(id: string, args: any[]): Promise<T | undefined>;
|
||||
$executeCommand<T>(id: string, args: any[], retry: boolean): Promise<T | undefined>;
|
||||
$getCommands(): Promise<string[]>;
|
||||
}
|
||||
|
||||
|
||||
@@ -112,6 +112,10 @@ export class ExtHostCommands implements ExtHostCommandsShape {
|
||||
|
||||
executeCommand<T>(id: string, ...args: any[]): Promise<T> {
|
||||
this._logService.trace('ExtHostCommands#executeCommand', id);
|
||||
return this._doExecuteCommand(id, args, true);
|
||||
}
|
||||
|
||||
private async _doExecuteCommand<T>(id: string, args: any[], retry: boolean): Promise<T> {
|
||||
|
||||
if (this._commands.has(id)) {
|
||||
// we stay inside the extension host and support
|
||||
@@ -120,8 +124,7 @@ export class ExtHostCommands implements ExtHostCommandsShape {
|
||||
|
||||
} else {
|
||||
// automagically convert some argument types
|
||||
|
||||
args = cloneAndChange(args, function (value) {
|
||||
const toArgs = cloneAndChange(args, function (value) {
|
||||
if (value instanceof extHostTypes.Position) {
|
||||
return extHostTypeConverter.Position.from(value);
|
||||
}
|
||||
@@ -136,7 +139,19 @@ export class ExtHostCommands implements ExtHostCommandsShape {
|
||||
}
|
||||
});
|
||||
|
||||
return this._proxy.$executeCommand<T>(id, args).then(result => revive(result, 0));
|
||||
try {
|
||||
const result = await this._proxy.$executeCommand<T>(id, toArgs, retry);
|
||||
return revive(result, 0);
|
||||
} catch (e) {
|
||||
// Rerun the command when it wasn't known, had arguments, and when retry
|
||||
// is enabled. We do this because the command might be registered inside
|
||||
// the extension host now and can therfore accept the arguments as-is.
|
||||
if (e instanceof Error && e.message === '$executeCommand:retry') {
|
||||
return this._doExecuteCommand(id, args, false);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user