Skip to content

Commit

Permalink
Teach flyouts and palette to prefer user bindings over defaults (#8725)
Browse files Browse the repository at this point in the history
Store the order of the bindings and upon lookup prefer the binding
that was added last.
The defaults will always "loose" to user overrides.

Closes #2991
  • Loading branch information
Don-Vito authored Jan 12, 2021
1 parent 7235996 commit 058cbd1
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 2 deletions.
20 changes: 18 additions & 2 deletions src/cascadia/TerminalSettingsModel/KeyMapping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,14 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
void KeyMapping::SetKeyBinding(const Microsoft::Terminal::Settings::Model::ActionAndArgs& actionAndArgs,
const KeyChord& chord)
{
// if the chord is already mapped - clear the mapping
if (_keyShortcuts.find(chord) != _keyShortcuts.end())
{
ClearKeyBinding(chord);
}

_keyShortcuts[chord] = actionAndArgs;
_keyShortcutsByInsertionOrder.push_back(std::make_pair(chord, actionAndArgs));
}

// Method Description:
Expand All @@ -53,12 +60,19 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
void KeyMapping::ClearKeyBinding(const KeyChord& chord)
{
_keyShortcuts.erase(chord);

KeyChordEquality keyChordEquality;
_keyShortcutsByInsertionOrder.erase(std::remove_if(_keyShortcutsByInsertionOrder.begin(), _keyShortcutsByInsertionOrder.end(), [keyChordEquality, chord](const auto& keyBinding) {
return keyChordEquality(keyBinding.first, chord);
}),
_keyShortcutsByInsertionOrder.end());
}

KeyChord KeyMapping::GetKeyBindingForAction(Microsoft::Terminal::Settings::Model::ShortcutAction const& action)
{
for (auto& kv : _keyShortcuts)
for (auto it = _keyShortcutsByInsertionOrder.rbegin(); it != _keyShortcutsByInsertionOrder.rend(); ++it)
{
const auto& kv = *it;
if (kv.second.Action() == action)
{
return kv.first;
Expand All @@ -72,6 +86,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
// and IActionArgs. This enables searching no only for the binding of a
// particular ShortcutAction, but also a particular set of values for
// arguments to that action.
// If several bindings might match the lookup, prefers the one that was added last.
// Arguments:
// - actionAndArgs: The ActionAndArgs to lookup the keybinding for.
// Return Value:
Expand All @@ -83,8 +98,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
return { nullptr };
}

for (auto& kv : _keyShortcuts)
for (auto it = _keyShortcutsByInsertionOrder.rbegin(); it != _keyShortcutsByInsertionOrder.rend(); ++it)
{
const auto& kv = *it;
const auto action = kv.second.Action();
const auto args = kv.second.Args();
const auto actionMatched = action == actionAndArgs.Action();
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalSettingsModel/KeyMapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation

private:
std::unordered_map<TerminalControl::KeyChord, Model::ActionAndArgs, KeyChordHash, KeyChordEquality> _keyShortcuts;
std::vector<std::pair<TerminalControl::KeyChord, Model::ActionAndArgs>> _keyShortcutsByInsertionOrder;

friend class SettingsModelLocalTests::DeserializationTests;
friend class SettingsModelLocalTests::KeyBindingsTests;
Expand Down

0 comments on commit 058cbd1

Please sign in to comment.