Skip to content
This repository was archived by the owner on Sep 6, 2021. It is now read-only.

Commit 13f85b4

Browse files
committed
Merge pull request #10110 from adobe/rlim/extension-key-bindings
Fix two issues of user key map for extension commands.
2 parents 10846d8 + eb12144 commit 13f85b4

1 file changed

Lines changed: 67 additions & 18 deletions

File tree

src/command/KeyBindingManager.js

Lines changed: 67 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -80,25 +80,32 @@ define(function (require, exports, module) {
8080
* Maps commandID to the list of shortcuts that are bound to it.
8181
* @type {!Object.<string, Array.<{key: string, displayKey: string}>>}
8282
*/
83-
var _commandMap = {},
84-
_allCommands = [];
83+
var _commandMap = {};
84+
85+
/**
86+
* @private
87+
* An array of command ID for all the available commands including the commands
88+
* of installed extensions.
89+
* @type {Array.<string>}
90+
*/
91+
var _allCommands = [];
8592

8693
/**
8794
* @private
8895
* Maps key names to the corresponding unicode symols
8996
* @type {{key: string, displayKey: string}}
9097
*/
91-
var _displayKeyMap = { "up": "\u2191",
92-
"down": "\u2193",
93-
"left": "\u2190",
94-
"right": "\u2192",
95-
"-": "\u2212" };
98+
var _displayKeyMap = { "up": "\u2191",
99+
"down": "\u2193",
100+
"left": "\u2190",
101+
"right": "\u2192",
102+
"-": "\u2212" };
96103

97-
var _specialCommands = [Commands.EDIT_UNDO, Commands.EDIT_REDO, Commands.EDIT_SELECT_ALL,
98-
Commands.EDIT_CUT, Commands.EDIT_COPY, Commands.EDIT_PASTE],
99-
_reservedShortcuts = ["Ctrl-Z", "Ctrl-Y", "Ctrl-A", "Ctrl-X", "Ctrl-C", "Ctrl-V"],
104+
var _specialCommands = [Commands.EDIT_UNDO, Commands.EDIT_REDO, Commands.EDIT_SELECT_ALL,
105+
Commands.EDIT_CUT, Commands.EDIT_COPY, Commands.EDIT_PASTE],
106+
_reservedShortcuts = ["Ctrl-Z", "Ctrl-Y", "Ctrl-A", "Ctrl-X", "Ctrl-C", "Ctrl-V"],
100107
_macReservedShortcuts = ["Cmd-,", "Cmd-H", "Cmd-Alt-H", "Cmd-M", "Cmd-Shift-Z", "Cmd-Q"],
101-
_keyNames = ["Up", "Down", "Left", "Right", "Backspace", "Enter", "Space", "Tab"];
108+
_keyNames = ["Up", "Down", "Left", "Right", "Backspace", "Enter", "Space", "Tab"];
102109

103110
/**
104111
* @private
@@ -124,6 +131,13 @@ define(function (require, exports, module) {
124131
* @type {Array.<function(Event): boolean>}
125132
*/
126133
var _globalKeydownHooks = [];
134+
135+
/**
136+
* @private
137+
* Forward declaration for JSLint.
138+
* @type {Function}
139+
*/
140+
var _loadUserKeyMap;
127141

128142
/**
129143
* @private
@@ -429,6 +443,29 @@ define(function (require, exports, module) {
429443
}
430444
}
431445

446+
/**
447+
* @private
448+
*
449+
* Updates _allCommands array and _defaultKeyMap with the new key binding
450+
* if it is not yet in the _allCommands array. _allCommands array is initialized
451+
* only in extensionsLoaded event. So any new commands or key bindings added after
452+
* that will be updated here.
453+
*
454+
* @param {{commandID: string, key: string, displayKey:string, explicitPlatform: string}} newBinding
455+
*/
456+
function _updateCommandAndKeyMaps(newBinding) {
457+
if (_allCommands.length === 0) {
458+
return;
459+
}
460+
461+
if (newBinding && newBinding.commandID && _allCommands.indexOf(newBinding.commandID) === -1) {
462+
_defaultKeyMap[newBinding.commandID] = _.cloneDeep(newBinding);
463+
464+
// Process user key map again to catch any reassignment to all new key bindings added from extensions.
465+
_loadUserKeyMap();
466+
}
467+
}
468+
432469
/**
433470
* @private
434471
*
@@ -437,11 +474,12 @@ define(function (require, exports, module) {
437474
* @param {?string} platform
438475
* - "all" indicates all platforms, not overridable
439476
* - undefined indicates all platforms, overridden by platform-specific binding
477+
* @param {boolean=} userBindings true if adding a user key binding or undefined otherwise.
440478
* @return {?{key: string, displayKey:String}} Returns a record for valid key bindings.
441479
* Returns null when key binding platform does not match, binding does not normalize,
442480
* or is already assigned.
443481
*/
444-
function _addBinding(commandID, keyBinding, platform) {
482+
function _addBinding(commandID, keyBinding, platform, userBindings) {
445483
var key,
446484
result = null,
447485
normalized,
@@ -585,6 +623,10 @@ define(function (require, exports, module) {
585623
explicitPlatform : explicitPlatform
586624
};
587625

626+
if (!userBindings) {
627+
_updateCommandAndKeyMaps(_keyMap[normalized]);
628+
}
629+
588630
// notify listeners
589631
command = CommandManager.get(commandID);
590632

@@ -1007,7 +1049,7 @@ define(function (require, exports, module) {
10071049
var keybinding = { key: normalizedKey };
10081050

10091051
keybinding.displayKey = _getDisplayKey(normalizedKey);
1010-
addBinding(commandID, keybinding.displayKey ? keybinding : normalizedKey, brackets.platform);
1052+
_addBinding(commandID, keybinding.displayKey ? keybinding : normalizedKey, brackets.platform, true);
10111053
remappedCommands.push(commandID);
10121054
} else {
10131055
multipleKeys.push(commandID);
@@ -1158,18 +1200,27 @@ define(function (require, exports, module) {
11581200
* binding by removing the existing one assigned to each key and adding
11591201
* new one for the specified command id. Shows errors and opens the user
11601202
* key map file if it cannot be parsed.
1203+
*
1204+
* This function is wrapped with debounce so that its execution is always delayed
1205+
* by 200 ms. The delay is required because when this function is called some
1206+
* extensions may still be adding some commands and their key bindings asychronously.
11611207
*/
1162-
function _loadUserKeyMap() {
1208+
_loadUserKeyMap = _.debounce(function () {
11631209
_readUserKeyMap()
11641210
.then(function (keyMap) {
1211+
// Some extensions may add a new command without any key binding. So
1212+
// we always have to get all commands again to ensure that we also have
1213+
// those from any extensions installed during the current session.
1214+
_allCommands = CommandManager.getAll();
1215+
11651216
_customKeyMapCache = _.cloneDeep(_customKeyMap);
11661217
_customKeyMap = keyMap;
11671218
_undoPriorUserKeyBindings();
11681219
_applyUserKeyBindings();
11691220
}, function (err) {
11701221
_showErrorsAndOpenKeyMap(err);
11711222
});
1172-
}
1223+
}, 200);
11731224

11741225
/**
11751226
* @private
@@ -1214,8 +1265,6 @@ define(function (require, exports, module) {
12141265
*
12151266
* Initializes _allCommands array and _defaultKeyMap so that we can use them for
12161267
* detecting non-existent commands and restoring the original key binding.
1217-
*
1218-
* @param {string} fullPath file path to the user key map file.
12191268
*/
12201269
function _initCommandAndKeyMaps() {
12211270
_allCommands = CommandManager.getAll();
@@ -1241,7 +1290,7 @@ define(function (require, exports, module) {
12411290
if (params.get("reloadWithoutUserExts") === "true") {
12421291
_showErrors = false;
12431292
}
1244-
1293+
12451294
_initCommandAndKeyMaps();
12461295
_loadUserKeyMap();
12471296
});

0 commit comments

Comments
 (0)