Path: blob/main/src/vs/workbench/contrib/commands/common/commands.contribution.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { safeStringify } from '../../../../base/common/objects.js';6import * as nls from '../../../../nls.js';7import { Action2, registerAction2 } from '../../../../platform/actions/common/actions.js';8import { ICommandService } from '../../../../platform/commands/common/commands.js';9import { ServicesAccessor } from '../../../../platform/instantiation/common/instantiation.js';10import { ILogService } from '../../../../platform/log/common/log.js';11import { INotificationService } from '../../../../platform/notification/common/notification.js';1213type RunnableCommand = string | { command: string; args: any[] };1415type CommandArgs = {16commands: RunnableCommand[];17};1819/** Runs several commands passed to it as an argument */20class RunCommands extends Action2 {2122constructor() {23super({24id: 'runCommands',25title: nls.localize2('runCommands', "Run Commands"),26f1: false,27metadata: {28description: nls.localize('runCommands.description', "Run several commands"),29args: [30{31name: 'args',32schema: {33type: 'object',34required: ['commands'],35properties: {36commands: {37type: 'array',38description: nls.localize('runCommands.commands', "Commands to run"),39items: {40anyOf: [41{42$ref: 'vscode://schemas/keybindings#/definitions/commandNames'43},44{45type: 'string',46},47{48type: 'object',49required: ['command'],50properties: {51command: {52'anyOf': [53{54$ref: 'vscode://schemas/keybindings#/definitions/commandNames'55},56{57type: 'string'58},59]60}61},62$ref: 'vscode://schemas/keybindings#/definitions/commandsSchemas'63}64]65}66}67}68}69}70]71}72});73}7475// dev decisions:76// - this command takes a single argument-object because77// - keybinding definitions don't allow running commands with several arguments78// - and we want to be able to take on different other arguments in future, e.g., `runMode : 'serial' | 'concurrent'`79async run(accessor: ServicesAccessor, args: unknown) {8081const notificationService = accessor.get(INotificationService);8283if (!this._isCommandArgs(args)) {84notificationService.error(nls.localize('runCommands.invalidArgs', "'runCommands' has received an argument with incorrect type. Please, review the argument passed to the command."));85return;86}8788if (args.commands.length === 0) {89notificationService.warn(nls.localize('runCommands.noCommandsToRun', "'runCommands' has not received commands to run. Did you forget to pass commands in the 'runCommands' argument?"));90return;91}9293const commandService = accessor.get(ICommandService);94const logService = accessor.get(ILogService);9596let i = 0;97try {98for (; i < args.commands.length; ++i) {99100const cmd = args.commands[i];101102logService.debug(`runCommands: executing ${i}-th command: ${safeStringify(cmd)}`);103104await this._runCommand(commandService, cmd);105106logService.debug(`runCommands: executed ${i}-th command`);107}108} catch (err) {109logService.debug(`runCommands: executing ${i}-th command resulted in an error: ${err instanceof Error ? err.message : safeStringify(err)}`);110111notificationService.error(err);112}113}114115private _isCommandArgs(args: unknown): args is CommandArgs {116if (!args || typeof args !== 'object') {117return false;118}119if (!('commands' in args) || !Array.isArray(args.commands)) {120return false;121}122for (const cmd of args.commands) {123if (typeof cmd === 'string') {124continue;125}126if (typeof cmd === 'object' && typeof cmd.command === 'string') {127continue;128}129return false;130}131return true;132}133134private _runCommand(commandService: ICommandService, cmd: RunnableCommand) {135let commandID: string, commandArgs;136137if (typeof cmd === 'string') {138commandID = cmd;139} else {140commandID = cmd.command;141commandArgs = cmd.args;142}143144if (commandArgs === undefined) {145return commandService.executeCommand(commandID);146} else {147if (Array.isArray(commandArgs)) {148return commandService.executeCommand(commandID, ...commandArgs);149} else {150return commandService.executeCommand(commandID, commandArgs);151}152}153}154}155156registerAction2(RunCommands);157158159