Introduce serialization for actions (#9926)

## Summary of the Pull Request

This PR builds on the `ActionMap` PR (#6900) by leveraging `ActionMap` to serialize actions. From the top down, the process is now as follows:
- `CascadiaSettings`: remove the hack of copying whatever we had for actions before.
- `GlobalAppSettings`: serialize the `ActionMap` to `"actions": []`
- `ActionMap`: iterate over the internal `_ActionMap` (list of actions) and serialize each `Command`
- `Command`: **THIS IS WHERE THE MAGIC HAPPENS!** For _each_ key mapping, serialize an action. Only the first one needs to include the name and icon.
- `ActionAndArgs`: Find the relevant `IActionArgs` parser and serialize the `ActionAndArgs`.
- `ActionArgs`: **ANNOYING CHANGE** Serialize any args that are set. We _need_ each setting to be saved as a `std::optional`. As with inheritance, this allows us to distinguish an explicit setting to the default value (sometimes `null`) vs an implicit "give me the default value". This allows us to serialize only the relevant details of each action, rather than writing _all_ of the args.

## References
- #8100: Inheritance/Layering for lists
   - This tracks layering and better serialization for color schemes _and_ actions. This PR resolves half of that issue. The next step is to apply the concepts used in this PR (and #9621) to solve the similar problem for color schemes.
- #6900: Actions page

## Validation Steps Performed
Tests added!
This commit is contained in:
Carlos Zamora 2021-05-20 14:44:04 -04:00 committed by GitHub
parent 13f0b8e007
commit ff8fdbd243
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 846 additions and 276 deletions

View file

@ -2069,6 +2069,8 @@ selectany
SELECTEDFONT
SELECTSTRING
Selfhosters
serializer
serializers
SERVERDLL
SETACTIVE
SETBUDDYINT

View file

@ -39,6 +39,7 @@ namespace SettingsModelLocalTests
TEST_METHOD(GlobalSettings);
TEST_METHOD(Profile);
TEST_METHOD(ColorScheme);
TEST_METHOD(Actions);
TEST_METHOD(CascadiaSettings);
TEST_CLASS_SETUP(ClassSetup)
@ -106,12 +107,15 @@ namespace SettingsModelLocalTests
"experimental.input.forceVT": false,
"experimental.rendering.forceFullRepaint": false,
"experimental.rendering.software": false
"experimental.rendering.software": false,
"actions": []
})" };
const std::string smallGlobalsString{ R"(
{
"defaultProfile": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}"
"defaultProfile": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
"actions": []
})" };
RoundtripTest<implementation::GlobalAppSettings>(globalsString);
@ -178,7 +182,9 @@ namespace SettingsModelLocalTests
// - null should be acceptable even though we're working with colors
const std::string weirdProfileString{ R"(
{
"guid" : "{8b039d4d-77ca-5a83-88e1-dfc8e895a127}",
"name": "Weird Profile",
"hidden": false,
"tabColor": null,
"foreground": null,
"source": "local"
@ -221,6 +227,149 @@ namespace SettingsModelLocalTests
RoundtripTest<implementation::ColorScheme>(schemeString);
}
void SerializationTests::Actions()
{
const std::string actionsString1{ R"([
{ "command": "paste" }
])" };
const std::string actionsString2A{ R"([
{ "command": { "action": "setTabColor" } }
])" };
const std::string actionsString2B{ R"([
{ "command": { "action": "setTabColor", "color": "#112233" } }
])" };
const std::string actionsString2C{ R"([
{ "command": { "action": "copy" } },
{ "command": { "action": "copy", "singleLine": true, "copyFormatting": "html" } }
])" };
const std::string actionsString3{ R"([
{ "command": "toggleAlwaysOnTop", "keys": "ctrl+a" },
{ "command": "toggleAlwaysOnTop", "keys": "ctrl+b" }
])" };
const std::string actionsString4{ R"([
{ "command": { "action": "adjustFontSize", "delta": 1 }, "keys": "ctrl+c" },
{ "command": { "action": "adjustFontSize", "delta": 1 }, "keys": "ctrl+d" }
])" };
const std::string actionsString5{ R"([
{ "icon": "image.png", "name": "Scroll To Top Name", "command": "scrollToTop", "keys": "ctrl+e" },
{ "command": "scrollToTop", "keys": "ctrl+f" }
])" };
const std::string actionsString6{ R"([
{ "command": { "action": "newTab", "index": 0 }, "keys": "ctrl+g" },
])" };
const std::string actionsString7{ R"([
{ "command": { "action": "renameWindow", "name": null }, "keys": "ctrl+h" }
])" };
const std::string actionsString8{ R"([
{
"name": "Change font size...",
"commands": [
{ "command": { "action": "adjustFontSize", "delta": 1 } },
{ "command": { "action": "adjustFontSize", "delta": -1 } },
{ "command": "resetFontSize" },
]
}
])" };
const std::string actionsString9A{ R"([
{
"name": "New tab",
"commands": [
{
"iterateOn": "profiles",
"icon": "${profile.icon}",
"name": "${profile.name}",
"command": { "action": "newTab", "profile": "${profile.name}" }
}
]
}
])" };
const std::string actionsString9B{ R"([
{
"commands":
[
{
"command":
{
"action": "sendInput",
"input": "${profile.name}"
},
"iterateOn": "profiles"
}
],
"name": "Send Input ..."
}
])" };
const std::string actionsString9C{ R""([
{
"commands":
[
{
"commands":
[
{
"command":
{
"action": "sendInput",
"input": "${profile.name} ${scheme.name}"
},
"iterateOn": "schemes"
}
],
"iterateOn": "profiles",
"name": "nest level (${profile.name})"
}
],
"name": "Send Input (Evil) ..."
}
])"" };
const std::string actionsString10{ R"([
{ "command": "unbound", "keys": "ctrl+c" }
])" };
Log::Comment(L"simple command");
RoundtripTest<implementation::ActionMap>(actionsString1);
Log::Comment(L"complex commands");
RoundtripTest<implementation::ActionMap>(actionsString2A);
RoundtripTest<implementation::ActionMap>(actionsString2B);
RoundtripTest<implementation::ActionMap>(actionsString2C);
Log::Comment(L"simple command with key chords");
RoundtripTest<implementation::ActionMap>(actionsString3);
Log::Comment(L"complex commands with key chords");
RoundtripTest<implementation::ActionMap>(actionsString4);
Log::Comment(L"command with name and icon and multiple key chords");
RoundtripTest<implementation::ActionMap>(actionsString5);
Log::Comment(L"complex command with new terminal args");
RoundtripTest<implementation::ActionMap>(actionsString6);
Log::Comment(L"complex command with meaningful null arg");
RoundtripTest<implementation::ActionMap>(actionsString7);
Log::Comment(L"nested command");
RoundtripTest<implementation::ActionMap>(actionsString8);
Log::Comment(L"iterable command");
RoundtripTest<implementation::ActionMap>(actionsString9A);
RoundtripTest<implementation::ActionMap>(actionsString9B);
RoundtripTest<implementation::ActionMap>(actionsString9C);
Log::Comment(L"unbound command");
RoundtripTest<implementation::ActionMap>(actionsString10);
}
void SerializationTests::CascadiaSettings()
{
const std::string settingsString{ R"({
@ -277,10 +426,9 @@ namespace SettingsModelLocalTests
}
],
"actions": [
{"command": { "action": "renameTab","input": "Liang Tab" },"keys": "ctrl+t" }
],
"keybindings": [
{ "command": { "action": "sendInput","input": "VT Griese Mode" },"keys": "ctrl+k" }
{ "command": { "action": "renameTab", "title": "Liang Tab" }, "keys": "ctrl+t" },
{ "command": { "action": "sendInput", "input": "VT Griese Mode" }, "keys": "ctrl+k" },
{ "command": { "action": "renameWindow", "name": "Hecker Window" }, "keys": "ctrl+l" }
]
})" };

View file

@ -1,4 +1,5 @@
#include "pch.h"
#include "AllShortcutActions.h"
#include "ActionArgs.h"
#include "ActionAndArgs.h"
#include "ActionAndArgs.g.cpp"
@ -29,10 +30,10 @@ static constexpr std::string_view RenameTabKey{ "renameTab" };
static constexpr std::string_view OpenTabRenamerKey{ "openTabRenamer" };
static constexpr std::string_view ResetFontSizeKey{ "resetFontSize" };
static constexpr std::string_view ResizePaneKey{ "resizePane" };
static constexpr std::string_view ScrolldownKey{ "scrollDown" };
static constexpr std::string_view ScrolldownpageKey{ "scrollDownPage" };
static constexpr std::string_view ScrollupKey{ "scrollUp" };
static constexpr std::string_view ScrolluppageKey{ "scrollUpPage" };
static constexpr std::string_view ScrollDownKey{ "scrollDown" };
static constexpr std::string_view ScrollDownPageKey{ "scrollDownPage" };
static constexpr std::string_view ScrollUpKey{ "scrollUp" };
static constexpr std::string_view ScrollUpPageKey{ "scrollUpPage" };
static constexpr std::string_view ScrollToTopKey{ "scrollToTop" };
static constexpr std::string_view ScrollToBottomKey{ "scrollToBottom" };
static constexpr std::string_view SendInputKey{ "sendInput" };
@ -65,6 +66,10 @@ static constexpr std::string_view ActionKey{ "action" };
// This key is reserved to remove a keybinding, instead of mapping it to an action.
static constexpr std::string_view UnboundKey{ "unbound" };
#define KEY_TO_ACTION_PAIR(action) { action##Key, ShortcutAction::action },
#define ACTION_TO_KEY_PAIR(action) { ShortcutAction::action, action##Key },
#define ACTION_TO_SERIALIZERS_PAIR(action) { ShortcutAction::action, { action##Args::FromJson, action##Args::ToJson } },
namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{
using namespace ::Microsoft::Terminal::Settings::Model;
@ -78,98 +83,38 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
// the map are all const for the lifetime of the app, we have nothing to worry
// about here.
const std::map<std::string_view, ShortcutAction, std::less<>> ActionAndArgs::ActionKeyNamesMap{
{ AdjustFontSizeKey, ShortcutAction::AdjustFontSize },
{ CloseOtherTabsKey, ShortcutAction::CloseOtherTabs },
{ ClosePaneKey, ShortcutAction::ClosePane },
{ CloseTabKey, ShortcutAction::CloseTab },
{ CloseTabsAfterKey, ShortcutAction::CloseTabsAfter },
{ CloseWindowKey, ShortcutAction::CloseWindow },
{ CopyTextKey, ShortcutAction::CopyText },
{ DuplicateTabKey, ShortcutAction::DuplicateTab },
{ ExecuteCommandlineKey, ShortcutAction::ExecuteCommandline },
{ FindKey, ShortcutAction::Find },
{ MoveFocusKey, ShortcutAction::MoveFocus },
{ NewTabKey, ShortcutAction::NewTab },
{ NextTabKey, ShortcutAction::NextTab },
{ OpenNewTabDropdownKey, ShortcutAction::OpenNewTabDropdown },
{ OpenSettingsKey, ShortcutAction::OpenSettings },
{ OpenTabColorPickerKey, ShortcutAction::OpenTabColorPicker },
{ PasteTextKey, ShortcutAction::PasteText },
{ PrevTabKey, ShortcutAction::PrevTab },
{ RenameTabKey, ShortcutAction::RenameTab },
{ OpenTabRenamerKey, ShortcutAction::OpenTabRenamer },
{ ResetFontSizeKey, ShortcutAction::ResetFontSize },
{ ResizePaneKey, ShortcutAction::ResizePane },
{ ScrolldownKey, ShortcutAction::ScrollDown },
{ ScrolldownpageKey, ShortcutAction::ScrollDownPage },
{ ScrollupKey, ShortcutAction::ScrollUp },
{ ScrolluppageKey, ShortcutAction::ScrollUpPage },
{ ScrollToTopKey, ShortcutAction::ScrollToTop },
{ ScrollToBottomKey, ShortcutAction::ScrollToBottom },
{ SendInputKey, ShortcutAction::SendInput },
{ SetColorSchemeKey, ShortcutAction::SetColorScheme },
{ SetTabColorKey, ShortcutAction::SetTabColor },
{ SplitPaneKey, ShortcutAction::SplitPane },
{ SwitchToTabKey, ShortcutAction::SwitchToTab },
{ TabSearchKey, ShortcutAction::TabSearch },
{ ToggleAlwaysOnTopKey, ShortcutAction::ToggleAlwaysOnTop },
{ ToggleCommandPaletteKey, ShortcutAction::ToggleCommandPalette },
{ ToggleFocusModeKey, ShortcutAction::ToggleFocusMode },
{ ToggleFullscreenKey, ShortcutAction::ToggleFullscreen },
{ TogglePaneZoomKey, ShortcutAction::TogglePaneZoom },
{ LegacyToggleRetroEffectKey, ShortcutAction::ToggleShaderEffects },
{ ToggleShaderEffectsKey, ShortcutAction::ToggleShaderEffects },
{ MoveTabKey, ShortcutAction::MoveTab },
{ BreakIntoDebuggerKey, ShortcutAction::BreakIntoDebugger },
{ UnboundKey, ShortcutAction::Invalid },
{ FindMatchKey, ShortcutAction::FindMatch },
{ TogglePaneReadOnlyKey, ShortcutAction::TogglePaneReadOnly },
{ NewWindowKey, ShortcutAction::NewWindow },
{ IdentifyWindowKey, ShortcutAction::IdentifyWindow },
{ IdentifyWindowsKey, ShortcutAction::IdentifyWindows },
{ RenameWindowKey, ShortcutAction::RenameWindow },
{ OpenWindowRenamerKey, ShortcutAction::OpenWindowRenamer },
{ GlobalSummonKey, ShortcutAction::GlobalSummon },
{ QuakeModeKey, ShortcutAction::QuakeMode },
#define ON_ALL_ACTIONS(action) KEY_TO_ACTION_PAIR(action)
ALL_SHORTCUT_ACTIONS
#undef ON_ALL_ACTIONS
};
static const std::map<ShortcutAction, std::string_view, std::less<>> ActionToStringMap{
#define ON_ALL_ACTIONS(action) ACTION_TO_KEY_PAIR(action)
ALL_SHORTCUT_ACTIONS
#undef ON_ALL_ACTIONS
};
using ParseResult = std::tuple<IActionArgs, std::vector<SettingsLoadWarnings>>;
using ParseActionFunction = std::function<ParseResult(const Json::Value&)>;
using SerializeActionFunction = std::function<Json::Value(IActionArgs)>;
// This is a map of ShortcutAction->function<IActionArgs(Json::Value)>. It holds
// a set of deserializer functions that can be used to deserialize a IActionArgs
// This is a map of ShortcutAction->{function<IActionArgs(Json::Value)>, function<Json::Value(IActionArgs)>. It holds
// a set of (de)serializer functions that can be used to (de)serialize an IActionArgs
// from json. Each type of IActionArgs that can accept arbitrary args should be
// placed into this map, with the corresponding deserializer function as the
// value.
static const std::map<ShortcutAction, ParseActionFunction, std::less<>> argParsers{
{ ShortcutAction::AdjustFontSize, AdjustFontSizeArgs::FromJson },
{ ShortcutAction::CloseOtherTabs, CloseOtherTabsArgs::FromJson },
{ ShortcutAction::CloseTabsAfter, CloseTabsAfterArgs::FromJson },
{ ShortcutAction::CopyText, CopyTextArgs::FromJson },
{ ShortcutAction::ExecuteCommandline, ExecuteCommandlineArgs::FromJson },
{ ShortcutAction::MoveFocus, MoveFocusArgs::FromJson },
{ ShortcutAction::NewTab, NewTabArgs::FromJson },
{ ShortcutAction::OpenSettings, OpenSettingsArgs::FromJson },
{ ShortcutAction::RenameTab, RenameTabArgs::FromJson },
{ ShortcutAction::ResizePane, ResizePaneArgs::FromJson },
{ ShortcutAction::SendInput, SendInputArgs::FromJson },
{ ShortcutAction::SetColorScheme, SetColorSchemeArgs::FromJson },
{ ShortcutAction::SetTabColor, SetTabColorArgs::FromJson },
{ ShortcutAction::SplitPane, SplitPaneArgs::FromJson },
{ ShortcutAction::SwitchToTab, SwitchToTabArgs::FromJson },
{ ShortcutAction::ScrollUp, ScrollUpArgs::FromJson },
{ ShortcutAction::ScrollDown, ScrollDownArgs::FromJson },
{ ShortcutAction::MoveTab, MoveTabArgs::FromJson },
{ ShortcutAction::ToggleCommandPalette, ToggleCommandPaletteArgs::FromJson },
{ ShortcutAction::FindMatch, FindMatchArgs::FromJson },
{ ShortcutAction::NewWindow, NewWindowArgs::FromJson },
{ ShortcutAction::PrevTab, PrevTabArgs::FromJson },
{ ShortcutAction::NextTab, NextTabArgs::FromJson },
{ ShortcutAction::RenameWindow, RenameWindowArgs::FromJson },
{ ShortcutAction::GlobalSummon, GlobalSummonArgs::FromJson },
{ ShortcutAction::QuakeMode, GlobalSummonArgs::QuakeModeFromJson },
static const std::unordered_map<ShortcutAction, std::pair<ParseActionFunction, SerializeActionFunction>> argSerializerMap{
{ ShortcutAction::Invalid, nullptr },
// These are special cases.
// - QuakeMode: deserializes into a GlobalSummon, so we don't need a serializer
// - Invalid: has no args
{ ShortcutAction::QuakeMode, { GlobalSummonArgs::QuakeModeFromJson, nullptr } },
{ ShortcutAction::Invalid, { nullptr, nullptr } },
#define ON_ALL_ACTIONS_WITH_ARGS(action) ACTION_TO_SERIALIZERS_PAIR(action)
ALL_SHORTCUT_ACTIONS_WITH_ARGS
#undef ON_ALL_ACTIONS_WITH_ARGS
};
// Function Description:
@ -248,10 +193,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
// the binding.
IActionArgs args{ nullptr };
std::vector<Microsoft::Terminal::Settings::Model::SettingsLoadWarnings> parseWarnings;
const auto deserializersIter = argParsers.find(action);
if (deserializersIter != argParsers.end())
const auto deserializersIter = argSerializerMap.find(action);
if (deserializersIter != argSerializerMap.end())
{
auto pfn = deserializersIter->second;
auto pfn = deserializersIter->second.first;
if (pfn)
{
std::tie(args, parseWarnings) = pfn(argsVal);
@ -271,6 +216,53 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
return make_self<ActionAndArgs>(action, args);
}
Json::Value ActionAndArgs::ToJson(const Model::ActionAndArgs& val)
{
if (val)
{
// Search for the ShortcutAction
const auto shortcutActionIter{ ActionToStringMap.find(val.Action()) };
if (shortcutActionIter == ActionToStringMap.end())
{
// Couldn't find the ShortcutAction,
// return... "command": "unbound"
return static_cast<std::string>(UnboundKey);
}
if (!val.Args())
{
// No args to serialize,
// output something like... "command": "copy"
return static_cast<std::string>(shortcutActionIter->second);
}
else
{
// Serialize any set args,
// output something like... "command": { "action": "copy", "singleLine": false }
Json::Value result{ Json::ValueType::objectValue };
// Set the action args, if any
const auto actionArgSerializerIter{ argSerializerMap.find(val.Action()) };
if (actionArgSerializerIter != argSerializerMap.end())
{
auto pfn{ actionArgSerializerIter->second.second };
if (pfn)
{
result = pfn(val.Args());
}
}
// Set the "action" part
result[static_cast<std::string>(ActionKey)] = static_cast<std::string>(shortcutActionIter->second);
return result;
}
}
// "command": "unbound"
return static_cast<std::string>(UnboundKey);
}
com_ptr<ActionAndArgs> ActionAndArgs::Copy() const
{
auto copy{ winrt::make_self<ActionAndArgs>() };

View file

@ -15,6 +15,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
static const std::map<std::string_view, ShortcutAction, std::less<>> ActionKeyNamesMap;
static winrt::com_ptr<ActionAndArgs> FromJson(const Json::Value& json,
std::vector<SettingsLoadWarnings>& warnings);
static Json::Value ToJson(const Model::ActionAndArgs& val);
ActionAndArgs() = default;
ActionAndArgs(ShortcutAction action, IActionArgs args) :

View file

@ -41,43 +41,43 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{
std::wstringstream ss;
if (!_Profile.empty())
if (!Profile().empty())
{
ss << fmt::format(L"profile: {}, ", _Profile);
ss << fmt::format(L"profile: {}, ", Profile());
}
else if (_ProfileIndex)
else if (ProfileIndex())
{
ss << fmt::format(L"profile index: {}, ", _ProfileIndex.Value());
ss << fmt::format(L"profile index: {}, ", ProfileIndex().Value());
}
if (!_Commandline.empty())
if (!Commandline().empty())
{
ss << fmt::format(L"commandline: {}, ", _Commandline);
ss << fmt::format(L"commandline: {}, ", Commandline());
}
if (!_StartingDirectory.empty())
if (!StartingDirectory().empty())
{
ss << fmt::format(L"directory: {}, ", _StartingDirectory);
ss << fmt::format(L"directory: {}, ", StartingDirectory());
}
if (!_TabTitle.empty())
if (!TabTitle().empty())
{
ss << fmt::format(L"title: {}, ", _TabTitle);
ss << fmt::format(L"title: {}, ", TabTitle());
}
if (_TabColor)
if (TabColor())
{
const til::color tabColor{ _TabColor.Value() };
const til::color tabColor{ TabColor().Value() };
ss << fmt::format(L"tabColor: {}, ", tabColor.ToHexString(true));
}
if (!_ColorScheme.empty())
if (!ColorScheme().empty())
{
ss << fmt::format(L"colorScheme: {}, ", _ColorScheme);
ss << fmt::format(L"colorScheme: {}, ", ColorScheme());
}
if (_SuppressApplicationTitle)
if (SuppressApplicationTitle())
{
if (_SuppressApplicationTitle.Value())
if (SuppressApplicationTitle().Value())
{
ss << fmt::format(L"suppress application title, ");
}
@ -101,37 +101,37 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{
std::wstringstream ss;
if (!_Profile.empty())
if (!Profile().empty())
{
ss << fmt::format(L"--profile \"{}\" ", _Profile);
ss << fmt::format(L"--profile \"{}\" ", Profile());
}
// The caller is always expected to provide the evaluated profile in the
// NewTerminalArgs, not the index
//
// else if (_ProfileIndex)
// else if (ProfileIndex())
// {
// ss << fmt::format(L"profile index: {}, ", _ProfileIndex.Value());
// ss << fmt::format(L"profile index: {}, ", ProfileIndex().Value());
// }
if (!_StartingDirectory.empty())
if (!StartingDirectory().empty())
{
ss << fmt::format(L"--startingDirectory \"{}\" ", _StartingDirectory);
ss << fmt::format(L"--startingDirectory \"{}\" ", StartingDirectory());
}
if (!_TabTitle.empty())
if (!TabTitle().empty())
{
ss << fmt::format(L"--title \"{}\" ", _TabTitle);
ss << fmt::format(L"--title \"{}\" ", TabTitle());
}
if (_TabColor)
if (TabColor())
{
const til::color tabColor{ _TabColor.Value() };
const til::color tabColor{ TabColor().Value() };
ss << fmt::format(L"--tabColor \"{}\" ", tabColor.ToHexString(true));
}
if (_SuppressApplicationTitle)
if (SuppressApplicationTitle())
{
if (_SuppressApplicationTitle.Value())
if (SuppressApplicationTitle().Value())
{
ss << fmt::format(L"--suppressApplicationTitle ");
}
@ -141,14 +141,14 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
}
if (!_ColorScheme.empty())
if (!ColorScheme().empty())
{
ss << fmt::format(L"--colorScheme \"{}\" ", _ColorScheme);
ss << fmt::format(L"--colorScheme \"{}\" ", ColorScheme());
}
if (!_Commandline.empty())
if (!Commandline().empty())
{
ss << fmt::format(L"-- \"{}\" ", _Commandline);
ss << fmt::format(L"-- \"{}\" ", Commandline());
}
auto s = ss.str();
@ -165,7 +165,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{
std::wstringstream ss;
if (_SingleLine)
if (SingleLine())
{
ss << RS_(L"CopyTextAsSingleLineCommandKey").c_str();
}
@ -174,25 +174,25 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
ss << RS_(L"CopyTextCommandKey").c_str();
}
if (_CopyFormatting != nullptr)
if (CopyFormatting())
{
ss << L", copyFormatting: ";
if (_CopyFormatting.Value() == CopyFormat::All)
if (CopyFormatting().Value() == CopyFormat::All)
{
ss << L"all, ";
}
else if (_CopyFormatting.Value() == static_cast<CopyFormat>(0))
else if (CopyFormatting().Value() == static_cast<CopyFormat>(0))
{
ss << L"none, ";
}
else
{
if (WI_IsFlagSet(_CopyFormatting.Value(), CopyFormat::HTML))
if (WI_IsFlagSet(CopyFormatting().Value(), CopyFormat::HTML))
{
ss << L"html, ";
}
if (WI_IsFlagSet(_CopyFormatting.Value(), CopyFormat::RTF))
if (WI_IsFlagSet(CopyFormatting().Value(), CopyFormat::RTF))
{
ss << L"rtf, ";
}
@ -209,9 +209,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
winrt::hstring NewTabArgs::GenerateName() const
{
winrt::hstring newTerminalArgsStr;
if (_TerminalArgs)
if (TerminalArgs())
{
newTerminalArgsStr = _TerminalArgs.GenerateName();
newTerminalArgsStr = TerminalArgs().GenerateName();
}
if (newTerminalArgsStr.empty())
@ -226,14 +226,14 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
winrt::hstring SwitchToTabArgs::GenerateName() const
{
return winrt::hstring{
fmt::format(L"{}, index:{}", RS_(L"SwitchToTabCommandKey"), _TabIndex)
fmt::format(L"{}, index:{}", RS_(L"SwitchToTabCommandKey"), TabIndex())
};
}
winrt::hstring ResizePaneArgs::GenerateName() const
{
winrt::hstring directionString;
switch (_ResizeDirection)
switch (ResizeDirection())
{
case ResizeDirection::Left:
directionString = RS_(L"DirectionLeft");
@ -257,7 +257,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
winrt::hstring MoveFocusArgs::GenerateName() const
{
winrt::hstring directionString;
switch (_FocusDirection)
switch (FocusDirection())
{
case FocusDirection::Left:
directionString = RS_(L"DirectionLeft");
@ -286,21 +286,21 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
// size" (or "Decrease font size"). If the amount delta has a greater
// absolute value, we'll include it like"
// * Decrease font size, amount: {delta}"
if (_Delta < 0)
if (Delta() < 0)
{
return _Delta == -1 ? RS_(L"DecreaseFontSizeCommandKey") :
winrt::hstring{
fmt::format(std::wstring_view(RS_(L"DecreaseFontSizeWithAmountCommandKey")),
-_Delta)
};
return Delta() == -1 ? RS_(L"DecreaseFontSizeCommandKey") :
winrt::hstring{
fmt::format(std::wstring_view(RS_(L"DecreaseFontSizeWithAmountCommandKey")),
-Delta())
};
}
else
{
return _Delta == 1 ? RS_(L"IncreaseFontSizeCommandKey") :
winrt::hstring{
fmt::format(std::wstring_view(RS_(L"IncreaseFontSizeWithAmountCommandKey")),
_Delta)
};
return Delta() == 1 ? RS_(L"IncreaseFontSizeCommandKey") :
winrt::hstring{
fmt::format(std::wstring_view(RS_(L"IncreaseFontSizeWithAmountCommandKey")),
Delta())
};
}
}
@ -309,7 +309,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
// The string will be similar to the following:
// * "Send Input: ...input..."
auto escapedInput = til::visualize_control_codes(_Input);
auto escapedInput = til::visualize_control_codes(Input());
auto name = fmt::format(std::wstring_view(RS_(L"SendInputCommandKey")), escapedInput);
return winrt::hstring{ name };
}
@ -326,7 +326,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
// will be omitted (as they're unused)
std::wstringstream ss;
if (_SplitMode == SplitType::Duplicate)
if (SplitMode() == SplitType::Duplicate)
{
ss << std::wstring_view(RS_(L"DuplicatePaneCommandKey"));
}
@ -338,7 +338,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
// This text is intentionally _not_ localized, to attempt to mirror the
// exact syntax that the property would have in JSON.
switch (_SplitStyle)
switch (SplitStyle())
{
case SplitState::Vertical:
ss << L"split: vertical, ";
@ -348,18 +348,18 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
break;
}
if (_SplitSize != .5f)
if (SplitSize() != .5f)
{
ss << L"size: " << (_SplitSize * 100) << L"%, ";
ss << L"size: " << (SplitSize() * 100) << L"%, ";
}
winrt::hstring newTerminalArgsStr;
if (_TerminalArgs)
if (TerminalArgs())
{
newTerminalArgsStr = _TerminalArgs.GenerateName();
newTerminalArgsStr = TerminalArgs().GenerateName();
}
if (_SplitMode != SplitType::Duplicate && !newTerminalArgsStr.empty())
if (SplitMode() != SplitType::Duplicate && !newTerminalArgsStr.empty())
{
ss << newTerminalArgsStr.c_str();
ss << L", ";
@ -372,7 +372,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
winrt::hstring OpenSettingsArgs::GenerateName() const
{
switch (_Target)
switch (Target())
{
case SettingsTarget::DefaultsFile:
return RS_(L"OpenDefaultSettingsCommandKey");
@ -389,11 +389,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
winrt::hstring SetColorSchemeArgs::GenerateName() const
{
// "Set color scheme to "{_SchemeName}""
if (!_SchemeName.empty())
if (!SchemeName().empty())
{
return winrt::hstring{
fmt::format(std::wstring_view(RS_(L"SetColorSchemeCommandKey")),
_SchemeName.c_str())
SchemeName().c_str())
};
}
return L"";
@ -403,9 +403,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{
// "Set tab color to #RRGGBB"
// "Reset tab color"
if (_TabColor)
if (TabColor())
{
til::color tabColor{ _TabColor.Value() };
til::color tabColor{ TabColor().Value() };
return winrt::hstring{
fmt::format(std::wstring_view(RS_(L"SetTabColorCommandKey")),
tabColor.ToHexString(true))
@ -419,11 +419,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{
// "Rename tab to \"{_Title}\""
// "Reset tab title"
if (!_Title.empty())
if (!Title().empty())
{
return winrt::hstring{
fmt::format(std::wstring_view(RS_(L"RenameTabCommandKey")),
_Title.c_str())
Title().c_str())
};
}
return RS_(L"ResetTabNameCommandKey");
@ -432,11 +432,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
winrt::hstring ExecuteCommandlineArgs::GenerateName() const
{
// "Run commandline "{_Commandline}" in this window"
if (!_Commandline.empty())
if (!Commandline().empty())
{
return winrt::hstring{
fmt::format(std::wstring_view(RS_(L"ExecuteCommandlineCommandKey")),
_Commandline.c_str())
Commandline().c_str())
};
}
return L"";
@ -444,12 +444,12 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
winrt::hstring CloseOtherTabsArgs::GenerateName() const
{
if (_Index)
if (Index())
{
// "Close tabs other than index {0}"
return winrt::hstring{
fmt::format(std::wstring_view(RS_(L"CloseOtherTabsCommandKey")),
_Index.Value())
Index().Value())
};
}
return RS_(L"CloseOtherTabsDefaultCommandKey");
@ -457,12 +457,12 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
winrt::hstring CloseTabsAfterArgs::GenerateName() const
{
if (_Index)
if (Index())
{
// "Close tabs after index {0}"
return winrt::hstring{
fmt::format(std::wstring_view(RS_(L"CloseTabsAfterCommandKey")),
_Index.Value())
Index().Value())
};
}
return RS_(L"CloseTabsAfterDefaultCommandKey");
@ -470,11 +470,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
winrt::hstring ScrollUpArgs::GenerateName() const
{
if (_RowsToScroll)
if (RowsToScroll())
{
return winrt::hstring{
fmt::format(std::wstring_view(RS_(L"ScrollUpSeveralRowsCommandKey")),
_RowsToScroll.Value())
RowsToScroll().Value())
};
}
return RS_(L"ScrollUpCommandKey");
@ -482,11 +482,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
winrt::hstring ScrollDownArgs::GenerateName() const
{
if (_RowsToScroll)
if (RowsToScroll())
{
return winrt::hstring{
fmt::format(std::wstring_view(RS_(L"ScrollDownSeveralRowsCommandKey")),
_RowsToScroll.Value())
RowsToScroll().Value())
};
}
return RS_(L"ScrollDownCommandKey");
@ -495,7 +495,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
winrt::hstring MoveTabArgs::GenerateName() const
{
winrt::hstring directionString;
switch (_Direction)
switch (Direction())
{
case MoveTabDirection::Forward:
directionString = RS_(L"MoveTabDirectionForward");
@ -512,7 +512,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
winrt::hstring ToggleCommandPaletteArgs::GenerateName() const
{
if (_LaunchMode == CommandPaletteLaunchMode::CommandLine)
if (LaunchMode() == CommandPaletteLaunchMode::CommandLine)
{
return RS_(L"ToggleCommandPaletteCommandLineModeCommandKey");
}
@ -521,7 +521,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
winrt::hstring FindMatchArgs::GenerateName() const
{
switch (_Direction)
switch (Direction())
{
case FindMatchDirection::Next:
return winrt::hstring{ RS_(L"FindNextCommandKey") };
@ -534,9 +534,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
winrt::hstring NewWindowArgs::GenerateName() const
{
winrt::hstring newTerminalArgsStr;
if (_TerminalArgs)
if (TerminalArgs())
{
newTerminalArgsStr = _TerminalArgs.GenerateName();
newTerminalArgsStr = TerminalArgs().GenerateName();
}
if (newTerminalArgsStr.empty())
@ -550,23 +550,23 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
winrt::hstring PrevTabArgs::GenerateName() const
{
if (!_SwitcherMode)
if (!SwitcherMode())
{
return RS_(L"PrevTabCommandKey");
}
const auto mode = _SwitcherMode.Value() == TabSwitcherMode::MostRecentlyUsed ? L"most recently used" : L"in order";
const auto mode = SwitcherMode().Value() == TabSwitcherMode::MostRecentlyUsed ? L"most recently used" : L"in order";
return winrt::hstring(fmt::format(L"{}, {}", RS_(L"PrevTabCommandKey"), mode));
}
winrt::hstring NextTabArgs::GenerateName() const
{
if (!_SwitcherMode)
if (!SwitcherMode())
{
return RS_(L"NextTabCommandKey");
}
const auto mode = _SwitcherMode.Value() == TabSwitcherMode::MostRecentlyUsed ? L"most recently used" : L"in order";
const auto mode = SwitcherMode().Value() == TabSwitcherMode::MostRecentlyUsed ? L"most recently used" : L"in order";
return winrt::hstring(fmt::format(L"{}, {}", RS_(L"NextTabCommandKey"), mode));
}
@ -574,11 +574,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{
// "Rename window to \"{_Name}\""
// "Clear window name"
if (!_Name.empty())
if (!Name().empty())
{
return winrt::hstring{
fmt::format(std::wstring_view(RS_(L"RenameWindowCommandKey")),
_Name.c_str())
Name().c_str())
};
}
return RS_(L"ResetWindowNameCommandKey");
@ -591,10 +591,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
// "Summon the Terminal window"
// "Summon the Terminal window, name:\"{_Name}\""
if (!_Name.empty())
if (!Name().empty())
{
ss << L", name: ";
ss << std::wstring_view(_Name);
ss << std::wstring_view(Name());
}
return winrt::hstring{ ss.str() };
}

View file

@ -41,6 +41,14 @@
#include "TerminalSettingsSerializationHelpers.h"
#define ACTION_ARG(type, name, ...) \
public: \
type name() const noexcept { return _##name.has_value() ? _##name.value() : type{ __VA_ARGS__ }; } \
void name(const type& value) noexcept { _##name = value; } \
\
private: \
std::optional<type> _##name{ std::nullopt };
// Notes on defining ActionArgs and ActionEventArgs:
// * All properties specific to an action should be defined as an ActionArgs
// class that implements IActionArgs
@ -79,14 +87,14 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
NewTerminalArgs() = default;
NewTerminalArgs(int32_t& profileIndex) :
_ProfileIndex{ profileIndex } {};
WINRT_PROPERTY(winrt::hstring, Commandline, L"");
WINRT_PROPERTY(winrt::hstring, StartingDirectory, L"");
WINRT_PROPERTY(winrt::hstring, TabTitle, L"");
WINRT_PROPERTY(Windows::Foundation::IReference<Windows::UI::Color>, TabColor, nullptr);
WINRT_PROPERTY(Windows::Foundation::IReference<int32_t>, ProfileIndex, nullptr);
WINRT_PROPERTY(winrt::hstring, Profile, L"");
WINRT_PROPERTY(Windows::Foundation::IReference<bool>, SuppressApplicationTitle, nullptr);
WINRT_PROPERTY(winrt::hstring, ColorScheme);
ACTION_ARG(winrt::hstring, Commandline, L"");
ACTION_ARG(winrt::hstring, StartingDirectory, L"");
ACTION_ARG(winrt::hstring, TabTitle, L"");
ACTION_ARG(Windows::Foundation::IReference<Windows::UI::Color>, TabColor, nullptr);
ACTION_ARG(Windows::Foundation::IReference<int32_t>, ProfileIndex, nullptr);
ACTION_ARG(winrt::hstring, Profile, L"");
ACTION_ARG(Windows::Foundation::IReference<bool>, SuppressApplicationTitle, nullptr);
ACTION_ARG(winrt::hstring, ColorScheme);
static constexpr std::string_view CommandlineKey{ "commandline" };
static constexpr std::string_view StartingDirectoryKey{ "startingDirectory" };
@ -126,6 +134,24 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
JsonUtils::GetValueForKey(json, ColorSchemeKey, args->_ColorScheme);
return *args;
}
static Json::Value ToJson(const Model::NewTerminalArgs& val)
{
if (!val)
{
return {};
}
Json::Value json{ Json::ValueType::objectValue };
const auto args{ get_self<NewTerminalArgs>(val) };
JsonUtils::SetValueForKey(json, CommandlineKey, args->_Commandline);
JsonUtils::SetValueForKey(json, StartingDirectoryKey, args->_StartingDirectory);
JsonUtils::SetValueForKey(json, TabTitleKey, args->_TabTitle);
JsonUtils::SetValueForKey(json, ProfileIndexKey, args->_ProfileIndex);
JsonUtils::SetValueForKey(json, ProfileKey, args->_Profile);
JsonUtils::SetValueForKey(json, TabColorKey, args->_TabColor);
JsonUtils::SetValueForKey(json, SuppressApplicationTitleKey, args->_SuppressApplicationTitle);
JsonUtils::SetValueForKey(json, ColorSchemeKey, args->_ColorScheme);
return json;
}
Model::NewTerminalArgs Copy() const
{
auto copy{ winrt::make_self<NewTerminalArgs>() };
@ -141,15 +167,15 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
size_t Hash() const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_Commandline, _StartingDirectory, _TabTitle, _TabColor, _ProfileIndex, _Profile, _SuppressApplicationTitle, _ColorScheme);
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Commandline(), StartingDirectory(), TabTitle(), TabColor(), ProfileIndex(), Profile(), SuppressApplicationTitle(), ColorScheme());
}
};
struct CopyTextArgs : public CopyTextArgsT<CopyTextArgs>
{
CopyTextArgs() = default;
WINRT_PROPERTY(bool, SingleLine, false);
WINRT_PROPERTY(Windows::Foundation::IReference<Control::CopyFormat>, CopyFormatting, nullptr);
ACTION_ARG(bool, SingleLine, false);
ACTION_ARG(Windows::Foundation::IReference<Control::CopyFormat>, CopyFormatting, nullptr);
static constexpr std::string_view SingleLineKey{ "singleLine" };
static constexpr std::string_view CopyFormattingKey{ "copyFormatting" };
@ -175,6 +201,18 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
JsonUtils::GetValueForKey(json, CopyFormattingKey, args->_CopyFormatting);
return { *args, {} };
}
static Json::Value ToJson(const IActionArgs& val)
{
if (!val)
{
return {};
}
Json::Value json{ Json::ValueType::objectValue };
const auto args{ get_self<CopyTextArgs>(val) };
JsonUtils::SetValueForKey(json, SingleLineKey, args->_SingleLine);
JsonUtils::SetValueForKey(json, CopyFormattingKey, args->_CopyFormatting);
return json;
}
IActionArgs Copy() const
{
@ -185,7 +223,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
size_t Hash() const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_SingleLine, _CopyFormatting);
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(SingleLine(), CopyFormatting());
}
};
@ -215,6 +253,15 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
args->_TerminalArgs = NewTerminalArgs::FromJson(json);
return { *args, {} };
}
static Json::Value ToJson(const IActionArgs& val)
{
if (!val)
{
return {};
}
const auto args{ get_self<NewTabArgs>(val) };
return NewTerminalArgs::ToJson(args->_TerminalArgs);
}
IActionArgs Copy() const
{
auto copy{ winrt::make_self<NewTabArgs>() };
@ -223,7 +270,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
size_t Hash() const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_TerminalArgs);
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(TerminalArgs());
}
};
@ -232,7 +279,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
SwitchToTabArgs() = default;
SwitchToTabArgs(uint32_t& tabIndex) :
_TabIndex{ tabIndex } {};
WINRT_PROPERTY(uint32_t, TabIndex, 0);
ACTION_ARG(uint32_t, TabIndex, 0);
static constexpr std::string_view TabIndexKey{ "index" };
@ -255,6 +302,17 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
JsonUtils::GetValueForKey(json, TabIndexKey, args->_TabIndex);
return { *args, {} };
}
static Json::Value ToJson(const IActionArgs& val)
{
if (!val)
{
return {};
}
Json::Value json{ Json::ValueType::objectValue };
const auto args{ get_self<SwitchToTabArgs>(val) };
JsonUtils::SetValueForKey(json, TabIndexKey, args->_TabIndex);
return json;
}
IActionArgs Copy() const
{
auto copy{ winrt::make_self<SwitchToTabArgs>() };
@ -263,14 +321,14 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
size_t Hash() const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_TabIndex);
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(TabIndex());
}
};
struct ResizePaneArgs : public ResizePaneArgsT<ResizePaneArgs>
{
ResizePaneArgs() = default;
WINRT_PROPERTY(Model::ResizeDirection, ResizeDirection, ResizeDirection::None);
ACTION_ARG(Model::ResizeDirection, ResizeDirection, ResizeDirection::None);
static constexpr std::string_view DirectionKey{ "direction" };
@ -291,7 +349,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
// LOAD BEARING: Not using make_self here _will_ break you in the future!
auto args = winrt::make_self<ResizePaneArgs>();
JsonUtils::GetValueForKey(json, DirectionKey, args->_ResizeDirection);
if (args->_ResizeDirection == ResizeDirection::None)
if (args->ResizeDirection() == ResizeDirection::None)
{
return { nullptr, { SettingsLoadWarnings::MissingRequiredParameter } };
}
@ -300,6 +358,17 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
return { *args, {} };
}
}
static Json::Value ToJson(const IActionArgs& val)
{
if (!val)
{
return {};
}
Json::Value json{ Json::ValueType::objectValue };
const auto args{ get_self<ResizePaneArgs>(val) };
JsonUtils::SetValueForKey(json, DirectionKey, args->_ResizeDirection);
return json;
}
IActionArgs Copy() const
{
auto copy{ winrt::make_self<ResizePaneArgs>() };
@ -308,7 +377,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
size_t Hash() const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_ResizeDirection);
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(ResizeDirection());
}
};
@ -318,7 +387,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
MoveFocusArgs(Model::FocusDirection direction) :
_FocusDirection{ direction } {};
WINRT_PROPERTY(Model::FocusDirection, FocusDirection, FocusDirection::None);
ACTION_ARG(Model::FocusDirection, FocusDirection, FocusDirection::None);
static constexpr std::string_view DirectionKey{ "direction" };
@ -339,7 +408,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
// LOAD BEARING: Not using make_self here _will_ break you in the future!
auto args = winrt::make_self<MoveFocusArgs>();
JsonUtils::GetValueForKey(json, DirectionKey, args->_FocusDirection);
if (args->_FocusDirection == FocusDirection::None)
if (args->FocusDirection() == FocusDirection::None)
{
return { nullptr, { SettingsLoadWarnings::MissingRequiredParameter } };
}
@ -348,6 +417,17 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
return { *args, {} };
}
}
static Json::Value ToJson(const IActionArgs& val)
{
if (!val)
{
return {};
}
Json::Value json{ Json::ValueType::objectValue };
const auto args{ get_self<MoveFocusArgs>(val) };
JsonUtils::SetValueForKey(json, DirectionKey, args->_FocusDirection);
return json;
}
IActionArgs Copy() const
{
auto copy{ winrt::make_self<MoveFocusArgs>() };
@ -356,14 +436,14 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
size_t Hash() const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_FocusDirection);
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(FocusDirection());
}
};
struct AdjustFontSizeArgs : public AdjustFontSizeArgsT<AdjustFontSizeArgs>
{
AdjustFontSizeArgs() = default;
WINRT_PROPERTY(int32_t, Delta, 0);
ACTION_ARG(int32_t, Delta, 0);
static constexpr std::string_view AdjustFontSizeDelta{ "delta" };
@ -386,6 +466,17 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
JsonUtils::GetValueForKey(json, AdjustFontSizeDelta, args->_Delta);
return { *args, {} };
}
static Json::Value ToJson(const IActionArgs& val)
{
if (!val)
{
return {};
}
Json::Value json{ Json::ValueType::objectValue };
const auto args{ get_self<AdjustFontSizeArgs>(val) };
JsonUtils::SetValueForKey(json, AdjustFontSizeDelta, args->_Delta);
return json;
}
IActionArgs Copy() const
{
auto copy{ winrt::make_self<AdjustFontSizeArgs>() };
@ -394,14 +485,14 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
size_t Hash() const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_Delta);
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Delta());
}
};
struct SendInputArgs : public SendInputArgsT<SendInputArgs>
{
SendInputArgs() = default;
WINRT_PROPERTY(winrt::hstring, Input, L"");
ACTION_ARG(winrt::hstring, Input, L"");
static constexpr std::string_view InputKey{ "input" };
@ -421,12 +512,23 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
// LOAD BEARING: Not using make_self here _will_ break you in the future!
auto args = winrt::make_self<SendInputArgs>();
JsonUtils::GetValueForKey(json, InputKey, args->_Input);
if (args->_Input.empty())
if (args->Input().empty())
{
return { nullptr, { SettingsLoadWarnings::MissingRequiredParameter } };
}
return { *args, {} };
}
static Json::Value ToJson(const IActionArgs& val)
{
if (!val)
{
return {};
}
Json::Value json{ Json::ValueType::objectValue };
const auto args{ get_self<SendInputArgs>(val) };
JsonUtils::SetValueForKey(json, InputKey, args->_Input);
return json;
}
IActionArgs Copy() const
{
auto copy{ winrt::make_self<SendInputArgs>() };
@ -435,7 +537,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
size_t Hash() const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_Input);
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Input());
}
};
@ -456,10 +558,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
_TerminalArgs{ terminalArgs } {};
SplitPaneArgs(SplitType splitMode) :
_SplitMode{ splitMode } {};
WINRT_PROPERTY(SplitState, SplitStyle, SplitState::Automatic);
ACTION_ARG(SplitState, SplitStyle, SplitState::Automatic);
WINRT_PROPERTY(Model::NewTerminalArgs, TerminalArgs, nullptr);
WINRT_PROPERTY(SplitType, SplitMode, SplitType::Manual);
WINRT_PROPERTY(double, SplitSize, .5);
ACTION_ARG(SplitType, SplitMode, SplitType::Manual);
ACTION_ARG(double, SplitSize, .5);
static constexpr std::string_view SplitKey{ "split" };
static constexpr std::string_view SplitModeKey{ "splitMode" };
@ -489,12 +591,25 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
JsonUtils::GetValueForKey(json, SplitKey, args->_SplitStyle);
JsonUtils::GetValueForKey(json, SplitModeKey, args->_SplitMode);
JsonUtils::GetValueForKey(json, SplitSizeKey, args->_SplitSize);
if (args->_SplitSize >= 1 || args->_SplitSize <= 0)
if (args->SplitSize() >= 1 || args->SplitSize() <= 0)
{
return { nullptr, { SettingsLoadWarnings::InvalidSplitSize } };
}
return { *args, {} };
}
static Json::Value ToJson(const IActionArgs& val)
{
if (!val)
{
return {};
}
const auto args{ get_self<SplitPaneArgs>(val) };
auto json{ NewTerminalArgs::ToJson(args->_TerminalArgs) };
JsonUtils::SetValueForKey(json, SplitKey, args->_SplitStyle);
JsonUtils::SetValueForKey(json, SplitModeKey, args->_SplitMode);
JsonUtils::SetValueForKey(json, SplitSizeKey, args->_SplitSize);
return json;
}
IActionArgs Copy() const
{
auto copy{ winrt::make_self<SplitPaneArgs>() };
@ -506,7 +621,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
size_t Hash() const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_SplitStyle, _TerminalArgs, _SplitMode, _SplitSize);
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(SplitStyle(), TerminalArgs(), SplitMode(), SplitSize());
}
};
@ -515,7 +630,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
OpenSettingsArgs() = default;
OpenSettingsArgs(const SettingsTarget& target) :
_Target{ target } {}
WINRT_PROPERTY(SettingsTarget, Target, SettingsTarget::SettingsFile);
ACTION_ARG(SettingsTarget, Target, SettingsTarget::SettingsFile);
static constexpr std::string_view TargetKey{ "target" };
@ -538,6 +653,17 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
JsonUtils::GetValueForKey(json, TargetKey, args->_Target);
return { *args, {} };
}
static Json::Value ToJson(const IActionArgs& val)
{
if (!val)
{
return {};
}
Json::Value json{ Json::ValueType::objectValue };
const auto args{ get_self<OpenSettingsArgs>(val) };
JsonUtils::SetValueForKey(json, TargetKey, args->_Target);
return json;
}
IActionArgs Copy() const
{
auto copy{ winrt::make_self<OpenSettingsArgs>() };
@ -546,7 +672,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
size_t Hash() const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_Target);
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Target());
}
};
@ -555,7 +681,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
SetColorSchemeArgs() = default;
SetColorSchemeArgs(winrt::hstring name) :
_SchemeName{ name } {};
WINRT_PROPERTY(winrt::hstring, SchemeName, L"");
ACTION_ARG(winrt::hstring, SchemeName, L"");
static constexpr std::string_view NameKey{ "colorScheme" };
@ -576,12 +702,23 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
// LOAD BEARING: Not using make_self here _will_ break you in the future!
auto args = winrt::make_self<SetColorSchemeArgs>();
JsonUtils::GetValueForKey(json, NameKey, args->_SchemeName);
if (args->_SchemeName.empty())
if (args->SchemeName().empty())
{
return { nullptr, { SettingsLoadWarnings::MissingRequiredParameter } };
}
return { *args, {} };
}
static Json::Value ToJson(const IActionArgs& val)
{
if (!val)
{
return {};
}
Json::Value json{ Json::ValueType::objectValue };
const auto args{ get_self<SetColorSchemeArgs>(val) };
JsonUtils::SetValueForKey(json, NameKey, args->_SchemeName);
return json;
}
IActionArgs Copy() const
{
auto copy{ winrt::make_self<SetColorSchemeArgs>() };
@ -590,14 +727,14 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
size_t Hash() const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_SchemeName);
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(SchemeName());
}
};
struct SetTabColorArgs : public SetTabColorArgsT<SetTabColorArgs>
{
SetTabColorArgs() = default;
WINRT_PROPERTY(Windows::Foundation::IReference<Windows::UI::Color>, TabColor, nullptr);
ACTION_ARG(Windows::Foundation::IReference<Windows::UI::Color>, TabColor, nullptr);
static constexpr std::string_view ColorKey{ "color" };
@ -620,6 +757,17 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
JsonUtils::GetValueForKey(json, ColorKey, args->_TabColor);
return { *args, {} };
}
static Json::Value ToJson(const IActionArgs& val)
{
if (!val)
{
return {};
}
Json::Value json{ Json::ValueType::objectValue };
const auto args{ get_self<SetTabColorArgs>(val) };
JsonUtils::SetValueForKey(json, ColorKey, args->_TabColor);
return json;
}
IActionArgs Copy() const
{
auto copy{ winrt::make_self<SetTabColorArgs>() };
@ -628,14 +776,14 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
size_t Hash() const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_TabColor);
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(TabColor());
}
};
struct RenameTabArgs : public RenameTabArgsT<RenameTabArgs>
{
RenameTabArgs() = default;
WINRT_PROPERTY(winrt::hstring, Title, L"");
ACTION_ARG(winrt::hstring, Title, L"");
static constexpr std::string_view TitleKey{ "title" };
@ -658,6 +806,17 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
JsonUtils::GetValueForKey(json, TitleKey, args->_Title);
return { *args, {} };
}
static Json::Value ToJson(const IActionArgs& val)
{
if (!val)
{
return {};
}
Json::Value json{ Json::ValueType::objectValue };
const auto args{ get_self<RenameTabArgs>(val) };
JsonUtils::SetValueForKey(json, TitleKey, args->_Title);
return json;
}
IActionArgs Copy() const
{
auto copy{ winrt::make_self<RenameTabArgs>() };
@ -666,7 +825,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
size_t Hash() const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_Title);
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Title());
}
};
@ -675,7 +834,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
ExecuteCommandlineArgs() = default;
ExecuteCommandlineArgs(winrt::hstring commandline) :
_Commandline{ commandline } {};
WINRT_PROPERTY(winrt::hstring, Commandline, L"");
ACTION_ARG(winrt::hstring, Commandline, L"");
static constexpr std::string_view CommandlineKey{ "commandline" };
@ -696,12 +855,23 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
// LOAD BEARING: Not using make_self here _will_ break you in the future!
auto args = winrt::make_self<ExecuteCommandlineArgs>();
JsonUtils::GetValueForKey(json, CommandlineKey, args->_Commandline);
if (args->_Commandline.empty())
if (args->Commandline().empty())
{
return { nullptr, { SettingsLoadWarnings::MissingRequiredParameter } };
}
return { *args, {} };
}
static Json::Value ToJson(const IActionArgs& val)
{
if (!val)
{
return {};
}
Json::Value json{ Json::ValueType::objectValue };
const auto args{ get_self<ExecuteCommandlineArgs>(val) };
JsonUtils::SetValueForKey(json, CommandlineKey, args->_Commandline);
return json;
}
IActionArgs Copy() const
{
auto copy{ winrt::make_self<ExecuteCommandlineArgs>() };
@ -710,7 +880,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
size_t Hash() const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_Commandline);
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Commandline());
}
};
@ -719,7 +889,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
CloseOtherTabsArgs() = default;
CloseOtherTabsArgs(uint32_t& tabIndex) :
_Index{ tabIndex } {};
WINRT_PROPERTY(Windows::Foundation::IReference<uint32_t>, Index, nullptr);
ACTION_ARG(Windows::Foundation::IReference<uint32_t>, Index, nullptr);
static constexpr std::string_view IndexKey{ "index" };
@ -742,6 +912,17 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
JsonUtils::GetValueForKey(json, IndexKey, args->_Index);
return { *args, {} };
}
static Json::Value ToJson(const IActionArgs& val)
{
if (!val)
{
return {};
}
Json::Value json{ Json::ValueType::objectValue };
const auto args{ get_self<CloseOtherTabsArgs>(val) };
JsonUtils::SetValueForKey(json, IndexKey, args->_Index);
return json;
}
IActionArgs Copy() const
{
auto copy{ winrt::make_self<CloseOtherTabsArgs>() };
@ -750,7 +931,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
size_t Hash() const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_Index);
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Index());
}
};
@ -759,7 +940,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
CloseTabsAfterArgs() = default;
CloseTabsAfterArgs(uint32_t& tabIndex) :
_Index{ tabIndex } {};
WINRT_PROPERTY(Windows::Foundation::IReference<uint32_t>, Index, nullptr);
ACTION_ARG(Windows::Foundation::IReference<uint32_t>, Index, nullptr);
static constexpr std::string_view IndexKey{ "index" };
@ -782,6 +963,17 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
JsonUtils::GetValueForKey(json, IndexKey, args->_Index);
return { *args, {} };
}
static Json::Value ToJson(const IActionArgs& val)
{
if (!val)
{
return {};
}
Json::Value json{ Json::ValueType::objectValue };
const auto args{ get_self<CloseTabsAfterArgs>(val) };
JsonUtils::SetValueForKey(json, IndexKey, args->_Index);
return json;
}
IActionArgs Copy() const
{
auto copy{ winrt::make_self<CloseTabsAfterArgs>() };
@ -790,7 +982,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
size_t Hash() const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_Index);
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Index());
}
};
@ -799,7 +991,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
MoveTabArgs() = default;
MoveTabArgs(MoveTabDirection direction) :
_Direction{ direction } {};
WINRT_PROPERTY(MoveTabDirection, Direction, MoveTabDirection::None);
ACTION_ARG(MoveTabDirection, Direction, MoveTabDirection::None);
static constexpr std::string_view DirectionKey{ "direction" };
@ -820,7 +1012,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
// LOAD BEARING: Not using make_self here _will_ break you in the future!
auto args = winrt::make_self<MoveTabArgs>();
JsonUtils::GetValueForKey(json, DirectionKey, args->_Direction);
if (args->_Direction == MoveTabDirection::None)
if (args->Direction() == MoveTabDirection::None)
{
return { nullptr, { SettingsLoadWarnings::MissingRequiredParameter } };
}
@ -829,6 +1021,17 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
return { *args, {} };
}
}
static Json::Value ToJson(const IActionArgs& val)
{
if (!val)
{
return {};
}
Json::Value json{ Json::ValueType::objectValue };
const auto args{ get_self<MoveTabArgs>(val) };
JsonUtils::SetValueForKey(json, DirectionKey, args->_Direction);
return json;
}
IActionArgs Copy() const
{
auto copy{ winrt::make_self<MoveTabArgs>() };
@ -837,14 +1040,14 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
size_t Hash() const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_Direction);
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Direction());
}
};
struct ScrollUpArgs : public ScrollUpArgsT<ScrollUpArgs>
{
ScrollUpArgs() = default;
WINRT_PROPERTY(Windows::Foundation::IReference<uint32_t>, RowsToScroll, nullptr);
ACTION_ARG(Windows::Foundation::IReference<uint32_t>, RowsToScroll, nullptr);
static constexpr std::string_view RowsToScrollKey{ "rowsToScroll" };
@ -867,6 +1070,17 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
JsonUtils::GetValueForKey(json, RowsToScrollKey, args->_RowsToScroll);
return { *args, {} };
}
static Json::Value ToJson(const IActionArgs& val)
{
if (!val)
{
return {};
}
Json::Value json{ Json::ValueType::objectValue };
const auto args{ get_self<ScrollUpArgs>(val) };
JsonUtils::SetValueForKey(json, RowsToScrollKey, args->_RowsToScroll);
return json;
}
IActionArgs Copy() const
{
auto copy{ winrt::make_self<ScrollUpArgs>() };
@ -875,14 +1089,14 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
size_t Hash() const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_RowsToScroll);
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(RowsToScroll());
}
};
struct ScrollDownArgs : public ScrollDownArgsT<ScrollDownArgs>
{
ScrollDownArgs() = default;
WINRT_PROPERTY(Windows::Foundation::IReference<uint32_t>, RowsToScroll, nullptr);
ACTION_ARG(Windows::Foundation::IReference<uint32_t>, RowsToScroll, nullptr);
static constexpr std::string_view RowsToScrollKey{ "rowsToScroll" };
@ -905,6 +1119,17 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
JsonUtils::GetValueForKey(json, RowsToScrollKey, args->_RowsToScroll);
return { *args, {} };
}
static Json::Value ToJson(const IActionArgs& val)
{
if (!val)
{
return {};
}
Json::Value json{ Json::ValueType::objectValue };
const auto args{ get_self<ScrollDownArgs>(val) };
JsonUtils::SetValueForKey(json, RowsToScrollKey, args->_RowsToScroll);
return json;
}
IActionArgs Copy() const
{
auto copy{ winrt::make_self<ScrollDownArgs>() };
@ -913,7 +1138,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
size_t Hash() const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_RowsToScroll);
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(RowsToScroll());
}
};
@ -922,7 +1147,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
ToggleCommandPaletteArgs() = default;
// To preserve backward compatibility the default is Action.
WINRT_PROPERTY(CommandPaletteLaunchMode, LaunchMode, CommandPaletteLaunchMode::Action);
ACTION_ARG(CommandPaletteLaunchMode, LaunchMode, CommandPaletteLaunchMode::Action);
static constexpr std::string_view LaunchModeKey{ "launchMode" };
@ -945,6 +1170,17 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
JsonUtils::GetValueForKey(json, LaunchModeKey, args->_LaunchMode);
return { *args, {} };
}
static Json::Value ToJson(const IActionArgs& val)
{
if (!val)
{
return {};
}
Json::Value json{ Json::ValueType::objectValue };
const auto args{ get_self<ToggleCommandPaletteArgs>(val) };
JsonUtils::SetValueForKey(json, LaunchModeKey, args->_LaunchMode);
return json;
}
IActionArgs Copy() const
{
auto copy{ winrt::make_self<ToggleCommandPaletteArgs>() };
@ -953,7 +1189,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
size_t Hash() const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_LaunchMode);
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(LaunchMode());
}
};
@ -962,7 +1198,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
FindMatchArgs() = default;
FindMatchArgs(FindMatchDirection direction) :
_Direction{ direction } {};
WINRT_PROPERTY(FindMatchDirection, Direction, FindMatchDirection::None);
ACTION_ARG(FindMatchDirection, Direction, FindMatchDirection::None);
static constexpr std::string_view DirectionKey{ "direction" };
@ -983,7 +1219,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
// LOAD BEARING: Not using make_self here _will_ break you in the future!
auto args = winrt::make_self<FindMatchArgs>();
JsonUtils::GetValueForKey(json, DirectionKey, args->_Direction);
if (args->_Direction == FindMatchDirection::None)
if (args->Direction() == FindMatchDirection::None)
{
return { nullptr, { SettingsLoadWarnings::MissingRequiredParameter } };
}
@ -992,6 +1228,17 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
return { *args, {} };
}
}
static Json::Value ToJson(const IActionArgs& val)
{
if (!val)
{
return {};
}
Json::Value json{ Json::ValueType::objectValue };
const auto args{ get_self<FindMatchArgs>(val) };
JsonUtils::GetValueForKey(json, DirectionKey, args->_Direction);
return json;
}
IActionArgs Copy() const
{
auto copy{ winrt::make_self<FindMatchArgs>() };
@ -1000,7 +1247,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
size_t Hash() const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_Direction);
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Direction());
}
};
@ -1030,6 +1277,15 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
args->_TerminalArgs = NewTerminalArgs::FromJson(json);
return { *args, {} };
}
static Json::Value ToJson(const IActionArgs& val)
{
if (!val)
{
return {};
}
const auto args{ get_self<NewWindowArgs>(val) };
return NewTerminalArgs::ToJson(args->_TerminalArgs);
}
IActionArgs Copy() const
{
auto copy{ winrt::make_self<NewWindowArgs>() };
@ -1038,14 +1294,14 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
size_t Hash() const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_TerminalArgs);
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(TerminalArgs());
}
};
struct PrevTabArgs : public PrevTabArgsT<PrevTabArgs>
{
PrevTabArgs() = default;
WINRT_PROPERTY(Windows::Foundation::IReference<TabSwitcherMode>, SwitcherMode, nullptr);
ACTION_ARG(Windows::Foundation::IReference<TabSwitcherMode>, SwitcherMode, nullptr);
static constexpr std::string_view SwitcherModeKey{ "tabSwitcherMode" };
public:
@ -1067,6 +1323,17 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
JsonUtils::GetValueForKey(json, SwitcherModeKey, args->_SwitcherMode);
return { *args, {} };
}
static Json::Value ToJson(const IActionArgs& val)
{
if (!val)
{
return {};
}
Json::Value json{ Json::ValueType::objectValue };
const auto args{ get_self<PrevTabArgs>(val) };
JsonUtils::SetValueForKey(json, SwitcherModeKey, args->_SwitcherMode);
return json;
}
IActionArgs Copy() const
{
auto copy{ winrt::make_self<PrevTabArgs>() };
@ -1075,14 +1342,14 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
size_t Hash() const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_SwitcherMode);
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(SwitcherMode());
}
};
struct NextTabArgs : public NextTabArgsT<NextTabArgs>
{
NextTabArgs() = default;
WINRT_PROPERTY(Windows::Foundation::IReference<TabSwitcherMode>, SwitcherMode, nullptr);
ACTION_ARG(Windows::Foundation::IReference<TabSwitcherMode>, SwitcherMode, nullptr);
static constexpr std::string_view SwitcherModeKey{ "tabSwitcherMode" };
public:
@ -1104,6 +1371,17 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
JsonUtils::GetValueForKey(json, SwitcherModeKey, args->_SwitcherMode);
return { *args, {} };
}
static Json::Value ToJson(const IActionArgs& val)
{
if (!val)
{
return {};
}
Json::Value json{ Json::ValueType::objectValue };
const auto args{ get_self<NextTabArgs>(val) };
JsonUtils::SetValueForKey(json, SwitcherModeKey, args->_SwitcherMode);
return json;
}
IActionArgs Copy() const
{
auto copy{ winrt::make_self<NextTabArgs>() };
@ -1112,14 +1390,14 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
size_t Hash() const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_SwitcherMode);
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(SwitcherMode());
}
};
struct RenameWindowArgs : public RenameWindowArgsT<RenameWindowArgs>
{
RenameWindowArgs() = default;
WINRT_PROPERTY(winrt::hstring, Name);
ACTION_ARG(winrt::hstring, Name);
static constexpr std::string_view NameKey{ "name" };
public:
@ -1141,6 +1419,17 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
JsonUtils::GetValueForKey(json, NameKey, args->_Name);
return { *args, {} };
}
static Json::Value ToJson(const IActionArgs& val)
{
if (!val)
{
return {};
}
Json::Value json{ Json::ValueType::objectValue };
const auto args{ get_self<RenameWindowArgs>(val) };
JsonUtils::SetValueForKey(json, NameKey, args->_Name);
return json;
}
IActionArgs Copy() const
{
auto copy{ winrt::make_self<RenameWindowArgs>() };
@ -1149,18 +1438,18 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
size_t Hash() const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_Name);
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Name());
}
};
struct GlobalSummonArgs : public GlobalSummonArgsT<GlobalSummonArgs>
{
GlobalSummonArgs() = default;
WINRT_PROPERTY(winrt::hstring, Name, L"");
WINRT_PROPERTY(Model::DesktopBehavior, Desktop, Model::DesktopBehavior::ToCurrent);
WINRT_PROPERTY(Model::MonitorBehavior, Monitor, Model::MonitorBehavior::ToMouse);
WINRT_PROPERTY(bool, ToggleVisibility, true);
WINRT_PROPERTY(uint32_t, DropdownDuration, 0);
ACTION_ARG(winrt::hstring, Name, L"");
ACTION_ARG(Model::DesktopBehavior, Desktop, Model::DesktopBehavior::ToCurrent);
ACTION_ARG(Model::MonitorBehavior, Monitor, Model::MonitorBehavior::ToMouse);
ACTION_ARG(bool, ToggleVisibility, true);
ACTION_ARG(uint32_t, DropdownDuration, 0);
static constexpr std::string_view NameKey{ "name" };
static constexpr std::string_view DesktopKey{ "desktop" };
@ -1194,6 +1483,21 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
JsonUtils::GetValueForKey(json, ToggleVisibilityKey, args->_ToggleVisibility);
return { *args, {} };
}
static Json::Value ToJson(const IActionArgs& val)
{
if (!val)
{
return {};
}
Json::Value json{ Json::ValueType::objectValue };
const auto args{ get_self<GlobalSummonArgs>(val) };
JsonUtils::SetValueForKey(json, NameKey, args->_Name);
JsonUtils::SetValueForKey(json, DesktopKey, args->_Desktop);
JsonUtils::SetValueForKey(json, MonitorKey, args->_Monitor);
JsonUtils::GetValueForKey(json, DropdownDurationKey, args->_DropdownDuration);
JsonUtils::SetValueForKey(json, ToggleVisibilityKey, args->_ToggleVisibility);
return json;
}
IActionArgs Copy() const
{
auto copy{ winrt::make_self<GlobalSummonArgs>() };
@ -1218,7 +1522,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
size_t Hash() const
{
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(_Name, _Desktop, _Monitor, _DropdownDuration, _ToggleVisibility);
return ::Microsoft::Terminal::Settings::Model::HashUtils::HashProperty(Name(), Desktop(), Monitor(), DropdownDuration(), ToggleVisibility());
}
};

View file

@ -65,7 +65,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
// population
void AddAction(const Model::Command& cmd);
// JSON
static com_ptr<ActionMap> FromJson(const Json::Value& json);
std::vector<SettingsLoadWarnings> LayerJson(const Json::Value& json);
Json::Value ToJson() const;
// modification
bool RebindKeys(Control::KeyChord const& oldKeys, Control::KeyChord const& newKeys);

View file

@ -19,6 +19,13 @@ using namespace winrt::Microsoft::Terminal::Settings::Model;
namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{
com_ptr<ActionMap> ActionMap::FromJson(const Json::Value& json)
{
auto result = make_self<ActionMap>();
result->LayerJson(json);
return result;
}
// Method Description:
// - Deserialize an ActionMap from the array `json`. The json array should contain
// an array of serialized `Command` objects.
@ -49,6 +56,41 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
return warnings;
}
Json::Value ActionMap::ToJson() const
{
Json::Value actionList{ Json::ValueType::arrayValue };
// Serialize all standard Command objects in the current layer
for (const auto& [_, cmd] : _ActionMap)
{
// Command serializes to an array of JSON objects.
// This is because a Command may have multiple key chords associated with it.
// The name and icon are only serialized in the first object.
// Example:
// { "name": "Custom Copy", "command": "copy", "keys": "ctrl+c" }
// { "command": "copy", "keys": "ctrl+shift+c" }
// { "command": "copy", "keys": "ctrl+ins" }
const auto cmdImpl{ winrt::get_self<implementation::Command>(cmd) };
const auto& cmdJsonArray{ cmdImpl->ToJson() };
for (const auto& cmdJson : cmdJsonArray)
{
actionList.append(cmdJson);
}
}
// Serialize all nested Command objects added in the current layer
for (const auto& [_, cmd] : _NestedCommands)
{
const auto cmdImpl{ winrt::get_self<implementation::Command>(cmd) };
const auto& cmdJsonArray{ cmdImpl->ToJson() };
for (const auto& cmdJson : cmdJsonArray)
{
actionList.append(cmdJson);
}
}
return actionList;
}
// Method Description:
// - Takes the KeyModifier flags from Terminal and maps them to the Windows WinRT types
// Return Value:

View file

@ -75,3 +75,30 @@
ON_ALL_ACTIONS(OpenWindowRenamer) \
ON_ALL_ACTIONS(GlobalSummon) \
ON_ALL_ACTIONS(QuakeMode)
#define ALL_SHORTCUT_ACTIONS_WITH_ARGS \
ON_ALL_ACTIONS_WITH_ARGS(AdjustFontSize) \
ON_ALL_ACTIONS_WITH_ARGS(CloseOtherTabs) \
ON_ALL_ACTIONS_WITH_ARGS(CloseTabsAfter) \
ON_ALL_ACTIONS_WITH_ARGS(CopyText) \
ON_ALL_ACTIONS_WITH_ARGS(ExecuteCommandline) \
ON_ALL_ACTIONS_WITH_ARGS(FindMatch) \
ON_ALL_ACTIONS_WITH_ARGS(GlobalSummon) \
ON_ALL_ACTIONS_WITH_ARGS(MoveFocus) \
ON_ALL_ACTIONS_WITH_ARGS(MoveTab) \
ON_ALL_ACTIONS_WITH_ARGS(NewTab) \
ON_ALL_ACTIONS_WITH_ARGS(NewWindow) \
ON_ALL_ACTIONS_WITH_ARGS(NextTab) \
ON_ALL_ACTIONS_WITH_ARGS(OpenSettings) \
ON_ALL_ACTIONS_WITH_ARGS(PrevTab) \
ON_ALL_ACTIONS_WITH_ARGS(RenameTab) \
ON_ALL_ACTIONS_WITH_ARGS(RenameWindow) \
ON_ALL_ACTIONS_WITH_ARGS(ResizePane) \
ON_ALL_ACTIONS_WITH_ARGS(ScrollDown) \
ON_ALL_ACTIONS_WITH_ARGS(ScrollUp) \
ON_ALL_ACTIONS_WITH_ARGS(SendInput) \
ON_ALL_ACTIONS_WITH_ARGS(SetColorScheme) \
ON_ALL_ACTIONS_WITH_ARGS(SetTabColor) \
ON_ALL_ACTIONS_WITH_ARGS(SplitPane) \
ON_ALL_ACTIONS_WITH_ARGS(SwitchToTab) \
ON_ALL_ACTIONS_WITH_ARGS(ToggleCommandPalette)

View file

@ -1345,15 +1345,5 @@ Json::Value CascadiaSettings::ToJson() const
}
json[JsonKey(SchemesKey)] = schemes;
// "actions"/"keybindings" will be whatever blob we had in the file
if (_userSettings.isMember(JsonKey(LegacyKeybindingsKey)))
{
json[JsonKey(LegacyKeybindingsKey)] = _userSettings[JsonKey(LegacyKeybindingsKey)];
}
if (_userSettings.isMember(JsonKey(ActionsKey)))
{
json[JsonKey(ActionsKey)] = _userSettings[JsonKey(ActionsKey)];
}
return json;
}

View file

@ -48,6 +48,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
command->_IterateOn = _IterateOn;
command->_originalJson = _originalJson;
command->_nestedCommand = _nestedCommand;
if (HasNestedCommands())
{
command->_subcommands = winrt::single_threaded_map<winrt::hstring, Model::Command>();
@ -383,6 +384,65 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
return warnings;
}
// Function Description:
// - Serialize the Command into an array of json actions
// Arguments:
// - <none>
// Return Value:
// - an array of serialized actions
Json::Value Command::ToJson() const
{
Json::Value cmdList{ Json::ValueType::arrayValue };
if (_nestedCommand)
{
// handle nested command
// For nested commands, we can trust _originalJson to be correct.
// In fact, we _need_ to use it here because we don't actually deserialize `iterateOn`
// until we expand the command.
cmdList.append(_originalJson);
}
else if (_keyMappings.empty())
{
// only write out one command
Json::Value cmdJson{ Json::ValueType::objectValue };
JsonUtils::SetValueForKey(cmdJson, IconKey, _iconPath);
JsonUtils::SetValueForKey(cmdJson, NameKey, _name);
if (_ActionAndArgs)
{
cmdJson[JsonKey(ActionKey)] = ActionAndArgs::ToJson(_ActionAndArgs);
}
cmdList.append(cmdJson);
}
else
{
// we'll write out one command per key mapping
for (auto keys{ _keyMappings.begin() }; keys != _keyMappings.end(); ++keys)
{
Json::Value cmdJson{ Json::ValueType::objectValue };
if (keys == _keyMappings.begin())
{
// First iteration also writes icon and name
JsonUtils::SetValueForKey(cmdJson, IconKey, _iconPath);
JsonUtils::SetValueForKey(cmdJson, NameKey, _name);
}
if (_ActionAndArgs)
{
cmdJson[JsonKey(ActionKey)] = ActionAndArgs::ToJson(_ActionAndArgs);
}
JsonUtils::SetValueForKey(cmdJson, KeysKey, *keys);
cmdList.append(cmdJson);
}
}
return cmdList;
}
// Function Description:
// - Helper to escape a string as a json string. This function will also
// trim off the leading and trailing double-quotes, so the output string

View file

@ -49,6 +49,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
static std::vector<SettingsLoadWarnings> LayerJson(Windows::Foundation::Collections::IMap<winrt::hstring, Model::Command>& commands,
const Json::Value& json);
Json::Value ToJson() const;
bool HasNestedCommands() const;
bool IsNestedCommand() const noexcept;
Windows::Foundation::Collections::IMapView<winrt::hstring, Model::Command> NestedCommands() const;

View file

@ -411,10 +411,6 @@ Json::Value GlobalAppSettings::ToJson() const
JsonUtils::SetValueForKey(json, DetectURLsKey, _DetectURLs);
// clang-format on
// TODO GH#8100: keymap needs to be serialized here
// For deserialization, we iterate over each action in the Json and interpret it as a keybinding, then as a command.
// Converting this back to JSON is a problem because we have no way to know if a Command and Keybinding come from
// the same entry.
json[JsonKey(ActionsKey)] = _actionMap->ToJson();
return json;
}

View file

@ -77,6 +77,7 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils
{
static constexpr std::optional<T> EmptyV() { return std::nullopt; }
static constexpr bool HasValue(const std::optional<T>& o) { return o.has_value(); }
// We can return a reference here because the original value is stored inside an std::optional
static constexpr auto&& Value(const std::optional<T>& o) { return *o; }
};
@ -85,7 +86,8 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils
{
static constexpr ::winrt::Windows::Foundation::IReference<T> EmptyV() { return nullptr; }
static constexpr bool HasValue(const ::winrt::Windows::Foundation::IReference<T>& o) { return static_cast<bool>(o); }
static constexpr auto&& Value(const ::winrt::Windows::Foundation::IReference<T>& o) { return o.Value(); }
// We CANNOT return a reference here because IReference does NOT return a reference to its internal memory
static constexpr auto Value(const ::winrt::Windows::Foundation::IReference<T>& o) { return o.Value(); }
};
class SerializationError : public std::runtime_error