Skip to content

Commit

Permalink
Add action to run multiple actions. (#11045)
Browse files Browse the repository at this point in the history
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
Add a new action that can contain multiple other actions.

<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> 
## References

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes #3992
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [x] Schema updated.
* [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx

<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
Creates a shortcut action that allows a list of actions to be specified as arguments. Steals a bunch of the serialization code from my other pr. Overall, because I had the serialization code written already, this was remarkably easy.

I can't think of any combined action to be added to the defaults, so I think this is just a thing for the documentation unless someone else has a good example. I know there are lot of times when the recommended workaround is "make an action with commandline wt.exe ..." and this could be a good replacement for that, but that is all personalized.

I didn't add this to the command line parsing, since the command line is already a way to run multiple actions.

<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Created a new command, confirmed that "Move right->down" showed up in the command palette, and that running it did the correct behavior (moving right one pane, then down one pane).
```
      {
        "command": {
          "action": "multipleActions",
          "name": "Move right->down",
          "actions": [
            {"action":  "moveFocus", "direction": "right" },
            {"action":  "moveFocus", "direction": "down" },
          ]
        }
      }
```
  • Loading branch information
Rosefield authored Aug 31, 2021
1 parent 717ea85 commit 8d81497
Show file tree
Hide file tree
Showing 10 changed files with 213 additions and 44 deletions.
19 changes: 19 additions & 0 deletions doc/cascadia/profiles.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@
"movePane",
"swapPane",
"moveTab",
"multipleActions",
"newTab",
"newWindow",
"nextTab",
Expand Down Expand Up @@ -825,6 +826,24 @@
],
"required": [ "direction" ]
},
"MultipleActionsAction": {
"description": "Arguments for the multiple actions command",
"allOf": [
{ "$ref": "#/definitions/ShortcutAction" },
{
"properties": {
"action": { "type": "string", "pattern": "multipleActions" },
"actions" : {
"$ref": "#/definitions/ShortcutAction",
"type": "array",
"minItems": 1,
"description": "A list of other actions."
}
}
}
],
"required": [ "actions" ]
},
"CommandPaletteAction": {
"description": "Arguments for a commandPalette action",
"allOf": [
Expand Down
17 changes: 17 additions & 0 deletions src/cascadia/TerminalApp/AppActionHandlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -874,4 +874,21 @@ namespace winrt::TerminalApp::implementation
}
}
}

void TerminalPage::_HandleMultipleActions(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
if (args)
{
if (const auto& realArgs = args.ActionArgs().try_as<MultipleActionsArgs>())
{
for (const auto& action : realArgs.Actions())
{
_actionDispatch->DoAction(action);
}

args.Handled(true);
}
}
}
}
2 changes: 2 additions & 0 deletions src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ static constexpr std::string_view OpenWindowRenamerKey{ "openWindowRenamer" };
static constexpr std::string_view GlobalSummonKey{ "globalSummon" };
static constexpr std::string_view QuakeModeKey{ "quakeMode" };
static constexpr std::string_view FocusPaneKey{ "focusPane" };
static constexpr std::string_view MultipleActionsKey{ "multipleActions" };

static constexpr std::string_view ActionKey{ "action" };

Expand Down Expand Up @@ -366,6 +367,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{ ShortcutAction::GlobalSummon, L"" }, // Intentionally omitted, must be generated by GenerateName
{ ShortcutAction::QuakeMode, RS_(L"QuakeModeCommandKey") },
{ ShortcutAction::FocusPane, L"" }, // Intentionally omitted, must be generated by GenerateName
{ ShortcutAction::MultipleActions, L"" }, // Intentionally omitted, must be generated by GenerateName
};
}();

Expand Down
31 changes: 31 additions & 0 deletions src/cascadia/TerminalSettingsModel/ActionAndArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,34 @@ namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation
{
BASIC_FACTORY(ActionAndArgs);
}

namespace Microsoft::Terminal::Settings::Model::JsonUtils
{
using namespace winrt::Microsoft::Terminal::Settings::Model;

template<>
struct ConversionTrait<ActionAndArgs>
{
ActionAndArgs FromJson(const Json::Value& json)
{
std::vector<SettingsLoadWarnings> v;
return *implementation::ActionAndArgs::FromJson(json, v);
}

bool CanConvert(const Json::Value& json) const
{
// commands without args might just be a string
return json.isString() || json.isObject();
}

Json::Value ToJson(const ActionAndArgs& val)
{
return implementation::ActionAndArgs::ToJson(val);
}

std::string TypeDescription() const
{
return "ActionAndArgs";
}
};
}
6 changes: 6 additions & 0 deletions src/cascadia/TerminalSettingsModel/ActionArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "RenameWindowArgs.g.cpp"
#include "GlobalSummonArgs.g.cpp"
#include "FocusPaneArgs.g.cpp"
#include "MultipleActionsArgs.g.cpp"

#include <LibraryResources.h>

Expand Down Expand Up @@ -687,4 +688,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
Id())
};
}

winrt::hstring MultipleActionsArgs::GenerateName() const
{
return L"";
}
}
49 changes: 49 additions & 0 deletions src/cascadia/TerminalSettingsModel/ActionArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "RenameWindowArgs.g.h"
#include "GlobalSummonArgs.g.h"
#include "FocusPaneArgs.g.h"
#include "MultipleActionsArgs.g.h"

#include "../../cascadia/inc/cppwinrt_utils.h"
#include "JsonUtils.h"
Expand Down Expand Up @@ -1754,6 +1755,53 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
};

struct MultipleActionsArgs : public MultipleActionsArgsT<MultipleActionsArgs>
{
MultipleActionsArgs() = default;
WINRT_PROPERTY(Windows::Foundation::Collections::IVector<ActionAndArgs>, Actions);
static constexpr std::string_view ActionsKey{ "actions" };

public:
hstring GenerateName() const;

bool Equals(const IActionArgs& other)
{
auto otherAsUs = other.try_as<MultipleActionsArgs>();
if (otherAsUs)
{
return otherAsUs->_Actions == _Actions;
}
return false;
};
static FromJsonResult FromJson(const Json::Value& json)
{
// LOAD BEARING: Not using make_self here _will_ break you in the future!
auto args = winrt::make_self<MultipleActionsArgs>();
JsonUtils::GetValueForKey(json, ActionsKey, args->_Actions);
return { *args, {} };
}
static Json::Value ToJson(const IActionArgs& val)
{
if (!val)
{
return {};
}
Json::Value json{ Json::ValueType::objectValue };
const auto args{ get_self<MultipleActionsArgs>(val) };
JsonUtils::SetValueForKey(json, ActionsKey, args->_Actions);
return json;
}
IActionArgs Copy() const
{
auto copy{ winrt::make_self<MultipleActionsArgs>() };
copy->_Actions = _Actions;
return *copy;
}
size_t Hash() const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_Actions);
}
};
}

namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation
Expand All @@ -1778,4 +1826,5 @@ namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation
BASIC_FACTORY(FocusPaneArgs);
BASIC_FACTORY(PrevTabArgs);
BASIC_FACTORY(NextTabArgs);
BASIC_FACTORY(MultipleActionsArgs);
}
8 changes: 8 additions & 0 deletions src/cascadia/TerminalSettingsModel/ActionArgs.idl
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import "Command.idl";

namespace Microsoft.Terminal.Settings.Model
{
interface IActionArgs
Expand Down Expand Up @@ -308,4 +310,10 @@ namespace Microsoft.Terminal.Settings.Model
FocusPaneArgs(UInt32 Id);
UInt32 Id { get; };
};

[default_interface] runtimeclass MultipleActionsArgs : IActionArgs
{
MultipleActionsArgs();
Windows.Foundation.Collections.IVector<ActionAndArgs> Actions;
}
}
6 changes: 4 additions & 2 deletions src/cascadia/TerminalSettingsModel/AllShortcutActions.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@
ON_ALL_ACTIONS(OpenWindowRenamer) \
ON_ALL_ACTIONS(GlobalSummon) \
ON_ALL_ACTIONS(QuakeMode) \
ON_ALL_ACTIONS(FocusPane)
ON_ALL_ACTIONS(FocusPane) \
ON_ALL_ACTIONS(MultipleActions)

#define ALL_SHORTCUT_ACTIONS_WITH_ARGS \
ON_ALL_ACTIONS_WITH_ARGS(AdjustFontSize) \
Expand Down Expand Up @@ -109,4 +110,5 @@
ON_ALL_ACTIONS_WITH_ARGS(SplitPane) \
ON_ALL_ACTIONS_WITH_ARGS(SwitchToTab) \
ON_ALL_ACTIONS_WITH_ARGS(ToggleCommandPalette) \
ON_ALL_ACTIONS_WITH_ARGS(FocusPane)
ON_ALL_ACTIONS_WITH_ARGS(FocusPane) \
ON_ALL_ACTIONS_WITH_ARGS(MultipleActions)
42 changes: 0 additions & 42 deletions src/cascadia/TerminalSettingsModel/ApplicationState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,48 +55,6 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils
return fmt::format("{}[]", ConversionTrait<GUID>{}.TypeDescription());
}
};

template<typename T>
struct ConversionTrait<winrt::Windows::Foundation::Collections::IVector<T>>
{
winrt::Windows::Foundation::Collections::IVector<T> FromJson(const Json::Value& json) const
{
ConversionTrait<T> trait;
std::vector<T> val;
val.reserve(json.size());

for (const auto& element : json)
{
val.push_back(trait.FromJson(element));
}

return winrt::single_threaded_vector(move(val));
}

bool CanConvert(const Json::Value& json) const
{
ConversionTrait<T> trait;
return json.isArray() && std::all_of(json.begin(), json.end(), [trait](const auto& json) -> bool { return trait.CanConvert(json); });
}

Json::Value ToJson(const winrt::Windows::Foundation::Collections::IVector<T>& val)
{
ConversionTrait<T> trait;
Json::Value json{ Json::arrayValue };

for (const auto& key : val)
{
json.append(trait.ToJson(key));
}

return json;
}

std::string TypeDescription() const
{
return fmt::format("vector ({})", ConversionTrait<T>{}.TypeDescription());
}
};
}

using namespace ::Microsoft::Terminal::Settings::Model;
Expand Down
77 changes: 77 additions & 0 deletions src/cascadia/TerminalSettingsModel/JsonUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,47 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils
}
};

template<typename T>
struct ConversionTrait<std::vector<T>>
{
std::vector<T> FromJson(const Json::Value& json)
{
std::vector<T> val;
val.reserve(json.size());

ConversionTrait<T> trait;
for (const auto& element : json)
{
val.push_back(trait.FromJson(element));
}

return val;
}

bool CanConvert(const Json::Value& json) const
{
ConversionTrait<T> trait;
return json.isArray() && std::all_of(json.begin(), json.end(), [trait](const auto& json) mutable -> bool { return trait.CanConvert(json); });
}

Json::Value ToJson(const std::vector<T>& val)
{
Json::Value json{ Json::arrayValue };

ConversionTrait<T> trait;
for (const auto& v : val)
{
json.append(trait.ToJson(v));
}

return json;
}
std::string TypeDescription() const
{
return fmt::format("{}[]", ConversionTrait<T>{}.TypeDescription());
}
};

template<typename T>
struct ConversionTrait<std::unordered_map<std::string, T>>
{
Expand Down Expand Up @@ -259,6 +300,42 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils
}
};

template<typename T>
struct ConversionTrait<winrt::Windows::Foundation::Collections::IVector<T>>
{
winrt::Windows::Foundation::Collections::IVector<T> FromJson(const Json::Value& json)
{
ConversionTrait<std::vector<T>> trait;
return winrt::single_threaded_vector<T>(std::move(trait.FromJson(json)));
}

bool CanConvert(const Json::Value& json) const
{
ConversionTrait<std::vector<T>> trait;
return trait.CanConvert(json);
}

Json::Value ToJson(const winrt::Windows::Foundation::Collections::IVector<T>& val)
{
Json::Value json{ Json::arrayValue };

if (val)
{
ConversionTrait<T> trait;
for (const auto& v : val)
{
json.append(trait.ToJson(v));
}
}

return json;
}
std::string TypeDescription() const
{
return fmt::format("{}[]", ConversionTrait<T>{}.TypeDescription());
}
};

template<typename T>
struct ConversionTrait<winrt::Windows::Foundation::Collections::IMap<winrt::hstring, T>>
{
Expand Down

0 comments on commit 8d81497

Please sign in to comment.