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:
parent
20b7fe4ef4
commit
eecdd53eb8
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -25,4 +25,11 @@ namespace TerminalApp
|
|||
std::optional<int> x;
|
||||
std::optional<int> y;
|
||||
};
|
||||
|
||||
enum class ExpandCommandType : uint32_t
|
||||
{
|
||||
None = 0,
|
||||
Profiles,
|
||||
ColorSchemes
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) = {
|
||||
|
|
|
@ -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}" }
|
||||
}
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue