1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
18 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
19 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
20 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
21 | return c > 3 && r && Object.defineProperty(target, key, r), r;
|
22 | };
|
23 | var __metadata = (this && this.__metadata) || function (k, v) {
|
24 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
25 | };
|
26 | var __param = (this && this.__param) || function (paramIndex, decorator) {
|
27 | return function (target, key) { decorator(target, key, paramIndex); }
|
28 | };
|
29 | Object.defineProperty(exports, "__esModule", { value: true });
|
30 | exports.CommandRegistry = exports.CommandService = exports.commandServicePath = exports.CommandContribution = exports.Command = void 0;
|
31 | const inversify_1 = require("inversify");
|
32 | const event_1 = require("./event");
|
33 | const disposable_1 = require("./disposable");
|
34 | const contribution_provider_1 = require("./contribution-provider");
|
35 | const nls_1 = require("./nls");
|
36 | const debounce = require("p-debounce");
|
37 | const types_1 = require("./types");
|
38 | var Command;
|
39 | (function (Command) {
|
40 |
|
41 | function is(arg) {
|
42 | return (0, types_1.isObject)(arg) && 'id' in arg;
|
43 | }
|
44 | Command.is = is;
|
45 |
|
46 | function toLocalizedCommand(command, nlsLabelKey = command.id, nlsCategoryKey) {
|
47 | return Object.assign(Object.assign({}, command), { label: command.label && nls_1.nls.localize(nlsLabelKey, command.label), originalLabel: command.label, category: nlsCategoryKey && command.category && nls_1.nls.localize(nlsCategoryKey, command.category) || command.category, originalCategory: command.category });
|
48 | }
|
49 | Command.toLocalizedCommand = toLocalizedCommand;
|
50 | function toDefaultLocalizedCommand(command) {
|
51 | return Object.assign(Object.assign({}, command), { label: command.label && nls_1.nls.localizeByDefault(command.label), originalLabel: command.label, category: command.category && nls_1.nls.localizeByDefault(command.category), originalCategory: command.category });
|
52 | }
|
53 | Command.toDefaultLocalizedCommand = toDefaultLocalizedCommand;
|
54 |
|
55 | function compareCommands(a, b) {
|
56 | if (a.label && b.label) {
|
57 | const aCommand = (a.category ? `${a.category}: ${a.label}` : a.label).toLowerCase();
|
58 | const bCommand = (b.category ? `${b.category}: ${b.label}` : b.label).toLowerCase();
|
59 | return (aCommand).localeCompare(bCommand);
|
60 | }
|
61 | else {
|
62 | return 0;
|
63 | }
|
64 | }
|
65 | Command.compareCommands = compareCommands;
|
66 | |
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 | function equals(a, b) {
|
73 | return (a.id === b.id &&
|
74 | a.label === b.label &&
|
75 | a.iconClass === b.iconClass &&
|
76 | a.category === b.category);
|
77 | }
|
78 | Command.equals = equals;
|
79 | })(Command = exports.Command || (exports.Command = {}));
|
80 | exports.CommandContribution = Symbol('CommandContribution');
|
81 | exports.commandServicePath = '/services/commands';
|
82 | exports.CommandService = Symbol('CommandService');
|
83 |
|
84 |
|
85 |
|
86 | let CommandRegistry = class CommandRegistry {
|
87 | constructor(contributionProvider) {
|
88 | this.contributionProvider = contributionProvider;
|
89 | this._commands = {};
|
90 | this._handlers = {};
|
91 | this.toUnregisterCommands = new Map();
|
92 |
|
93 | this._recent = [];
|
94 | this.onWillExecuteCommandEmitter = new event_1.Emitter();
|
95 | this.onWillExecuteCommand = this.onWillExecuteCommandEmitter.event;
|
96 | this.onDidExecuteCommandEmitter = new event_1.Emitter();
|
97 | this.onDidExecuteCommand = this.onDidExecuteCommandEmitter.event;
|
98 | this.onCommandsChangedEmitter = new event_1.Emitter();
|
99 | this.onCommandsChanged = this.onCommandsChangedEmitter.event;
|
100 | this.fireDidChange = debounce(() => this.doFireDidChange(), 0);
|
101 | }
|
102 | onStart() {
|
103 | const contributions = this.contributionProvider.getContributions();
|
104 | for (const contrib of contributions) {
|
105 | contrib.registerCommands(this);
|
106 | }
|
107 | }
|
108 | *getAllCommands() {
|
109 | var _a;
|
110 | for (const command of Object.values(this._commands)) {
|
111 | yield Object.assign(Object.assign({}, command), { handlers: (_a = this._handlers[command.id]) !== null && _a !== void 0 ? _a : [] });
|
112 | }
|
113 | }
|
114 | |
115 |
|
116 |
|
117 |
|
118 |
|
119 | registerCommand(command, handler) {
|
120 | if (this._commands[command.id]) {
|
121 | console.warn(`A command ${command.id} is already registered.`);
|
122 | return disposable_1.Disposable.NULL;
|
123 | }
|
124 | const toDispose = new disposable_1.DisposableCollection(this.doRegisterCommand(command));
|
125 | if (handler) {
|
126 | toDispose.push(this.registerHandler(command.id, handler));
|
127 | }
|
128 | this.toUnregisterCommands.set(command.id, toDispose);
|
129 | toDispose.push(disposable_1.Disposable.create(() => this.toUnregisterCommands.delete(command.id)));
|
130 | return toDispose;
|
131 | }
|
132 | doRegisterCommand(command) {
|
133 | this._commands[command.id] = command;
|
134 | return {
|
135 | dispose: () => {
|
136 | delete this._commands[command.id];
|
137 | }
|
138 | };
|
139 | }
|
140 | unregisterCommand(commandOrId) {
|
141 | const id = Command.is(commandOrId) ? commandOrId.id : commandOrId;
|
142 | const toUnregister = this.toUnregisterCommands.get(id);
|
143 | if (toUnregister) {
|
144 | toUnregister.dispose();
|
145 | }
|
146 | }
|
147 | |
148 |
|
149 |
|
150 |
|
151 |
|
152 |
|
153 |
|
154 | registerHandler(commandId, handler) {
|
155 | let handlers = this._handlers[commandId];
|
156 | if (!handlers) {
|
157 | this._handlers[commandId] = handlers = [];
|
158 | }
|
159 | handlers.unshift(handler);
|
160 | this.fireDidChange();
|
161 | return {
|
162 | dispose: () => {
|
163 | const idx = handlers.indexOf(handler);
|
164 | if (idx >= 0) {
|
165 | handlers.splice(idx, 1);
|
166 | this.fireDidChange();
|
167 | }
|
168 | }
|
169 | };
|
170 | }
|
171 | doFireDidChange() {
|
172 | this.onCommandsChangedEmitter.fire();
|
173 | }
|
174 | |
175 |
|
176 |
|
177 |
|
178 | isEnabled(command, ...args) {
|
179 | return typeof this.getActiveHandler(command, ...args) !== 'undefined';
|
180 | }
|
181 | |
182 |
|
183 |
|
184 |
|
185 | isVisible(command, ...args) {
|
186 | return typeof this.getVisibleHandler(command, ...args) !== 'undefined';
|
187 | }
|
188 | |
189 |
|
190 |
|
191 |
|
192 | isToggled(command, ...args) {
|
193 | return typeof this.getToggledHandler(command, ...args) !== 'undefined';
|
194 | }
|
195 | |
196 |
|
197 |
|
198 |
|
199 |
|
200 |
|
201 | async executeCommand(commandId, ...args) {
|
202 | const handler = this.getActiveHandler(commandId, ...args);
|
203 | if (handler) {
|
204 | await this.fireWillExecuteCommand(commandId, args);
|
205 | const result = await handler.execute(...args);
|
206 | this.onDidExecuteCommandEmitter.fire({ commandId, args });
|
207 | return result;
|
208 | }
|
209 | throw Object.assign(new Error(`The command '${commandId}' cannot be executed. There are no active handlers available for the command.`), { code: 'NO_ACTIVE_HANDLER' });
|
210 | }
|
211 |
|
212 | async fireWillExecuteCommand(commandId, args = []) {
|
213 | await event_1.WaitUntilEvent.fire(this.onWillExecuteCommandEmitter, { commandId, args }, 30000);
|
214 | }
|
215 | |
216 |
|
217 |
|
218 |
|
219 | getVisibleHandler(commandId, ...args) {
|
220 | const handlers = this._handlers[commandId];
|
221 | if (handlers) {
|
222 | for (const handler of handlers) {
|
223 | try {
|
224 | if (!handler.isVisible || handler.isVisible(...args)) {
|
225 | return handler;
|
226 | }
|
227 | }
|
228 | catch (error) {
|
229 | console.error(error);
|
230 | }
|
231 | }
|
232 | }
|
233 | return undefined;
|
234 | }
|
235 | |
236 |
|
237 |
|
238 |
|
239 | getActiveHandler(commandId, ...args) {
|
240 | const handlers = this._handlers[commandId];
|
241 | if (handlers) {
|
242 | for (const handler of handlers) {
|
243 | try {
|
244 | if (!handler.isEnabled || handler.isEnabled(...args)) {
|
245 | return handler;
|
246 | }
|
247 | }
|
248 | catch (error) {
|
249 | console.error(error);
|
250 | }
|
251 | }
|
252 | }
|
253 | return undefined;
|
254 | }
|
255 | |
256 |
|
257 |
|
258 |
|
259 | getToggledHandler(commandId, ...args) {
|
260 | const handlers = this._handlers[commandId];
|
261 | if (handlers) {
|
262 | for (const handler of handlers) {
|
263 | try {
|
264 | if (handler.isToggled && handler.isToggled(...args)) {
|
265 | return handler;
|
266 | }
|
267 | }
|
268 | catch (error) {
|
269 | console.error(error);
|
270 | }
|
271 | }
|
272 | }
|
273 | return undefined;
|
274 | }
|
275 | |
276 |
|
277 |
|
278 |
|
279 | getAllHandlers(commandId) {
|
280 | const handlers = this._handlers[commandId];
|
281 | return handlers ? handlers.slice() : [];
|
282 | }
|
283 | |
284 |
|
285 |
|
286 | get commands() {
|
287 | return Object.values(this._commands);
|
288 | }
|
289 | |
290 |
|
291 |
|
292 | getCommand(id) {
|
293 | return this._commands[id];
|
294 | }
|
295 | |
296 |
|
297 |
|
298 | get commandIds() {
|
299 | return Object.keys(this._commands);
|
300 | }
|
301 | |
302 |
|
303 |
|
304 | get recent() {
|
305 | const commands = [];
|
306 | for (const recentId of this._recent) {
|
307 | const command = this.getCommand(recentId);
|
308 | if (command) {
|
309 | commands.push(command);
|
310 | }
|
311 | }
|
312 | return commands;
|
313 | }
|
314 | |
315 |
|
316 |
|
317 |
|
318 | set recent(commands) {
|
319 | this._recent = Array.from(new Set(commands.map(e => e.id)));
|
320 | }
|
321 | |
322 |
|
323 |
|
324 |
|
325 |
|
326 |
|
327 | addRecentCommand(recent) {
|
328 | for (const recentCommand of Array.isArray(recent) ? recent : [recent]) {
|
329 |
|
330 | const index = this._recent.findIndex(commandId => commandId === recentCommand.id);
|
331 |
|
332 | if (index >= 0) {
|
333 | this._recent.splice(index, 1);
|
334 | }
|
335 |
|
336 | this._recent.unshift(recentCommand.id);
|
337 | }
|
338 | }
|
339 | |
340 |
|
341 |
|
342 | clearCommandHistory() {
|
343 | this.recent = [];
|
344 | }
|
345 | };
|
346 | CommandRegistry = __decorate([
|
347 | (0, inversify_1.injectable)(),
|
348 | __param(0, (0, inversify_1.inject)(contribution_provider_1.ContributionProvider)),
|
349 | __param(0, (0, inversify_1.named)(exports.CommandContribution)),
|
350 | __metadata("design:paramtypes", [Object])
|
351 | ], CommandRegistry);
|
352 | exports.CommandRegistry = CommandRegistry;
|
353 |
|
\ | No newline at end of file |