good lord
This commit is contained in:
parent
d493f6e551
commit
b278f2faf8
|
@ -115,8 +115,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
// These are special cases.
|
||||
// - QuakeMode: deserializes into a GlobalSummon, so we don't need a serializer
|
||||
// - Invalid: has no args
|
||||
// - ExplicitlyUnbound: specifically for the "unbound" case.
|
||||
{ ShortcutAction::QuakeMode, { GlobalSummonArgs::QuakeModeFromJson, nullptr } },
|
||||
{ ShortcutAction::Invalid, { nullptr, nullptr } },
|
||||
{ ShortcutAction::Unbound, { nullptr, nullptr } },
|
||||
|
||||
#define ON_ALL_ACTIONS_WITH_ARGS(action) ACTION_TO_SERIALIZERS_PAIR(action)
|
||||
ALL_SHORTCUT_ACTIONS_WITH_ARGS
|
||||
|
@ -161,6 +163,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
// - The ShortcutAction corresponding to the given string, if a match exists.
|
||||
static ShortcutAction GetActionFromString(const std::string_view actionString)
|
||||
{
|
||||
if (actionString == UnboundKey)
|
||||
{
|
||||
return ShortcutAction::Unbound;
|
||||
}
|
||||
|
||||
// Try matching the command to one we have. If we can't find the
|
||||
// action name in our list of names, let's just unbind that key.
|
||||
const auto found = ActionAndArgs::ActionKeyNamesMap.find(actionString);
|
||||
|
@ -306,6 +313,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
return copy;
|
||||
}
|
||||
|
||||
bool ActionAndArgs::IsUnbound() const
|
||||
{
|
||||
return _Action == ShortcutAction::Invalid || _Action == ShortcutAction::Unbound;
|
||||
}
|
||||
|
||||
winrt::hstring ActionAndArgs::GenerateName() const
|
||||
{
|
||||
// Use a magic static to initialize this map, because we won't be able
|
||||
|
|
|
@ -26,6 +26,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
|
||||
hstring GenerateName() const;
|
||||
|
||||
bool IsUnbound() const;
|
||||
|
||||
WINRT_PROPERTY(ShortcutAction, Action, ShortcutAction::Invalid);
|
||||
WINRT_PROPERTY(IActionArgs, Args, nullptr);
|
||||
};
|
||||
|
|
|
@ -444,6 +444,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
if (!name.empty())
|
||||
{
|
||||
_NestedCommands.emplace(name, cmd);
|
||||
|
||||
if (!cmd.ExternalID().empty())
|
||||
{
|
||||
_ExternalIDToSpecialCommands.emplace(cmd.ExternalID(), cmd);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -452,6 +457,12 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
if (cmdImpl->IterateOn() != ExpandCommandType::None)
|
||||
{
|
||||
_IterableCommands.emplace_back(cmd);
|
||||
|
||||
if (!cmd.ExternalID().empty())
|
||||
{
|
||||
_ExternalIDToSpecialCommands.emplace(cmd.ExternalID(), cmd);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -476,11 +487,55 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
// _TryUpdateActionMap may update oldCmd and maskingCmd
|
||||
Model::Command oldCmd{ nullptr };
|
||||
Model::Command maskingCmd{ nullptr };
|
||||
_TryUpdateActionMap(cmd, oldCmd, maskingCmd);
|
||||
|
||||
_TryUpdateExternalID(cmd, oldCmd, maskingCmd);
|
||||
_TryUpdateName(cmd, oldCmd, maskingCmd);
|
||||
_TryUpdateKeyChord(cmd, oldCmd, maskingCmd);
|
||||
// _TryUpdateActionWithID may update mergedCmd
|
||||
// that should be passed through the rest of the update functions.
|
||||
Model::Command mergedCmd{ cmd };
|
||||
if (!cmd.ExternalID().empty())
|
||||
{
|
||||
// Try to find a use of the ID in our layer, then in our parents.
|
||||
// If found in our layer, set it to oldCmd. If found in parents,
|
||||
// set it to maskingCmd.
|
||||
const auto& externalPair = _ExternalIDMap.find(cmd.ExternalID());
|
||||
if (externalPair != _ExternalIDMap.end())
|
||||
{
|
||||
oldCmd = _ActionMap.find(externalPair->second)->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The user is referring to an action defined in another layer.
|
||||
// We should make a copy of that action, apply the incoming action
|
||||
// on top of it (replace action, name, etc.), then re-add the action
|
||||
for (const auto& parent : _parents)
|
||||
{
|
||||
auto parentAction = parent->GetActionByExternalID(cmd.ExternalID());
|
||||
if (parentAction && *parentAction)
|
||||
{
|
||||
// We've found an action in a parent with the ID, so we want to update
|
||||
// that parent action with whatever we've got in our command.
|
||||
// In order to update, we'll make a copy of the parent action, layer
|
||||
// our command on top of it, and re-add it to the parent layer.
|
||||
const auto parentActionImpl{ get_self<implementation::Command>(*parentAction) };
|
||||
const auto parentActionCopy{ parentActionImpl->Copy() };
|
||||
parentActionCopy->LayerCommand(cmd);
|
||||
|
||||
parent->DeleteAction(Hash(parentAction->ActionAndArgs()));
|
||||
parent->AddAction(*parentActionCopy);
|
||||
|
||||
mergedCmd = *parentActionCopy;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_ExternalIDMap.emplace(cmd.ExternalID(), Hash(mergedCmd.ActionAndArgs()));
|
||||
}
|
||||
}
|
||||
|
||||
_TryUpdateActionMap(mergedCmd, oldCmd, maskingCmd);
|
||||
|
||||
_TryUpdateExternalID(mergedCmd, oldCmd, maskingCmd);
|
||||
_TryUpdateName(mergedCmd, oldCmd, maskingCmd);
|
||||
_TryUpdateKeyChord(mergedCmd, oldCmd, maskingCmd);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
@ -496,35 +551,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
const auto actionID{ Hash(cmd.ActionAndArgs()) };
|
||||
const auto& actionPair{ _ActionMap.find(actionID) };
|
||||
|
||||
if (!cmd.ExternalID().empty())
|
||||
// Example:
|
||||
// { "command": "copy", "keys": "ctrl+c" } --> add the action in for the first time
|
||||
// { "command": "copy", "keys": "ctrl+shift+c" } --> update oldCmd
|
||||
if (!oldCmd)
|
||||
{
|
||||
const auto& externalPair = _ExternalIDMap.find(cmd.ExternalID());
|
||||
if (externalPair == _ExternalIDMap.end())
|
||||
{
|
||||
_ExternalIDMap.emplace(cmd.ExternalID(), actionID);
|
||||
|
||||
if (actionPair == _ActionMap.end())
|
||||
{
|
||||
// add this action in for the first time
|
||||
_ActionMap.emplace(actionID, cmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We're adding an action that already exists in our layer.
|
||||
// Record it so that we update it with any new information.
|
||||
oldCmd = actionPair->second;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
oldCmd = _ActionMap.find(externalPair->second)->second;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Example:
|
||||
// { "command": "copy", "keys": "ctrl+c" } --> add the action in for the first time
|
||||
// { "command": "copy", "keys": "ctrl+shift+c" } --> update oldCmd
|
||||
if (actionPair == _ActionMap.end())
|
||||
{
|
||||
// add this action in for the first time
|
||||
|
@ -553,37 +584,15 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
FAIL_FAST_IF(_parents.size() > 1);
|
||||
for (const auto& parent : _parents)
|
||||
{
|
||||
if (!cmd.ExternalID().empty())
|
||||
// NOTE: This only checks the layer above us, but that's ok.
|
||||
// If we had to find one from a layer above that, parent->_MaskingActions
|
||||
// would have found it, so we inherit it for free!
|
||||
auto inheritedCmd{ parent->_GetActionByID(actionID) };
|
||||
if (inheritedCmd && *inheritedCmd)
|
||||
{
|
||||
auto inheritedCmdWithID{ parent->GetActionByExternalID(cmd.ExternalID()) };
|
||||
if (inheritedCmdWithID && *inheritedCmdWithID)
|
||||
{
|
||||
// We've found an action in a parent layer that has the same external
|
||||
// ID as our current layer action. We'll need to overwrite the parent's info.
|
||||
|
||||
// Update the parent's action with the incoming action.
|
||||
parent->_TryUpdateAction(Hash(inheritedCmdWithID->ActionAndArgs()), cmd);
|
||||
|
||||
auto newParentAction{ parent->_GetActionByID(actionID) };
|
||||
if (newParentAction && *newParentAction)
|
||||
{
|
||||
maskingCmd = *newParentAction;
|
||||
_MaskingActions.emplace(actionID, maskingCmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: This only checks the layer above us, but that's ok.
|
||||
// If we had to find one from a layer above that, parent->_MaskingActions
|
||||
// would have found it, so we inherit it for free!
|
||||
auto inheritedCmd{ parent->_GetActionByID(actionID) };
|
||||
if (inheritedCmd && *inheritedCmd)
|
||||
{
|
||||
const auto& inheritedCmdImpl{ get_self<Command>(*inheritedCmd) };
|
||||
maskingCmd = *inheritedCmdImpl->Copy();
|
||||
_MaskingActions.emplace(actionID, maskingCmd);
|
||||
}
|
||||
const auto& inheritedCmdImpl{ get_self<Command>(*inheritedCmd) };
|
||||
maskingCmd = *inheritedCmdImpl->Copy();
|
||||
_MaskingActions.emplace(actionID, maskingCmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -595,59 +604,43 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
}
|
||||
}
|
||||
|
||||
void ActionMap::_StashIncompleteActions(const Model::Command& cmd)
|
||||
void ActionMap::_StashExternalIDActions(const Model::Command& cmd)
|
||||
{
|
||||
// Stash commands with external IDs so we can combine them
|
||||
// and AddAction when we know there's no more declarations using the ID.
|
||||
// As we continue to come across action definitions with external
|
||||
// IDs defined, we'll merge the action info into one object.
|
||||
// We'll always take the latest name and command, and we'll register
|
||||
// all the keys that are defined to this action.
|
||||
//
|
||||
// Once we've finished parsing the actions array for the layer,
|
||||
// we'll iterate through our resulting actions and add them
|
||||
// to the action map.
|
||||
//
|
||||
// Example:
|
||||
// {
|
||||
// "id": "customaction",
|
||||
// "keys": "ctrl+shift+g"
|
||||
// },
|
||||
// {
|
||||
// "id": "customaction",
|
||||
// "name": "customaction"
|
||||
// },
|
||||
// {
|
||||
// "id": "customaction",
|
||||
// "command": "copy"
|
||||
// }
|
||||
// { "id": "customaction", "keys": "ctrl+shift+g"},
|
||||
// { "id": "customaction", "name": "customaction"},
|
||||
// { "id": "customaction", "command": "copy"}, --> Results in {"id": "customaction", "command": "copy", "keys": "ctrl+shift+g", "name": "customaction"}
|
||||
// { "id": "customaction", "keys": "ctrl+v"},
|
||||
// { "id": "customaction", "command": "paste"} --> Results in {"id": "customaction", "command": "paste", "keys": {"ctrl+shift+g", "ctrl+v"}, "name": "customaction"}
|
||||
//
|
||||
if (!cmd.ExternalID().empty())
|
||||
{
|
||||
std::wstring externalID{ cmd.ExternalID() };
|
||||
if (externalID == L"")
|
||||
{
|
||||
|
||||
}
|
||||
// Add it to incomplete, or combine it with an existing incomplete.
|
||||
auto incompletePair{ _ExternalIDStaging.find(cmd.ExternalID()) };
|
||||
if (incompletePair == _ExternalIDStaging.end())
|
||||
auto stagingPair{ _ExternalIDStaging.find(cmd.ExternalID()) };
|
||||
if (stagingPair == _ExternalIDStaging.end())
|
||||
{
|
||||
_ExternalIDStaging.emplace(cmd.ExternalID(), cmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto incompleteImpl{ get_self<Command>(incompletePair->second) };
|
||||
const auto cmdImpl{ get_self<Command>(cmd) };
|
||||
if (cmdImpl->HasName())
|
||||
{
|
||||
incompleteImpl->Name(cmdImpl->Name());
|
||||
}
|
||||
if (cmdImpl->Keys())
|
||||
{
|
||||
incompleteImpl->RegisterKey(cmdImpl->Keys());
|
||||
}
|
||||
|
||||
if ((incompleteImpl->ActionAndArgs().Action() == ShortcutAction::Invalid) ||
|
||||
(cmd.ActionAndArgs().Action() != ShortcutAction::Invalid))
|
||||
{
|
||||
incompleteImpl->ActionAndArgs(cmd.ActionAndArgs());
|
||||
}
|
||||
// Merge the incoming cmd with the one found in staging.
|
||||
// We'll overwrite the staging cmd's values if the incoming cmd has those values.
|
||||
const auto incompleteImpl{ get_self<Command>(stagingPair->second) };
|
||||
incompleteImpl->LayerCommand(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ActionMap::_AddIncompleteActions()
|
||||
void ActionMap::_AddStashedActions()
|
||||
{
|
||||
for (const auto& [id, cmd]: _ExternalIDStaging)
|
||||
{
|
||||
|
@ -656,29 +649,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
_ExternalIDStaging.clear();
|
||||
}
|
||||
|
||||
void ActionMap::_TryUpdateAction(const InternalActionID actionID, const Model::Command& action)
|
||||
{
|
||||
const auto& newActionHash{ Hash(action.ActionAndArgs()) };
|
||||
const auto& actionPair{ _ActionMap.find(actionID) };
|
||||
if (actionPair != _ActionMap.end())
|
||||
{
|
||||
// ActionMap update
|
||||
auto actionMapNode = _ActionMap.extract(actionID);
|
||||
actionMapNode.key() = newActionHash;
|
||||
_ActionMap.insert(std::move(actionMapNode));
|
||||
|
||||
// KeyMap update
|
||||
const auto& actionImpl = get_self<implementation::Command>(*_GetActionByID(newActionHash));
|
||||
for (const auto& keychord : actionImpl->KeyMappings())
|
||||
{
|
||||
_KeyMap.insert_or_assign(keychord, newActionHash);
|
||||
}
|
||||
|
||||
// ExternalIDMap update
|
||||
_ExternalIDMap.insert_or_assign(action.ExternalID(), newActionHash);
|
||||
}
|
||||
}
|
||||
|
||||
void ActionMap::_TryUpdateExternalID(const Model::Command& cmd, Model::Command& oldCmd, Model::Command& maskingCmd)
|
||||
{
|
||||
if (cmd.ExternalID().empty())
|
||||
|
@ -975,16 +945,52 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
std::optional<Model::Command> ActionMap::GetActionByExternalID(const winrt::hstring& externalID) const
|
||||
{
|
||||
const auto idMapPair{ _ExternalIDMap.find(externalID) };
|
||||
const auto specialMapPair{ _ExternalIDToSpecialCommands.find(externalID) };
|
||||
|
||||
if (idMapPair != _ExternalIDMap.end())
|
||||
{
|
||||
// Really there should be no scenario where an ExternalID mapping to InternalID
|
||||
// mapping exists but the InternalID doesn't have an action associated to it right?
|
||||
return _GetActionByID(idMapPair->second);
|
||||
}
|
||||
else if (specialMapPair != _ExternalIDToSpecialCommands.end())
|
||||
{
|
||||
return specialMapPair->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ActionMap::DeleteAction(const InternalActionID& id)
|
||||
{
|
||||
if (auto action = _GetActionByID(id))
|
||||
{
|
||||
// Removing from KeyMap
|
||||
const auto& actionImpl = get_self<implementation::Command>(*action);
|
||||
for (const auto& keychord : actionImpl->KeyMappings())
|
||||
{
|
||||
// Double check that the keychord of this command is mapped to itself.
|
||||
auto keyMapPair = _KeyMap.find(keychord);
|
||||
if (keyMapPair != _KeyMap.end())
|
||||
{
|
||||
if (keyMapPair->second == id)
|
||||
{
|
||||
_KeyMap.erase(keychord);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Removing from ExternalIDMap
|
||||
if (!action->ExternalID().empty())
|
||||
{
|
||||
_ExternalIDMap.erase(action->ExternalID());
|
||||
}
|
||||
|
||||
// Remove from ActionMap
|
||||
_ActionMap.erase(id);
|
||||
|
||||
// TODO: How will I remove it if it's Nested/Iterable commands?
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Rebinds a key binding to a new key chord
|
||||
// Arguments:
|
||||
|
|
|
@ -73,6 +73,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
Json::Value ToJson() const;
|
||||
|
||||
// modification
|
||||
void DeleteAction(const InternalActionID& id);
|
||||
bool RebindKeys(Control::KeyChord const& oldKeys, Control::KeyChord const& newKeys);
|
||||
void DeleteKeyBinding(Control::KeyChord const& keys);
|
||||
void RegisterKeyBinding(Control::KeyChord keys, Model::ActionAndArgs action);
|
||||
|
@ -92,9 +93,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
void _TryUpdateName(const Model::Command& cmd, const Model::Command& oldCmd, const Model::Command& consolidatedCmd);
|
||||
void _TryUpdateKeyChord(const Model::Command& cmd, const Model::Command& oldCmd, const Model::Command& consolidatedCmd);
|
||||
void _TryUpdateExternalID(const Model::Command& cmd, Model::Command& oldCmd, Model::Command& consolidatedCmd);
|
||||
void _TryUpdateAction(const InternalActionID oldActionID, const Model::Command& action);
|
||||
void _AddIncompleteActions();
|
||||
void _StashIncompleteActions(const Model::Command& cmd);
|
||||
void _AddStashedActions();
|
||||
void _StashExternalIDActions(const Model::Command& cmd);
|
||||
|
||||
Windows::Foundation::Collections::IMap<hstring, Model::ActionAndArgs> _AvailableActionsCache{ nullptr };
|
||||
Windows::Foundation::Collections::IMap<hstring, Model::Command> _NameMapCache{ nullptr };
|
||||
|
@ -106,6 +106,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
std::unordered_map<Control::KeyChord, InternalActionID, KeyChordHash, KeyChordEquality> _KeyMap;
|
||||
std::unordered_map<InternalActionID, Model::Command> _ActionMap;
|
||||
std::unordered_map<winrt::hstring, InternalActionID> _ExternalIDMap;
|
||||
std::unordered_map<winrt::hstring, Model::Command> _ExternalIDToSpecialCommands;
|
||||
std::unordered_map<winrt::hstring, Model::Command> _ExternalIDStaging;
|
||||
|
||||
// Masking Actions:
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
|
||||
if (!cmd->ExternalID().empty())
|
||||
{
|
||||
_StashIncompleteActions(*cmd);
|
||||
_StashExternalIDActions(*cmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -62,7 +62,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
}
|
||||
}
|
||||
|
||||
_AddIncompleteActions();
|
||||
_AddStashedActions();
|
||||
|
||||
return warnings;
|
||||
}
|
||||
|
|
|
@ -67,6 +67,16 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
return _subcommands ? _subcommands.GetView() : nullptr;
|
||||
}
|
||||
|
||||
void Command::NestedCommands(const IMapView<winrt::hstring, Model::Command>& commands)
|
||||
{
|
||||
_subcommands.Clear();
|
||||
for (auto kv : commands)
|
||||
{
|
||||
const auto subCmd{ winrt::get_self<Command>(kv.Value()) };
|
||||
_subcommands.Insert(kv.Key(), *subCmd->Copy());
|
||||
}
|
||||
}
|
||||
|
||||
// Function Description:
|
||||
// - reports if the current command has nested commands
|
||||
// - This CANNOT detect { "name": "foo", "commands": null }
|
||||
|
@ -255,6 +265,14 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
{
|
||||
auto result = winrt::make_self<Command>();
|
||||
|
||||
if (const auto idJson{ json[JsonKey(IdKey)] })
|
||||
{
|
||||
if (idJson.isString())
|
||||
{
|
||||
result->ExternalID(to_hstring(idJson.asCString()));
|
||||
}
|
||||
}
|
||||
|
||||
bool nested = false;
|
||||
JsonUtils::GetValueForKey(json, IterateOnKey, result->_IterateOn);
|
||||
|
||||
|
@ -293,14 +311,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
// If we're a nested command, we can ignore the current action.
|
||||
if (!nested)
|
||||
{
|
||||
if (const auto idJson{ json[JsonKey(IdKey)] })
|
||||
{
|
||||
if (idJson.isString())
|
||||
{
|
||||
result->ExternalID(to_hstring(idJson.asCString()));
|
||||
}
|
||||
}
|
||||
|
||||
if (const auto actionJson{ json[JsonKey(ActionKey)] })
|
||||
{
|
||||
result->_ActionAndArgs = *ActionAndArgs::FromJson(actionJson, warnings);
|
||||
|
@ -646,4 +656,38 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
|
||||
return newCommands;
|
||||
}
|
||||
|
||||
void Command::LayerCommand(const Model::Command& cmd)
|
||||
{
|
||||
// Merge the incoming cmd with the one found in staging.
|
||||
// We'll overwrite the staging cmd's values if the incoming cmd has those values.
|
||||
const auto cmdImpl{ get_self<Command>(cmd) };
|
||||
if (cmdImpl->HasName())
|
||||
{
|
||||
Name(cmdImpl->Name());
|
||||
}
|
||||
|
||||
for (const auto& keys : cmdImpl->KeyMappings())
|
||||
{
|
||||
RegisterKey(keys);
|
||||
}
|
||||
|
||||
if (!cmdImpl->IconPath().empty())
|
||||
{
|
||||
IconPath(cmd.IconPath());
|
||||
}
|
||||
|
||||
// Copy over the nested commands if there are some.
|
||||
// Otherwise just copy the ActionAndArgs if they're valid.
|
||||
IterateOn(cmdImpl->IterateOn());
|
||||
if (cmdImpl->HasNestedCommands())
|
||||
{
|
||||
NestedCommands(cmd.NestedCommands());
|
||||
}
|
||||
|
||||
if (cmd.ActionAndArgs().Action() != ShortcutAction::Invalid)
|
||||
{
|
||||
ActionAndArgs(cmd.ActionAndArgs());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
{
|
||||
Command();
|
||||
com_ptr<Command> Copy() const;
|
||||
void Merge(const com_ptr<Command>& cmd);
|
||||
|
||||
static winrt::com_ptr<Command> FromJson(const Json::Value& json,
|
||||
std::vector<SettingsLoadWarnings>& warnings);
|
||||
|
@ -54,6 +55,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
bool HasNestedCommands() const;
|
||||
bool IsNestedCommand() const noexcept;
|
||||
Windows::Foundation::Collections::IMapView<winrt::hstring, Model::Command> NestedCommands() const;
|
||||
void NestedCommands(const Windows::Foundation::Collections::IMapView<winrt::hstring, Model::Command>& commands);
|
||||
|
||||
bool HasName() const noexcept;
|
||||
hstring Name() const noexcept;
|
||||
|
@ -68,6 +70,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
hstring IconPath() const noexcept;
|
||||
void IconPath(const hstring& val);
|
||||
|
||||
void LayerCommand(const Model::Command& cmd);
|
||||
|
||||
winrt::Windows::UI::Xaml::Data::INotifyPropertyChanged::PropertyChanged_revoker propertyChangedRevoker;
|
||||
|
||||
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
|
||||
|
|
|
@ -12,7 +12,8 @@ namespace Microsoft.Terminal.Settings.Model
|
|||
{
|
||||
enum ShortcutAction
|
||||
{
|
||||
Invalid = 0, // treat Invalid as unbound actions
|
||||
Invalid = 0,
|
||||
Unbound = 1,
|
||||
|
||||
// When adding a new action, add them to AllShortcutActions.h!
|
||||
#define ON_ALL_ACTIONS(action) action,
|
||||
|
@ -26,6 +27,8 @@ namespace Microsoft.Terminal.Settings.Model
|
|||
|
||||
IActionArgs Args;
|
||||
ShortcutAction Action;
|
||||
|
||||
Boolean IsUnbound();
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass Command : Windows.UI.Xaml.Data.INotifyPropertyChanged
|
||||
|
|
Loading…
Reference in a new issue