UNPKG

29.4 kBJavaScriptView Raw
1"use strict";
2// *****************************************************************************
3// Copyright (C) 2017 TypeFox and others.
4//
5// This program and the accompanying materials are made available under the
6// terms of the Eclipse Public License v. 2.0 which is available at
7// http://www.eclipse.org/legal/epl-2.0.
8//
9// This Source Code may also be made available under the following Secondary
10// Licenses when the conditions for such availability set forth in the Eclipse
11// Public License v. 2.0 are satisfied: GNU General Public License, version 2
12// with the GNU Classpath Exception which is available at
13// https://www.gnu.org/software/classpath/license.html.
14//
15// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
16// *****************************************************************************
17var __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};
23var __metadata = (this && this.__metadata) || function (k, v) {
24 if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
25};
26var KeybindingRegistry_1;
27Object.defineProperty(exports, "__esModule", { value: true });
28exports.KeybindingRegistry = exports.KeybindingContexts = exports.KeybindingContext = exports.KeybindingContribution = exports.Keybinding = exports.KeybindingScope = void 0;
29const inversify_1 = require("inversify");
30const os_1 = require("../common/os");
31const event_1 = require("../common/event");
32const command_1 = require("../common/command");
33const disposable_1 = require("../common/disposable");
34const keys_1 = require("./keyboard/keys");
35const keyboard_layout_service_1 = require("./keyboard/keyboard-layout-service");
36const contribution_provider_1 = require("../common/contribution-provider");
37const logger_1 = require("../common/logger");
38const status_bar_1 = require("./status-bar/status-bar");
39const context_key_service_1 = require("./context-key-service");
40const core_preferences_1 = require("./core-preferences");
41const common = require("../common/keybinding");
42const nls_1 = require("../common/nls");
43var KeybindingScope;
44(function (KeybindingScope) {
45 KeybindingScope[KeybindingScope["DEFAULT"] = 0] = "DEFAULT";
46 KeybindingScope[KeybindingScope["USER"] = 1] = "USER";
47 KeybindingScope[KeybindingScope["WORKSPACE"] = 2] = "WORKSPACE";
48 KeybindingScope[KeybindingScope["END"] = 3] = "END";
49})(KeybindingScope = exports.KeybindingScope || (exports.KeybindingScope = {}));
50(function (KeybindingScope) {
51 KeybindingScope.length = KeybindingScope.END - KeybindingScope.DEFAULT;
52})(KeybindingScope = exports.KeybindingScope || (exports.KeybindingScope = {}));
53exports.Keybinding = common.Keybinding;
54exports.KeybindingContribution = Symbol('KeybindingContribution');
55exports.KeybindingContext = Symbol('KeybindingContext');
56var KeybindingContexts;
57(function (KeybindingContexts) {
58 KeybindingContexts.NOOP_CONTEXT = {
59 id: 'noop.keybinding.context',
60 isEnabled: () => true
61 };
62 KeybindingContexts.DEFAULT_CONTEXT = {
63 id: 'default.keybinding.context',
64 isEnabled: () => false
65 };
66})(KeybindingContexts = exports.KeybindingContexts || (exports.KeybindingContexts = {}));
67let KeybindingRegistry = KeybindingRegistry_1 = class KeybindingRegistry {
68 constructor() {
69 this.keySequence = [];
70 this.contexts = {};
71 this.keymaps = [...Array(KeybindingScope.length)].map(() => []);
72 this.keybindingsChanged = new event_1.Emitter();
73 this.toResetKeymap = new Map();
74 }
75 async onStart() {
76 await this.keyboardLayoutService.initialize();
77 this.keyboardLayoutService.onKeyboardLayoutChanged(newLayout => {
78 this.clearResolvedKeybindings();
79 this.keybindingsChanged.fire(undefined);
80 });
81 this.registerContext(KeybindingContexts.NOOP_CONTEXT);
82 this.registerContext(KeybindingContexts.DEFAULT_CONTEXT);
83 this.registerContext(...this.contextProvider.getContributions());
84 for (const contribution of this.contributions.getContributions()) {
85 contribution.registerKeybindings(this);
86 }
87 }
88 /**
89 * Event that is fired when the resolved keybindings change due to a different keyboard layout
90 * or when a new keymap is being set
91 */
92 get onKeybindingsChanged() {
93 return this.keybindingsChanged.event;
94 }
95 /**
96 * Registers the keybinding context arguments into the application. Fails when an already registered
97 * context is being registered.
98 *
99 * @param contexts the keybinding contexts to register into the application.
100 */
101 registerContext(...contexts) {
102 for (const context of contexts) {
103 const { id } = context;
104 if (this.contexts[id]) {
105 this.logger.error(`A keybinding context with ID ${id} is already registered.`);
106 }
107 else {
108 this.contexts[id] = context;
109 }
110 }
111 }
112 /**
113 * Register a default keybinding to the registry.
114 *
115 * Keybindings registered later have higher priority during evaluation.
116 *
117 * @param binding the keybinding to be registered
118 */
119 registerKeybinding(binding) {
120 return this.doRegisterKeybinding(binding);
121 }
122 /**
123 * Register multiple default keybindings to the registry
124 *
125 * @param bindings An array of keybinding to be registered
126 */
127 registerKeybindings(...bindings) {
128 return this.doRegisterKeybindings(bindings, KeybindingScope.DEFAULT);
129 }
130 unregisterKeybinding(arg) {
131 const keymap = this.keymaps[KeybindingScope.DEFAULT];
132 const filter = command_1.Command.is(arg)
133 ? ({ command }) => command === arg.id
134 : ({ keybinding }) => exports.Keybinding.is(arg)
135 ? keybinding === arg.keybinding
136 : keybinding === arg;
137 for (const binding of keymap.filter(filter)) {
138 const idx = keymap.indexOf(binding);
139 if (idx !== -1) {
140 keymap.splice(idx, 1);
141 }
142 }
143 }
144 doRegisterKeybindings(bindings, scope = KeybindingScope.DEFAULT) {
145 const toDispose = new disposable_1.DisposableCollection();
146 for (const binding of bindings) {
147 toDispose.push(this.doRegisterKeybinding(binding, scope));
148 }
149 return toDispose;
150 }
151 doRegisterKeybinding(binding, scope = KeybindingScope.DEFAULT) {
152 try {
153 this.resolveKeybinding(binding);
154 const scoped = Object.assign(binding, { scope });
155 this.insertBindingIntoScope(scoped, scope);
156 return disposable_1.Disposable.create(() => {
157 const index = this.keymaps[scope].indexOf(scoped);
158 if (index !== -1) {
159 this.keymaps[scope].splice(index, 1);
160 }
161 });
162 }
163 catch (error) {
164 this.logger.warn(`Could not register keybinding:\n ${common.Keybinding.stringify(binding)}\n${error}`);
165 return disposable_1.Disposable.NULL;
166 }
167 }
168 /**
169 * Ensures that keybindings are inserted in order of increasing length of binding to ensure that if a
170 * user triggers a short keybinding (e.g. ctrl+k), the UI won't wait for a longer one (e.g. ctrl+k enter)
171 */
172 insertBindingIntoScope(item, scope) {
173 const scopedKeymap = this.keymaps[scope];
174 const getNumberOfKeystrokes = (binding) => { var _a, _b; return ((_b = (_a = binding.keybinding.trim().match(/\s/g)) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) + 1; };
175 const numberOfKeystrokesInBinding = getNumberOfKeystrokes(item);
176 const indexOfFirstItemWithEqualStrokes = scopedKeymap.findIndex(existingBinding => getNumberOfKeystrokes(existingBinding) === numberOfKeystrokesInBinding);
177 if (indexOfFirstItemWithEqualStrokes > -1) {
178 scopedKeymap.splice(indexOfFirstItemWithEqualStrokes, 0, item);
179 }
180 else {
181 scopedKeymap.push(item);
182 }
183 }
184 /**
185 * Ensure that the `resolved` property of the given binding is set by calling the KeyboardLayoutService.
186 */
187 resolveKeybinding(binding) {
188 if (!binding.resolved) {
189 const sequence = keys_1.KeySequence.parse(binding.keybinding);
190 binding.resolved = sequence.map(code => this.keyboardLayoutService.resolveKeyCode(code));
191 }
192 return binding.resolved;
193 }
194 /**
195 * Clear all `resolved` properties of registered keybindings so the KeyboardLayoutService is called
196 * again to resolve them. This is necessary when the user's keyboard layout has changed.
197 */
198 clearResolvedKeybindings() {
199 for (let i = KeybindingScope.DEFAULT; i < KeybindingScope.END; i++) {
200 const bindings = this.keymaps[i];
201 for (let j = 0; j < bindings.length; j++) {
202 const binding = bindings[j];
203 binding.resolved = undefined;
204 }
205 }
206 }
207 /**
208 * Checks whether a colliding {@link common.Keybinding} exists in a specific scope.
209 * @param binding the keybinding to check
210 * @param scope the keybinding scope to check
211 * @returns true if there is a colliding keybinding
212 */
213 containsKeybindingInScope(binding, scope = KeybindingScope.USER) {
214 const bindingKeySequence = this.resolveKeybinding(binding);
215 const collisions = this.getKeySequenceCollisions(this.getUsableBindings(this.keymaps[scope]), bindingKeySequence)
216 .filter(b => b.context === binding.context && !b.when && !binding.when);
217 if (collisions.full.length > 0) {
218 return true;
219 }
220 if (collisions.partial.length > 0) {
221 return true;
222 }
223 if (collisions.shadow.length > 0) {
224 return true;
225 }
226 return false;
227 }
228 /**
229 * Get a user visible representation of a {@link common.Keybinding}.
230 * @returns an array of strings representing all elements of the {@link KeySequence} defined by the {@link common.Keybinding}
231 * @param keybinding the keybinding
232 * @param separator the separator to be used to stringify {@link KeyCode}s that are part of the {@link KeySequence}
233 */
234 acceleratorFor(keybinding, separator = ' ', asciiOnly = false) {
235 const bindingKeySequence = this.resolveKeybinding(keybinding);
236 return this.acceleratorForSequence(bindingKeySequence, separator, asciiOnly);
237 }
238 /**
239 * Get a user visible representation of a {@link KeySequence}.
240 * @returns an array of strings representing all elements of the {@link KeySequence}
241 * @param keySequence the keysequence
242 * @param separator the separator to be used to stringify {@link KeyCode}s that are part of the {@link KeySequence}
243 */
244 acceleratorForSequence(keySequence, separator = ' ', asciiOnly = false) {
245 return keySequence.map(keyCode => this.acceleratorForKeyCode(keyCode, separator, asciiOnly));
246 }
247 /**
248 * Get a user visible representation of a key code (a key with modifiers).
249 * @returns a string representing the {@link KeyCode}
250 * @param keyCode the keycode
251 * @param separator the separator used to separate keys (key and modifiers) in the returning string
252 * @param asciiOnly if `true`, no special characters will be substituted into the string returned. Ensures correct keyboard shortcuts in Electron menus.
253 */
254 acceleratorForKeyCode(keyCode, separator = ' ', asciiOnly = false) {
255 return this.componentsForKeyCode(keyCode, asciiOnly).join(separator);
256 }
257 componentsForKeyCode(keyCode, asciiOnly = false) {
258 const keyCodeResult = [];
259 const useSymbols = os_1.isOSX && !asciiOnly;
260 if (keyCode.meta && os_1.isOSX) {
261 keyCodeResult.push(useSymbols ? '⌘' : 'Cmd');
262 }
263 if (keyCode.ctrl) {
264 keyCodeResult.push(useSymbols ? '⌃' : 'Ctrl');
265 }
266 if (keyCode.alt) {
267 keyCodeResult.push(useSymbols ? '⌥' : 'Alt');
268 }
269 if (keyCode.shift) {
270 keyCodeResult.push(useSymbols ? '⇧' : 'Shift');
271 }
272 if (keyCode.key) {
273 keyCodeResult.push(this.acceleratorForKey(keyCode.key, asciiOnly));
274 }
275 return keyCodeResult;
276 }
277 /**
278 * @param asciiOnly if `true`, no special characters will be substituted into the string returned. Ensures correct keyboard shortcuts in Electron menus.
279 *
280 * Return a user visible representation of a single key.
281 */
282 acceleratorForKey(key, asciiOnly = false) {
283 if (os_1.isOSX && !asciiOnly) {
284 if (key === keys_1.Key.ARROW_LEFT) {
285 return '←';
286 }
287 if (key === keys_1.Key.ARROW_RIGHT) {
288 return '→';
289 }
290 if (key === keys_1.Key.ARROW_UP) {
291 return '↑';
292 }
293 if (key === keys_1.Key.ARROW_DOWN) {
294 return '↓';
295 }
296 }
297 const keyString = this.keyboardLayoutService.getKeyboardCharacter(key);
298 if (key.keyCode >= keys_1.Key.KEY_A.keyCode && key.keyCode <= keys_1.Key.KEY_Z.keyCode ||
299 key.keyCode >= keys_1.Key.F1.keyCode && key.keyCode <= keys_1.Key.F24.keyCode) {
300 return keyString.toUpperCase();
301 }
302 else if (keyString.length > 1) {
303 return keyString.charAt(0).toUpperCase() + keyString.slice(1);
304 }
305 else {
306 return keyString;
307 }
308 }
309 /**
310 * Finds collisions for a key sequence inside a list of bindings (error-free)
311 *
312 * @param bindings the reference bindings
313 * @param candidate the sequence to match
314 */
315 getKeySequenceCollisions(bindings, candidate) {
316 const result = new KeybindingRegistry_1.KeybindingsResult();
317 for (const binding of bindings) {
318 try {
319 const bindingKeySequence = this.resolveKeybinding(binding);
320 const compareResult = keys_1.KeySequence.compare(candidate, bindingKeySequence);
321 switch (compareResult) {
322 case keys_1.KeySequence.CompareResult.FULL: {
323 result.full.push(binding);
324 break;
325 }
326 case keys_1.KeySequence.CompareResult.PARTIAL: {
327 result.partial.push(binding);
328 break;
329 }
330 case keys_1.KeySequence.CompareResult.SHADOW: {
331 result.shadow.push(binding);
332 break;
333 }
334 }
335 }
336 catch (error) {
337 this.logger.warn(error);
338 }
339 }
340 return result;
341 }
342 /**
343 * Get all keybindings associated to a commandId.
344 *
345 * @param commandId The ID of the command for which we are looking for keybindings.
346 * @returns an array of {@link ScopedKeybinding}
347 */
348 getKeybindingsForCommand(commandId) {
349 const result = [];
350 const disabledBindings = new Set();
351 for (let scope = KeybindingScope.END - 1; scope >= KeybindingScope.DEFAULT; scope--) {
352 this.keymaps[scope].forEach(binding => {
353 var _a;
354 if ((_a = binding.command) === null || _a === void 0 ? void 0 : _a.startsWith('-')) {
355 disabledBindings.add(JSON.stringify({ command: binding.command.substring(1), binding: binding.keybinding, context: binding.context, when: binding.when }));
356 }
357 else {
358 const command = this.commandRegistry.getCommand(binding.command);
359 if (command
360 && command.id === commandId
361 && !disabledBindings.has(JSON.stringify({ command: binding.command, binding: binding.keybinding, context: binding.context, when: binding.when }))) {
362 result.push({ ...binding, scope });
363 }
364 }
365 });
366 }
367 return result;
368 }
369 isActive(binding) {
370 /* Pseudo commands like "passthrough" are always active (and not found
371 in the command registry). */
372 if (this.isPseudoCommand(binding.command)) {
373 return true;
374 }
375 const command = this.commandRegistry.getCommand(binding.command);
376 return !!command && !!this.commandRegistry.getActiveHandler(command.id);
377 }
378 /**
379 * Tries to execute a keybinding.
380 *
381 * @param binding to execute
382 * @param event keyboard event.
383 */
384 executeKeyBinding(binding, event) {
385 if (this.isPseudoCommand(binding.command)) {
386 /* Don't do anything, let the event propagate. */
387 }
388 else {
389 const command = this.commandRegistry.getCommand(binding.command);
390 if (command) {
391 if (this.commandRegistry.isEnabled(binding.command, binding.args)) {
392 this.commandRegistry.executeCommand(binding.command, binding.args)
393 .catch(e => console.error('Failed to execute command:', e));
394 }
395 /* Note that if a keybinding is in context but the command is
396 not active we still stop the processing here. */
397 event.preventDefault();
398 event.stopPropagation();
399 }
400 }
401 }
402 /**
403 * Only execute if it has no context (global context) or if we're in that context.
404 */
405 isEnabled(binding, event) {
406 return this.isEnabledInScope(binding, event.target);
407 }
408 isEnabledInScope(binding, target) {
409 const context = binding.context && this.contexts[binding.context];
410 if (context && !context.isEnabled(binding)) {
411 return false;
412 }
413 if (binding.when && !this.whenContextService.match(binding.when, target)) {
414 return false;
415 }
416 return true;
417 }
418 dispatchCommand(id, target) {
419 const keybindings = this.getKeybindingsForCommand(id);
420 if (keybindings.length) {
421 for (const keyCode of this.resolveKeybinding(keybindings[0])) {
422 this.dispatchKeyDown(keyCode, target);
423 }
424 }
425 }
426 dispatchKeyDown(input, target = document.activeElement || window) {
427 const eventInit = this.asKeyboardEventInit(input);
428 const emulatedKeyboardEvent = new KeyboardEvent('keydown', eventInit);
429 target.dispatchEvent(emulatedKeyboardEvent);
430 }
431 asKeyboardEventInit(input) {
432 if (typeof input === 'string') {
433 return this.asKeyboardEventInit(keys_1.KeyCode.createKeyCode(input));
434 }
435 if (input instanceof keys_1.KeyCode) {
436 return {
437 metaKey: input.meta,
438 shiftKey: input.shift,
439 altKey: input.alt,
440 ctrlKey: input.ctrl,
441 code: input.key && input.key.code,
442 key: (input && input.character) || (input.key && input.key.code),
443 keyCode: input.key && input.key.keyCode
444 };
445 }
446 return input;
447 }
448 registerEventListeners(win) {
449 /* vvv HOTFIX begin vvv
450 *
451 * This is a hotfix against issues eclipse/theia#6459 and gitpod-io/gitpod#875 .
452 * It should be reverted after Theia was updated to the newer Monaco.
453 */
454 let inComposition = false;
455 const compositionStart = () => {
456 inComposition = true;
457 };
458 win.document.addEventListener('compositionstart', compositionStart);
459 const compositionEnd = () => {
460 inComposition = false;
461 };
462 win.document.addEventListener('compositionend', compositionEnd);
463 const keydown = (event) => {
464 if (inComposition !== true) {
465 this.run(event);
466 }
467 };
468 win.document.addEventListener('keydown', keydown, true);
469 return disposable_1.Disposable.create(() => {
470 win.document.removeEventListener('compositionstart', compositionStart);
471 win.document.removeEventListener('compositionend', compositionEnd);
472 win.document.removeEventListener('keydown', keydown);
473 });
474 }
475 /**
476 * Run the command matching to the given keyboard event.
477 */
478 run(event) {
479 if (event.defaultPrevented) {
480 return;
481 }
482 const eventDispatch = this.corePreferences['keyboard.dispatch'];
483 const keyCode = keys_1.KeyCode.createKeyCode(event, eventDispatch);
484 /* Keycode is only a modifier, next keycode will be modifier + key.
485 Ignore this one. */
486 if (keyCode.isModifierOnly()) {
487 return;
488 }
489 this.keyboardLayoutService.validateKeyCode(keyCode);
490 this.keySequence.push(keyCode);
491 const match = this.matchKeybinding(this.keySequence, event);
492 if (match && match.kind === 'partial') {
493 /* Accumulate the keysequence */
494 event.preventDefault();
495 event.stopPropagation();
496 this.statusBar.setElement('keybinding-status', {
497 text: nls_1.nls.localize('theia/core/keybindingStatus', '{0} was pressed, waiting for more keys', `(${this.acceleratorForSequence(this.keySequence, '+')})`),
498 alignment: status_bar_1.StatusBarAlignment.LEFT,
499 priority: 2
500 });
501 }
502 else {
503 if (match && match.kind === 'full') {
504 this.executeKeyBinding(match.binding, event);
505 }
506 this.keySequence = [];
507 this.statusBar.removeElement('keybinding-status');
508 }
509 }
510 /**
511 * Match first binding in the current context.
512 * Keybindings ordered by a scope and by a registration order within the scope.
513 *
514 * FIXME:
515 * This method should run very fast since it happens on each keystroke. We should reconsider how keybindings are stored.
516 * It should be possible to look up full and partial keybinding for given key sequence for constant time using some kind of tree.
517 * Such tree should not contain disabled keybindings and be invalidated whenever the registry is changed.
518 */
519 matchKeybinding(keySequence, event) {
520 let disabled;
521 const isEnabled = (binding) => {
522 if (event && !this.isEnabled(binding, event)) {
523 return false;
524 }
525 const { command, context, when, keybinding } = binding;
526 if (!this.isUsable(binding)) {
527 disabled = disabled || new Set();
528 disabled.add(JSON.stringify({ command: command.substring(1), context, when, keybinding }));
529 return false;
530 }
531 return !(disabled === null || disabled === void 0 ? void 0 : disabled.has(JSON.stringify({ command, context, when, keybinding })));
532 };
533 for (let scope = KeybindingScope.END; --scope >= KeybindingScope.DEFAULT;) {
534 for (const binding of this.keymaps[scope]) {
535 const resolved = this.resolveKeybinding(binding);
536 const compareResult = keys_1.KeySequence.compare(keySequence, resolved);
537 if (compareResult === keys_1.KeySequence.CompareResult.FULL && isEnabled(binding)) {
538 return { kind: 'full', binding };
539 }
540 if (compareResult === keys_1.KeySequence.CompareResult.PARTIAL && isEnabled(binding)) {
541 return { kind: 'partial', binding };
542 }
543 }
544 }
545 return undefined;
546 }
547 /**
548 * Returns true if the binding is usable
549 * @param binding Binding to be checked
550 */
551 isUsable(binding) {
552 return binding.command.charAt(0) !== '-';
553 }
554 /**
555 * Return a new filtered array containing only the usable bindings among the input bindings
556 * @param bindings Bindings to filter
557 */
558 getUsableBindings(bindings) {
559 return bindings.filter(binding => this.isUsable(binding));
560 }
561 /**
562 * Return true of string a pseudo-command id, in other words a command id
563 * that has a special meaning and that we won't find in the command
564 * registry.
565 *
566 * @param commandId commandId to test
567 */
568 isPseudoCommand(commandId) {
569 return commandId === KeybindingRegistry_1.PASSTHROUGH_PSEUDO_COMMAND;
570 }
571 /**
572 * Sets a new keymap replacing all existing {@link common.Keybinding}s in the given scope.
573 * @param scope the keybinding scope
574 * @param bindings an array containing the new {@link common.Keybinding}s
575 */
576 setKeymap(scope, bindings) {
577 this.resetKeybindingsForScope(scope);
578 this.toResetKeymap.set(scope, this.doRegisterKeybindings(bindings, scope));
579 this.keybindingsChanged.fire(undefined);
580 }
581 /**
582 * Reset keybindings for a specific scope
583 * @param scope scope to reset the keybindings for
584 */
585 resetKeybindingsForScope(scope) {
586 const toReset = this.toResetKeymap.get(scope);
587 if (toReset) {
588 toReset.dispose();
589 }
590 }
591 /**
592 * Reset keybindings for all scopes(only leaves the default keybindings mapped)
593 */
594 resetKeybindings() {
595 for (let i = KeybindingScope.DEFAULT + 1; i < KeybindingScope.END; i++) {
596 this.keymaps[i] = [];
597 }
598 }
599 /**
600 * Get all {@link common.Keybinding}s for a {@link KeybindingScope}.
601 * @returns an array of {@link common.ScopedKeybinding}
602 * @param scope the keybinding scope to retrieve the {@link common.Keybinding}s for.
603 */
604 getKeybindingsByScope(scope) {
605 return this.keymaps[scope];
606 }
607};
608KeybindingRegistry.PASSTHROUGH_PSEUDO_COMMAND = 'passthrough';
609__decorate([
610 (0, inversify_1.inject)(core_preferences_1.CorePreferences),
611 __metadata("design:type", Object)
612], KeybindingRegistry.prototype, "corePreferences", void 0);
613__decorate([
614 (0, inversify_1.inject)(keyboard_layout_service_1.KeyboardLayoutService),
615 __metadata("design:type", keyboard_layout_service_1.KeyboardLayoutService)
616], KeybindingRegistry.prototype, "keyboardLayoutService", void 0);
617__decorate([
618 (0, inversify_1.inject)(contribution_provider_1.ContributionProvider),
619 (0, inversify_1.named)(exports.KeybindingContext),
620 __metadata("design:type", Object)
621], KeybindingRegistry.prototype, "contextProvider", void 0);
622__decorate([
623 (0, inversify_1.inject)(command_1.CommandRegistry),
624 __metadata("design:type", command_1.CommandRegistry)
625], KeybindingRegistry.prototype, "commandRegistry", void 0);
626__decorate([
627 (0, inversify_1.inject)(contribution_provider_1.ContributionProvider),
628 (0, inversify_1.named)(exports.KeybindingContribution),
629 __metadata("design:type", Object)
630], KeybindingRegistry.prototype, "contributions", void 0);
631__decorate([
632 (0, inversify_1.inject)(status_bar_1.StatusBar),
633 __metadata("design:type", Object)
634], KeybindingRegistry.prototype, "statusBar", void 0);
635__decorate([
636 (0, inversify_1.inject)(logger_1.ILogger),
637 __metadata("design:type", Object)
638], KeybindingRegistry.prototype, "logger", void 0);
639__decorate([
640 (0, inversify_1.inject)(context_key_service_1.ContextKeyService),
641 __metadata("design:type", Object)
642], KeybindingRegistry.prototype, "whenContextService", void 0);
643KeybindingRegistry = KeybindingRegistry_1 = __decorate([
644 (0, inversify_1.injectable)()
645], KeybindingRegistry);
646exports.KeybindingRegistry = KeybindingRegistry;
647(function (KeybindingRegistry) {
648 class KeybindingsResult {
649 constructor() {
650 this.full = [];
651 this.partial = [];
652 this.shadow = [];
653 }
654 /**
655 * Merge two results together inside `this`
656 *
657 * @param other the other KeybindingsResult to merge with
658 * @return this
659 */
660 merge(other) {
661 this.full.push(...other.full);
662 this.partial.push(...other.partial);
663 this.shadow.push(...other.shadow);
664 return this;
665 }
666 /**
667 * Returns a new filtered KeybindingsResult
668 *
669 * @param fn callback filter on the results
670 * @return filtered new result
671 */
672 filter(fn) {
673 const result = new KeybindingsResult();
674 result.full = this.full.filter(fn);
675 result.partial = this.partial.filter(fn);
676 result.shadow = this.shadow.filter(fn);
677 return result;
678 }
679 }
680 KeybindingRegistry.KeybindingsResult = KeybindingsResult;
681})(KeybindingRegistry = exports.KeybindingRegistry || (exports.KeybindingRegistry = {}));
682exports.KeybindingRegistry = KeybindingRegistry;
683//# sourceMappingURL=keybinding.js.map
\No newline at end of file