Add support for commands iterable on color schemes (#7329)

## Summary of the Pull Request

![cmdpal-set-color-scheme](https://user-images.githubusercontent.com/18356694/90517094-8eddd480-e12a-11ea-8be4-8b6782d8d88c.gif)

Allows for creating commands that iterate over the user's color schemes. Also adds a top-level nested command to `defaults.json` that allows the user to select a color scheme (pictured above). I'm not sure there are really any other use cases that make sense, but it _really_ makes sense for this one.

## References
* #5400 - cmdpal megathread
* made possible by #6856, _and support from viewers like you._
* All this is being done in pursuit of #6689 

## PR Checklist
* [x] Closes wait what? I could have swore there was an issue for this one...
* [x] I work here
* [x] Tests added/passed
* [ ] Requires documentation to be updated - okay maybe now I'll write some docs

## Detailed Description of the Pull Request / Additional comments

Most of the hard work for this was already done in #6856. This is just another thing to iterate over.

## Validation Steps Performed
* Played with this default command. It works great.
* Added tests.
This commit is contained in:
Mike Griese 2020-08-19 12:33:19 -05:00 committed by GitHub
parent 20b7fe4ef4
commit eecdd53eb8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 258 additions and 43 deletions

View file

@ -97,6 +97,8 @@ namespace TerminalAppLocalTests
TEST_METHOD(TestUnbindNestedCommand);
TEST_METHOD(TestRebindNestedCommand);
TEST_METHOD(TestIterableColorSchemeCommands);
TEST_CLASS_SETUP(ClassSetup)
{
InitializeJsonReader();
@ -2681,7 +2683,7 @@ namespace TerminalAppLocalTests
VERIFY_ARE_EQUAL(L"${profile.name}", realArgs.TerminalArgs().Profile());
}
auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles());
auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles(), settings._globals.GetColorSchemes());
_logCommandNames(expandedCommands);
VERIFY_ARE_EQUAL(0u, settings._warnings.size());
@ -2811,7 +2813,7 @@ namespace TerminalAppLocalTests
VERIFY_ARE_EQUAL(L"${profile.name}", realArgs.TerminalArgs().Profile());
}
auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles());
auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles(), settings._globals.GetColorSchemes());
_logCommandNames(expandedCommands);
VERIFY_ARE_EQUAL(0u, settings._warnings.size());
@ -2944,7 +2946,7 @@ namespace TerminalAppLocalTests
}
settings._ValidateSettings();
auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles());
auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles(), settings._globals.GetColorSchemes());
_logCommandNames(expandedCommands);
VERIFY_ARE_EQUAL(0u, settings._warnings.size());
@ -3065,7 +3067,7 @@ namespace TerminalAppLocalTests
auto& commands = settings._globals.GetCommands();
settings._ValidateSettings();
auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles());
auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles(), settings._globals.GetColorSchemes());
_logCommandNames(expandedCommands);
VERIFY_ARE_EQUAL(0u, settings._warnings.size());
@ -3173,7 +3175,7 @@ namespace TerminalAppLocalTests
auto& commands = settings._globals.GetCommands();
settings._ValidateSettings();
auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles());
auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles(), settings._globals.GetColorSchemes());
_logCommandNames(expandedCommands);
VERIFY_ARE_EQUAL(0u, settings._warnings.size());
@ -3312,7 +3314,7 @@ namespace TerminalAppLocalTests
auto& commands = settings._globals.GetCommands();
settings._ValidateSettings();
auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles());
auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles(), settings._globals.GetColorSchemes());
_logCommandNames(expandedCommands);
VERIFY_ARE_EQUAL(0u, settings._warnings.size());
@ -3465,7 +3467,7 @@ namespace TerminalAppLocalTests
auto& commands = settings._globals.GetCommands();
settings._ValidateSettings();
auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles());
auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles(), settings._globals.GetColorSchemes());
_logCommandNames(expandedCommands);
VERIFY_ARE_EQUAL(0u, settings._warnings.size());
@ -3578,7 +3580,7 @@ namespace TerminalAppLocalTests
auto& commands = settings._globals.GetCommands();
settings._ValidateSettings();
auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles());
auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles(), settings._globals.GetColorSchemes());
_logCommandNames(expandedCommands);
VERIFY_ARE_EQUAL(0u, settings._warnings.size());
@ -3942,4 +3944,141 @@ namespace TerminalAppLocalTests
}
}
void SettingsTests::TestIterableColorSchemeCommands()
{
// For this test, put an iterable command with a given `name`,
// containing a ${profile.name} to replace. When we expand it, it should
// have created one command for each profile.
const std::string settingsJson{ R"(
{
"defaultProfile": "{6239a42c-0000-49a3-80bd-e8fdd045185c}",
"profiles": [
{
"name": "profile0",
"guid": "{6239a42c-0000-49a3-80bd-e8fdd045185c}",
"historySize": 1,
"commandline": "cmd.exe"
},
{
"name": "profile1",
"guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}",
"historySize": 2,
"commandline": "pwsh.exe"
},
{
"name": "profile2",
"historySize": 3,
"commandline": "wsl.exe"
}
],
"schemes": [
{ "name": "scheme_0" },
{ "name": "scheme_1" },
{ "name": "scheme_2" },
],
"bindings": [
{
"name": "iterable command ${scheme.name}",
"iterateOn": "schemes",
"command": { "action": "splitPane", "profile": "${scheme.name}" }
},
]
})" };
VerifyParseSucceeded(settingsJson);
CascadiaSettings settings{};
settings._ParseJsonString(settingsJson, false);
settings.LayerJson(settings._userSettings);
VERIFY_ARE_EQUAL(0u, settings._warnings.size());
VERIFY_ARE_EQUAL(3u, settings.GetProfiles().size());
auto& commands = settings._globals.GetCommands();
VERIFY_ARE_EQUAL(1u, commands.Size());
{
auto command = commands.Lookup(L"iterable command ${scheme.name}");
VERIFY_IS_NOT_NULL(command);
auto actionAndArgs = command.Action();
VERIFY_IS_NOT_NULL(actionAndArgs);
VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, actionAndArgs.Action());
const auto& realArgs = actionAndArgs.Args().try_as<SplitPaneArgs>();
VERIFY_IS_NOT_NULL(realArgs);
// Verify the args have the expected value
VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle());
VERIFY_IS_NOT_NULL(realArgs.TerminalArgs());
VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty());
VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty());
VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty());
VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty());
VERIFY_ARE_EQUAL(L"${scheme.name}", realArgs.TerminalArgs().Profile());
}
auto expandedCommands = implementation::TerminalPage::_ExpandCommands(commands.GetView(), settings.GetProfiles(), settings._globals.GetColorSchemes());
_logCommandNames(expandedCommands);
VERIFY_ARE_EQUAL(0u, settings._warnings.size());
VERIFY_ARE_EQUAL(3u, expandedCommands.Size());
// Yes, this test is testing splitPane with profiles named after each
// color scheme. These would obviously not work in real life, they're
// just easy tests to write.
{
auto command = expandedCommands.Lookup(L"iterable command scheme_0");
VERIFY_IS_NOT_NULL(command);
auto actionAndArgs = command.Action();
VERIFY_IS_NOT_NULL(actionAndArgs);
VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, actionAndArgs.Action());
const auto& realArgs = actionAndArgs.Args().try_as<SplitPaneArgs>();
VERIFY_IS_NOT_NULL(realArgs);
// Verify the args have the expected value
VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle());
VERIFY_IS_NOT_NULL(realArgs.TerminalArgs());
VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty());
VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty());
VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty());
VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty());
VERIFY_ARE_EQUAL(L"scheme_0", realArgs.TerminalArgs().Profile());
}
{
auto command = expandedCommands.Lookup(L"iterable command scheme_1");
VERIFY_IS_NOT_NULL(command);
auto actionAndArgs = command.Action();
VERIFY_IS_NOT_NULL(actionAndArgs);
VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, actionAndArgs.Action());
const auto& realArgs = actionAndArgs.Args().try_as<SplitPaneArgs>();
VERIFY_IS_NOT_NULL(realArgs);
// Verify the args have the expected value
VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle());
VERIFY_IS_NOT_NULL(realArgs.TerminalArgs());
VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty());
VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty());
VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty());
VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty());
VERIFY_ARE_EQUAL(L"scheme_1", realArgs.TerminalArgs().Profile());
}
{
auto command = expandedCommands.Lookup(L"iterable command scheme_2");
VERIFY_IS_NOT_NULL(command);
auto actionAndArgs = command.Action();
VERIFY_IS_NOT_NULL(actionAndArgs);
VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, actionAndArgs.Action());
const auto& realArgs = actionAndArgs.Args().try_as<SplitPaneArgs>();
VERIFY_IS_NOT_NULL(realArgs);
// Verify the args have the expected value
VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Automatic, realArgs.SplitStyle());
VERIFY_IS_NOT_NULL(realArgs.TerminalArgs());
VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty());
VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty());
VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty());
VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty());
VERIFY_ARE_EQUAL(L"scheme_2", realArgs.TerminalArgs().Profile());
}
}
}

View file

@ -9,6 +9,7 @@
#include "ActionAndArgs.h"
#include "JsonUtils.h"
#include <LibraryResources.h>
#include "TerminalSettingsSerializationHelpers.h"
using namespace winrt::TerminalApp;
using namespace winrt::Windows::Foundation;
@ -21,9 +22,8 @@ static constexpr std::string_view ArgsKey{ "args" };
static constexpr std::string_view IterateOnKey{ "iterateOn" };
static constexpr std::string_view CommandsKey{ "commands" };
static constexpr std::string_view IterateOnProfilesValue{ "profiles" };
static constexpr std::string_view ProfileName{ "${profile.name}" };
static constexpr std::string_view ProfileNameToken{ "${profile.name}" };
static constexpr std::string_view SchemeNameToken{ "${scheme.name}" };
namespace winrt::TerminalApp::implementation
{
@ -121,14 +121,7 @@ namespace winrt::TerminalApp::implementation
auto result = winrt::make_self<Command>();
bool nested = false;
if (const auto iterateOnJson{ json[JsonKey(IterateOnKey)] })
{
auto s = iterateOnJson.asString();
if (s == IterateOnProfilesValue)
{
result->_IterateOn = ExpandCommandType::Profiles;
}
}
JsonUtils::GetValueForKey(json, IterateOnKey, result->_IterateOn);
// For iterable commands, we'll make another pass at parsing them once
// the json is patched. So ignore parsing sub-commands for now. Commands
@ -290,6 +283,7 @@ namespace winrt::TerminalApp::implementation
// - <none>
void Command::ExpandCommands(Windows::Foundation::Collections::IMap<winrt::hstring, winrt::TerminalApp::Command>& commands,
gsl::span<const ::TerminalApp::Profile> profiles,
gsl::span<winrt::TerminalApp::ColorScheme> schemes,
std::vector<::TerminalApp::SettingsLoadWarnings>& warnings)
{
std::vector<winrt::hstring> commandsToRemove;
@ -300,7 +294,7 @@ namespace winrt::TerminalApp::implementation
{
auto cmd{ get_self<implementation::Command>(nameAndCmd.Value()) };
auto newCommands = _expandCommand(cmd, profiles, warnings);
auto newCommands = _expandCommand(cmd, profiles, schemes, warnings);
if (newCommands.size() > 0)
{
commandsToRemove.push_back(nameAndCmd.Key());
@ -345,13 +339,14 @@ namespace winrt::TerminalApp::implementation
// the newly-created commands.
std::vector<winrt::TerminalApp::Command> Command::_expandCommand(Command* const expandable,
gsl::span<const ::TerminalApp::Profile> profiles,
gsl::span<winrt::TerminalApp::ColorScheme> schemes,
std::vector<::TerminalApp::SettingsLoadWarnings>& warnings)
{
std::vector<winrt::TerminalApp::Command> newCommands;
if (expandable->HasNestedCommands())
{
ExpandCommands(expandable->_subcommands, profiles, warnings);
ExpandCommands(expandable->_subcommands, profiles, schemes, warnings);
}
if (expandable->_IterateOn == ExpandCommandType::None)
@ -365,6 +360,26 @@ namespace winrt::TerminalApp::implementation
// First, get a string for the original Json::Value
auto oldJsonString = expandable->_originalJson.toStyledString();
auto reParseJson = [&](const auto& newJsonString) -> bool {
// - Now, re-parse the modified value.
Json::Value newJsonValue;
const auto actualDataStart = newJsonString.data();
const auto actualDataEnd = newJsonString.data() + newJsonString.size();
if (!reader->parse(actualDataStart, actualDataEnd, &newJsonValue, &errs))
{
warnings.push_back(::TerminalApp::SettingsLoadWarnings::FailedToParseCommandJson);
// If we encounter a re-parsing error, just stop processing the rest of the commands.
return false;
}
// Pass the new json back though FromJson, to get the new expanded value.
if (auto newCmd{ Command::FromJson(newJsonValue, warnings) })
{
newCommands.push_back(*newCmd);
}
return true;
};
if (expandable->_IterateOn == ExpandCommandType::Profiles)
{
for (const auto& p : profiles)
@ -382,24 +397,35 @@ namespace winrt::TerminalApp::implementation
// - Escape the profile name for JSON appropriately
auto escapedProfileName = _escapeForJson(til::u16u8(p.GetName()));
auto newJsonString = til::replace_needle_in_haystack(oldJsonString,
ProfileName,
ProfileNameToken,
escapedProfileName);
// - Now, re-parse the modified value.
Json::Value newJsonValue;
const auto actualDataStart = newJsonString.data();
const auto actualDataEnd = newJsonString.data() + newJsonString.size();
if (!reader->parse(actualDataStart, actualDataEnd, &newJsonValue, &errs))
// If we encounter a re-parsing error, just stop processing the rest of the commands.
if (!reParseJson(newJsonString))
{
warnings.push_back(::TerminalApp::SettingsLoadWarnings::FailedToParseCommandJson);
// If we encounter a re-parsing error, just stop processing the rest of the commands.
break;
}
}
}
else if (expandable->_IterateOn == ExpandCommandType::ColorSchemes)
{
for (const auto& s : schemes)
{
// For each scheme, create a new command. We'll take the
// original json, replace any instances of "${scheme.name}" with
// the scheme's name, then re-attempt to parse the action and
// args.
// Pass the new json back though FromJson, to get the new expanded value.
if (auto newCmd{ Command::FromJson(newJsonValue, warnings) })
// - Escape the profile name for JSON appropriately
auto escapedSchemeName = _escapeForJson(til::u16u8(s.Name()));
auto newJsonString = til::replace_needle_in_haystack(oldJsonString,
SchemeNameToken,
escapedSchemeName);
// If we encounter a re-parsing error, just stop processing the rest of the commands.
if (!reParseJson(newJsonString))
{
newCommands.push_back(*newCmd);
break;
}
}
}

View file

@ -22,6 +22,7 @@ Author(s):
#include "TerminalWarnings.h"
#include "Profile.h"
#include "..\inc\cppwinrt_utils.h"
#include "SettingsTypes.h"
// fwdecl unittest classes
namespace TerminalAppLocalTests
@ -32,12 +33,6 @@ namespace TerminalAppLocalTests
namespace winrt::TerminalApp::implementation
{
enum class ExpandCommandType : uint32_t
{
None = 0,
Profiles
};
struct Command : CommandT<Command>
{
Command();
@ -47,6 +42,7 @@ namespace winrt::TerminalApp::implementation
static void ExpandCommands(Windows::Foundation::Collections::IMap<winrt::hstring, winrt::TerminalApp::Command>& commands,
gsl::span<const ::TerminalApp::Profile> profiles,
gsl::span<winrt::TerminalApp::ColorScheme> schemes,
std::vector<::TerminalApp::SettingsLoadWarnings>& warnings);
static std::vector<::TerminalApp::SettingsLoadWarnings> LayerJson(Windows::Foundation::Collections::IMap<winrt::hstring, winrt::TerminalApp::Command>& commands,
@ -62,7 +58,7 @@ namespace winrt::TerminalApp::implementation
OBSERVABLE_GETSET_PROPERTY(winrt::hstring, KeyChordText, _PropertyChangedHandlers);
OBSERVABLE_GETSET_PROPERTY(winrt::Windows::UI::Xaml::Controls::IconSource, IconSource, _PropertyChangedHandlers, nullptr);
GETSET_PROPERTY(ExpandCommandType, IterateOn, ExpandCommandType::None);
GETSET_PROPERTY(::TerminalApp::ExpandCommandType, IterateOn, ::TerminalApp::ExpandCommandType::None);
private:
Json::Value _originalJson;
@ -70,6 +66,7 @@ namespace winrt::TerminalApp::implementation
static std::vector<winrt::TerminalApp::Command> _expandCommand(Command* const expandable,
gsl::span<const ::TerminalApp::Profile> profiles,
gsl::span<winrt::TerminalApp::ColorScheme> schemes,
std::vector<::TerminalApp::SettingsLoadWarnings>& warnings);
friend class TerminalAppLocalTests::SettingsTests;
friend class TerminalAppLocalTests::CommandTests;

View file

@ -573,6 +573,9 @@
<value>Close tabs after index {0}</value>
<comment>{0} will be replaced with a number</comment>
</data>
<data name="SetColorSchemeParentCommandName" xml:space="preserve">
<value>Select color scheme...</value>
</data>
<data name="TabSwitcherControlName" xml:space="preserve">
<value>Tab Switcher</value>
</data>

View file

@ -25,4 +25,11 @@ namespace TerminalApp
std::optional<int> x;
std::optional<int> y;
};
enum class ExpandCommandType : uint32_t
{
None = 0,
Profiles,
ColorSchemes
};
};

View file

@ -2046,6 +2046,14 @@ namespace winrt::TerminalApp::implementation
_alwaysOnTopChangedHandlers(*this, nullptr);
}
// This is a helper to aid in sorting commands by their `Name`s, alphabetically.
static bool _compareSchemeNames(const winrt::TerminalApp::ColorScheme& lhs, const winrt::TerminalApp::ColorScheme& rhs)
{
std::wstring leftName{ lhs.Name() };
std::wstring rightName{ rhs.Name() };
return leftName.compare(rightName) < 0;
}
// Method Description:
// - Takes a mapping of names->commands and expands them
// Arguments:
@ -2053,9 +2061,22 @@ namespace winrt::TerminalApp::implementation
// Return Value:
// - <none>
IMap<winrt::hstring, winrt::TerminalApp::Command> TerminalPage::_ExpandCommands(IMapView<winrt::hstring, winrt::TerminalApp::Command> commandsToExpand,
gsl::span<const ::TerminalApp::Profile> profiles)
gsl::span<const ::TerminalApp::Profile> profiles,
const std::unordered_map<std::wstring, winrt::TerminalApp::ColorScheme>& schemes)
{
std::vector<::TerminalApp::SettingsLoadWarnings> warnings;
std::vector<winrt::TerminalApp::ColorScheme> sortedSchemes;
sortedSchemes.reserve(schemes.size());
for (const auto& nameAndScheme : schemes)
{
sortedSchemes.push_back(nameAndScheme.second);
}
std::sort(sortedSchemes.begin(),
sortedSchemes.end(),
_compareSchemeNames);
IMap<winrt::hstring, winrt::TerminalApp::Command> copyOfCommands = winrt::single_threaded_map<winrt::hstring, winrt::TerminalApp::Command>();
for (const auto& nameAndCommand : commandsToExpand)
{
@ -2064,6 +2085,7 @@ namespace winrt::TerminalApp::implementation
Command::ExpandCommands(copyOfCommands,
profiles,
sortedSchemes,
warnings);
return copyOfCommands;
@ -2079,7 +2101,8 @@ namespace winrt::TerminalApp::implementation
void TerminalPage::_UpdateCommandsForPalette()
{
IMap<winrt::hstring, winrt::TerminalApp::Command> copyOfCommands = _ExpandCommands(_settings->GlobalSettings().GetCommands().GetView(),
_settings->GetProfiles());
_settings->GetProfiles(),
_settings->GlobalSettings().GetColorSchemes());
_recursiveUpdateCommandKeybindingLabels(_settings, copyOfCommands.GetView());
_recursiveUpdateCommandIcons(copyOfCommands.GetView());

View file

@ -137,7 +137,8 @@ namespace winrt::TerminalApp::implementation
void _UpdateTabWidthMode();
void _UpdateCommandsForPalette();
static winrt::Windows::Foundation::Collections::IMap<winrt::hstring, winrt::TerminalApp::Command> _ExpandCommands(Windows::Foundation::Collections::IMapView<winrt::hstring, winrt::TerminalApp::Command> commandsToExpand,
gsl::span<const ::TerminalApp::Profile> profiles);
gsl::span<const ::TerminalApp::Profile> profiles,
const std::unordered_map<std::wstring, winrt::TerminalApp::ColorScheme>& schemes);
void _DuplicateTabViewItem();
void _RemoveTabViewItem(const Microsoft::UI::Xaml::Controls::TabViewItem& tabViewItem);

View file

@ -184,6 +184,14 @@ JSON_ENUM_MAPPER(::winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode)
};
};
JSON_ENUM_MAPPER(::TerminalApp::ExpandCommandType)
{
JSON_MAPPINGS(2) = {
pair_type{ "profiles", ValueType::Profiles },
pair_type{ "schemes", ValueType::ColorSchemes },
};
};
JSON_FLAG_MAPPER(::winrt::Microsoft::Terminal::TerminalControl::CopyFormat)
{
JSON_MAPPINGS(5) = {

View file

@ -340,6 +340,17 @@
// Visual Adjustments
{ "command": { "action": "adjustFontSize", "delta": 1 }, "keys": "ctrl+=" },
{ "command": { "action": "adjustFontSize", "delta": -1 }, "keys": "ctrl+-" },
{ "command": "resetFontSize", "keys": "ctrl+0" }
{ "command": "resetFontSize", "keys": "ctrl+0" },
{
"name": { "key": "SetColorSchemeParentCommandName" },
"commands": [
{
"iterateOn": "schemes",
"name": "${scheme.name}",
"command": { "action": "setColorScheme", "colorScheme": "${scheme.name}" }
}
]
},
]
}