From eac3eea4848d33f611297e124f46967bfc32e378 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 29 Mar 2021 15:04:39 -0500 Subject: [PATCH] Add a `--colorScheme` param to `new-tab`, `split-pane` (#9602) This is entirely self-serving. In my go-to config, I like having some of the panes for a given profile in a different color scheme. This will let a user pass `--colorScheme ` to manually override the scheme for that profile. Neat! --- doc/cascadia/profiles.schema.json | 4 ++ .../CommandlineTest.cpp | 37 +++++++++++++++++++ .../TerminalApp/AppCommandlineArgs.cpp | 8 ++++ src/cascadia/TerminalApp/AppCommandlineArgs.h | 2 + .../Resources/en-US/Resources.resw | 4 ++ .../TerminalSettingsModel/ActionArgs.cpp | 9 +++++ .../TerminalSettingsModel/ActionArgs.h | 7 +++- .../TerminalSettingsModel/ActionArgs.idl | 2 + .../TerminalSettings.cpp | 8 ++++ 9 files changed, 80 insertions(+), 1 deletion(-) diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index 681a0b6be..5d3410951 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -227,6 +227,10 @@ "type": "boolean", "default": "false", "description": "When set to true, tabTitle overrides the default title of the tab and any title change messages from the application will be suppressed. When set to false, tabTitle behaves as normal" + }, + "colorScheme": { + "description": "The name of a color scheme to use, instead of the one specified by the profile", + "type": "string" } }, "type": "object" diff --git a/src/cascadia/LocalTests_TerminalApp/CommandlineTest.cpp b/src/cascadia/LocalTests_TerminalApp/CommandlineTest.cpp index 0afeb245e..e9d6e74a3 100644 --- a/src/cascadia/LocalTests_TerminalApp/CommandlineTest.cpp +++ b/src/cascadia/LocalTests_TerminalApp/CommandlineTest.cpp @@ -458,6 +458,7 @@ namespace TerminalAppLocalTests VERIFY_IS_NULL(myArgs.TerminalArgs().TabColor()); VERIFY_IS_NULL(myArgs.TerminalArgs().ProfileIndex()); VERIFY_IS_TRUE(myArgs.TerminalArgs().Profile().empty()); + VERIFY_IS_TRUE(myArgs.TerminalArgs().ColorScheme().empty()); } { AppCommandlineArgs appArgs{}; @@ -479,6 +480,7 @@ namespace TerminalAppLocalTests VERIFY_IS_NULL(myArgs.TerminalArgs().ProfileIndex()); VERIFY_IS_FALSE(myArgs.TerminalArgs().Profile().empty()); VERIFY_ARE_EQUAL(L"cmd", myArgs.TerminalArgs().Profile()); + VERIFY_IS_TRUE(myArgs.TerminalArgs().ColorScheme().empty()); } { AppCommandlineArgs appArgs{}; @@ -500,6 +502,7 @@ namespace TerminalAppLocalTests VERIFY_IS_NULL(myArgs.TerminalArgs().ProfileIndex()); VERIFY_IS_TRUE(myArgs.TerminalArgs().Profile().empty()); VERIFY_ARE_EQUAL(L"c:\\Foo", myArgs.TerminalArgs().StartingDirectory()); + VERIFY_IS_TRUE(myArgs.TerminalArgs().ColorScheme().empty()); } { AppCommandlineArgs appArgs{}; @@ -521,6 +524,7 @@ namespace TerminalAppLocalTests VERIFY_IS_NULL(myArgs.TerminalArgs().ProfileIndex()); VERIFY_IS_TRUE(myArgs.TerminalArgs().Profile().empty()); VERIFY_ARE_EQUAL(L"powershell.exe", myArgs.TerminalArgs().Commandline()); + VERIFY_IS_TRUE(myArgs.TerminalArgs().ColorScheme().empty()); } { AppCommandlineArgs appArgs{}; @@ -543,6 +547,7 @@ namespace TerminalAppLocalTests VERIFY_IS_TRUE(myArgs.TerminalArgs().Profile().empty()); auto myCommand = myArgs.TerminalArgs().Commandline(); VERIFY_ARE_EQUAL(L"powershell.exe \"This is an arg with spaces\"", myCommand); + VERIFY_IS_TRUE(myArgs.TerminalArgs().ColorScheme().empty()); } { AppCommandlineArgs appArgs{}; @@ -565,6 +570,7 @@ namespace TerminalAppLocalTests VERIFY_IS_TRUE(myArgs.TerminalArgs().Profile().empty()); auto myCommand = myArgs.TerminalArgs().Commandline(); VERIFY_ARE_EQUAL(L"powershell.exe \"This is an arg with spaces\" another-arg \"more spaces in this one\"", myCommand); + VERIFY_IS_TRUE(myArgs.TerminalArgs().ColorScheme().empty()); } { AppCommandlineArgs appArgs{}; @@ -586,6 +592,7 @@ namespace TerminalAppLocalTests VERIFY_IS_NULL(myArgs.TerminalArgs().ProfileIndex()); VERIFY_IS_FALSE(myArgs.TerminalArgs().Profile().empty()); VERIFY_ARE_EQUAL(L"Windows PowerShell", myArgs.TerminalArgs().Profile()); + VERIFY_IS_TRUE(myArgs.TerminalArgs().ColorScheme().empty()); } { AppCommandlineArgs appArgs{}; @@ -606,6 +613,7 @@ namespace TerminalAppLocalTests VERIFY_IS_NULL(myArgs.TerminalArgs().ProfileIndex()); VERIFY_IS_TRUE(myArgs.TerminalArgs().Profile().empty()); VERIFY_ARE_EQUAL(L"wsl -d Alpine", myArgs.TerminalArgs().Commandline()); + VERIFY_IS_TRUE(myArgs.TerminalArgs().ColorScheme().empty()); } { AppCommandlineArgs appArgs{}; @@ -628,6 +636,7 @@ namespace TerminalAppLocalTests VERIFY_IS_FALSE(myArgs.TerminalArgs().Profile().empty()); VERIFY_ARE_EQUAL(L"wsl -d Alpine", myArgs.TerminalArgs().Commandline()); VERIFY_ARE_EQUAL(L"1", myArgs.TerminalArgs().Profile()); + VERIFY_IS_TRUE(myArgs.TerminalArgs().ColorScheme().empty()); } { AppCommandlineArgs appArgs{}; @@ -651,6 +660,31 @@ namespace TerminalAppLocalTests VERIFY_ARE_EQUAL(til::color(myArgs.TerminalArgs().TabColor().Value()), expectedColor); VERIFY_IS_NULL(myArgs.TerminalArgs().ProfileIndex()); VERIFY_IS_TRUE(myArgs.TerminalArgs().Profile().empty()); + VERIFY_IS_TRUE(myArgs.TerminalArgs().ColorScheme().empty()); + } + { + AppCommandlineArgs appArgs{}; + std::vector rawCommands{ L"wt.exe", subcommand, L"--colorScheme", L"Vintage" }; + const winrt::hstring expectedScheme{ L"Vintage" }; + + _buildCommandlinesHelper(appArgs, 1u, rawCommands); + + VERIFY_ARE_EQUAL(1u, appArgs._startupActions.size()); + + auto actionAndArgs = appArgs._startupActions.at(0); + VERIFY_ARE_EQUAL(ShortcutAction::NewTab, actionAndArgs.Action()); + VERIFY_IS_NOT_NULL(actionAndArgs.Args()); + auto myArgs = actionAndArgs.Args().try_as(); + VERIFY_IS_NOT_NULL(myArgs); + VERIFY_IS_NOT_NULL(myArgs.TerminalArgs()); + VERIFY_IS_TRUE(myArgs.TerminalArgs().Commandline().empty()); + VERIFY_IS_TRUE(myArgs.TerminalArgs().StartingDirectory().empty()); + VERIFY_IS_TRUE(myArgs.TerminalArgs().TabTitle().empty()); + VERIFY_IS_NULL(myArgs.TerminalArgs().TabColor()); + VERIFY_IS_NULL(myArgs.TerminalArgs().ProfileIndex()); + VERIFY_IS_TRUE(myArgs.TerminalArgs().Profile().empty()); + VERIFY_IS_FALSE(myArgs.TerminalArgs().ColorScheme().empty()); + VERIFY_ARE_EQUAL(expectedScheme, myArgs.TerminalArgs().ColorScheme()); } } @@ -749,6 +783,7 @@ namespace TerminalAppLocalTests VERIFY_IS_FALSE(myArgs.TerminalArgs().Profile().empty()); VERIFY_ARE_EQUAL(L"wsl -d Alpine", myArgs.TerminalArgs().Commandline()); VERIFY_ARE_EQUAL(L"1", myArgs.TerminalArgs().Profile()); + VERIFY_IS_TRUE(myArgs.TerminalArgs().ColorScheme().empty()); } { AppCommandlineArgs appArgs{}; @@ -777,6 +812,7 @@ namespace TerminalAppLocalTests VERIFY_IS_FALSE(myArgs.TerminalArgs().Profile().empty()); VERIFY_ARE_EQUAL(L"wsl -d Alpine", myArgs.TerminalArgs().Commandline()); VERIFY_ARE_EQUAL(L"1", myArgs.TerminalArgs().Profile()); + VERIFY_IS_TRUE(myArgs.TerminalArgs().ColorScheme().empty()); } { AppCommandlineArgs appArgs{}; @@ -805,6 +841,7 @@ namespace TerminalAppLocalTests VERIFY_IS_FALSE(myArgs.TerminalArgs().Profile().empty()); VERIFY_ARE_EQUAL(L"wsl -d Alpine -H", myArgs.TerminalArgs().Commandline()); VERIFY_ARE_EQUAL(L"1", myArgs.TerminalArgs().Profile()); + VERIFY_IS_TRUE(myArgs.TerminalArgs().ColorScheme().empty()); } } diff --git a/src/cascadia/TerminalApp/AppCommandlineArgs.cpp b/src/cascadia/TerminalApp/AppCommandlineArgs.cpp index 6e68084e8..978b33abe 100644 --- a/src/cascadia/TerminalApp/AppCommandlineArgs.cpp +++ b/src/cascadia/TerminalApp/AppCommandlineArgs.cpp @@ -422,6 +422,9 @@ void AppCommandlineArgs::_addNewTerminalArgs(AppCommandlineArgs::NewTerminalSubc _suppressApplicationTitle, RS_A(L"CmdSuppressApplicationTitleDesc")); + subcommand.colorSchemeOption = subcommand.subcommand->add_option("--colorScheme", + _startingColorScheme, + RS_A(L"CmdColorSchemeArgDesc")); // Using positionals_at_end allows us to support "wt new-tab -d wsl -d Ubuntu" // without CLI11 thinking that we've specified -d twice. // There's an alternate construction where we make all subcommands "prefix commands", @@ -494,6 +497,11 @@ NewTerminalArgs AppCommandlineArgs::_getNewTerminalArgs(AppCommandlineArgs::NewT args.SuppressApplicationTitle(_suppressApplicationTitle); } + if (*subcommand.colorSchemeOption) + { + args.ColorScheme(winrt::to_hstring(_startingColorScheme)); + } + return args; } diff --git a/src/cascadia/TerminalApp/AppCommandlineArgs.h b/src/cascadia/TerminalApp/AppCommandlineArgs.h index bc3d56f16..a05855134 100644 --- a/src/cascadia/TerminalApp/AppCommandlineArgs.h +++ b/src/cascadia/TerminalApp/AppCommandlineArgs.h @@ -63,6 +63,7 @@ private: CLI::Option* titleOption; CLI::Option* tabColorOption; CLI::Option* suppressApplicationTitleOption; + CLI::Option* colorSchemeOption; }; struct NewPaneSubcommand : public NewTerminalSubcommand @@ -87,6 +88,7 @@ private: std::string _startingDirectory; std::string _startingTitle; std::string _startingTabColor; + std::string _startingColorScheme; bool _suppressApplicationTitle{ false }; winrt::Microsoft::Terminal::Settings::Model::FocusDirection _moveFocusDirection{ winrt::Microsoft::Terminal::Settings::Model::FocusDirection::None }; diff --git a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw index 68dcb0da8..e969a7a68 100644 --- a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw @@ -323,6 +323,10 @@ Open the tab with tabTitle overriding default title and suppressing title change messages from the application {Locked="\"tabTitle\""} + + Open the tab with the specified color scheme, instead of the profile's set "colorScheme" + {Locked="\"colorScheme\""} + Display the application version diff --git a/src/cascadia/TerminalSettingsModel/ActionArgs.cpp b/src/cascadia/TerminalSettingsModel/ActionArgs.cpp index 5401c050f..cf4a4956f 100644 --- a/src/cascadia/TerminalSettingsModel/ActionArgs.cpp +++ b/src/cascadia/TerminalSettingsModel/ActionArgs.cpp @@ -68,6 +68,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation const til::color tabColor{ _TabColor.Value() }; ss << fmt::format(L"tabColor: {}, ", tabColor.ToHexString(true)); } + if (!_ColorScheme.empty()) + { + ss << fmt::format(L"colorScheme: {}, ", _ColorScheme); + } if (_SuppressApplicationTitle) { @@ -135,6 +139,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation } } + if (!_ColorScheme.empty()) + { + ss << fmt::format(L"--colorScheme \"{}\" ", _ColorScheme); + } + if (!_Commandline.empty()) { ss << fmt::format(L"-- \"{}\" ", _Commandline); diff --git a/src/cascadia/TerminalSettingsModel/ActionArgs.h b/src/cascadia/TerminalSettingsModel/ActionArgs.h index c96d08a25..a2a3867bf 100644 --- a/src/cascadia/TerminalSettingsModel/ActionArgs.h +++ b/src/cascadia/TerminalSettingsModel/ActionArgs.h @@ -70,6 +70,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation WINRT_PROPERTY(Windows::Foundation::IReference, ProfileIndex, nullptr); WINRT_PROPERTY(winrt::hstring, Profile, L""); WINRT_PROPERTY(Windows::Foundation::IReference, SuppressApplicationTitle, nullptr); + WINRT_PROPERTY(winrt::hstring, ColorScheme); static constexpr std::string_view CommandlineKey{ "commandline" }; static constexpr std::string_view StartingDirectoryKey{ "startingDirectory" }; @@ -78,6 +79,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation static constexpr std::string_view ProfileIndexKey{ "index" }; static constexpr std::string_view ProfileKey{ "profile" }; static constexpr std::string_view SuppressApplicationTitleKey{ "suppressApplicationTitle" }; + static constexpr std::string_view ColorSchemeKey{ "colorScheme" }; public: hstring GenerateName() const; @@ -91,7 +93,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation other.TabColor() == _TabColor && other.ProfileIndex() == _ProfileIndex && other.Profile() == _Profile && - other.SuppressApplicationTitle() == _SuppressApplicationTitle; + other.SuppressApplicationTitle() == _SuppressApplicationTitle && + other.ColorScheme() == _ColorScheme; }; static Model::NewTerminalArgs FromJson(const Json::Value& json) { @@ -104,6 +107,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation JsonUtils::GetValueForKey(json, ProfileKey, args->_Profile); JsonUtils::GetValueForKey(json, TabColorKey, args->_TabColor); JsonUtils::GetValueForKey(json, SuppressApplicationTitleKey, args->_SuppressApplicationTitle); + JsonUtils::GetValueForKey(json, ColorSchemeKey, args->_ColorScheme); return *args; } Model::NewTerminalArgs Copy() const @@ -116,6 +120,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation copy->_ProfileIndex = _ProfileIndex; copy->_Profile = _Profile; copy->_SuppressApplicationTitle = _SuppressApplicationTitle; + copy->_ColorScheme = _ColorScheme; return *copy; } }; diff --git a/src/cascadia/TerminalSettingsModel/ActionArgs.idl b/src/cascadia/TerminalSettingsModel/ActionArgs.idl index 67b76be7b..7a939c1f1 100644 --- a/src/cascadia/TerminalSettingsModel/ActionArgs.idl +++ b/src/cascadia/TerminalSettingsModel/ActionArgs.idl @@ -100,6 +100,8 @@ namespace Microsoft.Terminal.Settings.Model Windows.Foundation.IReference SuppressApplicationTitle; + String ColorScheme; + Boolean Equals(NewTerminalArgs other); String GenerateName(); String ToCommandline(); diff --git a/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp b/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp index f59d9cb83..77e52c2a2 100644 --- a/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp +++ b/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp @@ -118,6 +118,14 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation { settings.SuppressApplicationTitle(newTerminalArgs.SuppressApplicationTitle().Value()); } + if (!newTerminalArgs.ColorScheme().empty()) + { + const auto schemes = appSettings.GlobalSettings().ColorSchemes(); + if (const auto& scheme = schemes.TryLookup(newTerminalArgs.ColorScheme())) + { + settings.ApplyColorScheme(scheme); + } + } } return settings;