Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/commands/common/commands.contribution.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { safeStringify } from '../../../../base/common/objects.js';
7
import * as nls from '../../../../nls.js';
8
import { Action2, registerAction2 } from '../../../../platform/actions/common/actions.js';
9
import { ICommandService } from '../../../../platform/commands/common/commands.js';
10
import { ServicesAccessor } from '../../../../platform/instantiation/common/instantiation.js';
11
import { ILogService } from '../../../../platform/log/common/log.js';
12
import { INotificationService } from '../../../../platform/notification/common/notification.js';
13
14
type RunnableCommand = string | { command: string; args: any[] };
15
16
type CommandArgs = {
17
commands: RunnableCommand[];
18
};
19
20
/** Runs several commands passed to it as an argument */
21
class RunCommands extends Action2 {
22
23
constructor() {
24
super({
25
id: 'runCommands',
26
title: nls.localize2('runCommands', "Run Commands"),
27
f1: false,
28
metadata: {
29
description: nls.localize('runCommands.description', "Run several commands"),
30
args: [
31
{
32
name: 'args',
33
schema: {
34
type: 'object',
35
required: ['commands'],
36
properties: {
37
commands: {
38
type: 'array',
39
description: nls.localize('runCommands.commands', "Commands to run"),
40
items: {
41
anyOf: [
42
{
43
$ref: 'vscode://schemas/keybindings#/definitions/commandNames'
44
},
45
{
46
type: 'string',
47
},
48
{
49
type: 'object',
50
required: ['command'],
51
properties: {
52
command: {
53
'anyOf': [
54
{
55
$ref: 'vscode://schemas/keybindings#/definitions/commandNames'
56
},
57
{
58
type: 'string'
59
},
60
]
61
}
62
},
63
$ref: 'vscode://schemas/keybindings#/definitions/commandsSchemas'
64
}
65
]
66
}
67
}
68
}
69
}
70
}
71
]
72
}
73
});
74
}
75
76
// dev decisions:
77
// - this command takes a single argument-object because
78
// - keybinding definitions don't allow running commands with several arguments
79
// - and we want to be able to take on different other arguments in future, e.g., `runMode : 'serial' | 'concurrent'`
80
async run(accessor: ServicesAccessor, args: unknown) {
81
82
const notificationService = accessor.get(INotificationService);
83
84
if (!this._isCommandArgs(args)) {
85
notificationService.error(nls.localize('runCommands.invalidArgs', "'runCommands' has received an argument with incorrect type. Please, review the argument passed to the command."));
86
return;
87
}
88
89
if (args.commands.length === 0) {
90
notificationService.warn(nls.localize('runCommands.noCommandsToRun', "'runCommands' has not received commands to run. Did you forget to pass commands in the 'runCommands' argument?"));
91
return;
92
}
93
94
const commandService = accessor.get(ICommandService);
95
const logService = accessor.get(ILogService);
96
97
let i = 0;
98
try {
99
for (; i < args.commands.length; ++i) {
100
101
const cmd = args.commands[i];
102
103
logService.debug(`runCommands: executing ${i}-th command: ${safeStringify(cmd)}`);
104
105
await this._runCommand(commandService, cmd);
106
107
logService.debug(`runCommands: executed ${i}-th command`);
108
}
109
} catch (err) {
110
logService.debug(`runCommands: executing ${i}-th command resulted in an error: ${err instanceof Error ? err.message : safeStringify(err)}`);
111
112
notificationService.error(err);
113
}
114
}
115
116
private _isCommandArgs(args: unknown): args is CommandArgs {
117
if (!args || typeof args !== 'object') {
118
return false;
119
}
120
if (!('commands' in args) || !Array.isArray(args.commands)) {
121
return false;
122
}
123
for (const cmd of args.commands) {
124
if (typeof cmd === 'string') {
125
continue;
126
}
127
if (typeof cmd === 'object' && typeof cmd.command === 'string') {
128
continue;
129
}
130
return false;
131
}
132
return true;
133
}
134
135
private _runCommand(commandService: ICommandService, cmd: RunnableCommand) {
136
let commandID: string, commandArgs;
137
138
if (typeof cmd === 'string') {
139
commandID = cmd;
140
} else {
141
commandID = cmd.command;
142
commandArgs = cmd.args;
143
}
144
145
if (commandArgs === undefined) {
146
return commandService.executeCommand(commandID);
147
} else {
148
if (Array.isArray(commandArgs)) {
149
return commandService.executeCommand(commandID, ...commandArgs);
150
} else {
151
return commandService.executeCommand(commandID, commandArgs);
152
}
153
}
154
}
155
}
156
157
registerAction2(RunCommands);
158
159