Move commandline->title promotion into TerminalSettings (#11029)
It was insufficient to only promote commandline components to titles during commandline parsing, because we also have a whole complement of actions that contain NewTerminalArgs. The tests caught me out a little too late (sorry!). I decided it was better move promotion down to TerminalSettings. Fixes #6776 Re-implements #10998
This commit is contained in:
parent
f3cc4c0328
commit
7b6df26411
|
@ -42,6 +42,8 @@ namespace SettingsModelLocalTests
|
||||||
|
|
||||||
TEST_METHOD(TestLayerProfileOnColorScheme);
|
TEST_METHOD(TestLayerProfileOnColorScheme);
|
||||||
|
|
||||||
|
TEST_METHOD(TestCommandlineToTitlePromotion);
|
||||||
|
|
||||||
TEST_CLASS_SETUP(ClassSetup)
|
TEST_CLASS_SETUP(ClassSetup)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
@ -554,4 +556,85 @@ namespace SettingsModelLocalTests
|
||||||
VERIFY_ARE_EQUAL(ARGB(0, 0x45, 0x67, 0x89), terminalSettings4->CursorColor()); // from profile (no color scheme)
|
VERIFY_ARE_EQUAL(ARGB(0, 0x45, 0x67, 0x89), terminalSettings4->CursorColor()); // from profile (no color scheme)
|
||||||
VERIFY_ARE_EQUAL(DEFAULT_CURSOR_COLOR, terminalSettings5->CursorColor()); // default
|
VERIFY_ARE_EQUAL(DEFAULT_CURSOR_COLOR, terminalSettings5->CursorColor()); // default
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TerminalSettingsTests::TestCommandlineToTitlePromotion()
|
||||||
|
{
|
||||||
|
const std::string settingsJson{ R"(
|
||||||
|
{
|
||||||
|
"defaultProfile": "{6239a42c-0000-49a3-80bd-e8fdd045185c}",
|
||||||
|
"profiles": { "list": [
|
||||||
|
{
|
||||||
|
"name": "profile0",
|
||||||
|
"guid": "{6239a42c-0000-49a3-80bd-e8fdd045185c}",
|
||||||
|
"historySize": 1,
|
||||||
|
"commandline": "cmd.exe"
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"defaults": {
|
||||||
|
"historySize": 29
|
||||||
|
} }
|
||||||
|
})" };
|
||||||
|
|
||||||
|
const winrt::guid guid0{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-0000-49a3-80bd-e8fdd045185c}") };
|
||||||
|
|
||||||
|
CascadiaSettings settings{ til::u8u16(settingsJson) };
|
||||||
|
|
||||||
|
{ // just a profile (profile wins)
|
||||||
|
NewTerminalArgs args{};
|
||||||
|
args.Profile(L"profile0");
|
||||||
|
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(settings, args, nullptr) };
|
||||||
|
VERIFY_ARE_EQUAL(L"profile0", settingsStruct.DefaultSettings().StartingTitle());
|
||||||
|
}
|
||||||
|
{ // profile and command line -> no promotion (profile wins)
|
||||||
|
NewTerminalArgs args{};
|
||||||
|
args.Profile(L"profile0");
|
||||||
|
args.Commandline(L"foo.exe");
|
||||||
|
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(settings, args, nullptr) };
|
||||||
|
VERIFY_ARE_EQUAL(L"profile0", settingsStruct.DefaultSettings().StartingTitle());
|
||||||
|
}
|
||||||
|
{ // just a title -> it is propagated
|
||||||
|
NewTerminalArgs args{};
|
||||||
|
args.TabTitle(L"Analog Kid");
|
||||||
|
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(settings, args, nullptr) };
|
||||||
|
VERIFY_ARE_EQUAL(L"Analog Kid", settingsStruct.DefaultSettings().StartingTitle());
|
||||||
|
}
|
||||||
|
{ // title and command line -> no promotion
|
||||||
|
NewTerminalArgs args{};
|
||||||
|
args.TabTitle(L"Digital Man");
|
||||||
|
args.Commandline(L"foo.exe");
|
||||||
|
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(settings, args, nullptr) };
|
||||||
|
VERIFY_ARE_EQUAL(L"Digital Man", settingsStruct.DefaultSettings().StartingTitle());
|
||||||
|
}
|
||||||
|
{ // just a commandline -> promotion
|
||||||
|
NewTerminalArgs args{};
|
||||||
|
args.Commandline(L"foo.exe");
|
||||||
|
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(settings, args, nullptr) };
|
||||||
|
VERIFY_ARE_EQUAL(L"foo.exe", settingsStruct.DefaultSettings().StartingTitle());
|
||||||
|
}
|
||||||
|
// various typesof commandline follow
|
||||||
|
{
|
||||||
|
NewTerminalArgs args{};
|
||||||
|
args.Commandline(L"foo.exe bar");
|
||||||
|
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(settings, args, nullptr) };
|
||||||
|
VERIFY_ARE_EQUAL(L"foo.exe", settingsStruct.DefaultSettings().StartingTitle());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
NewTerminalArgs args{};
|
||||||
|
args.Commandline(L"\"foo exe.exe\" bar");
|
||||||
|
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(settings, args, nullptr) };
|
||||||
|
VERIFY_ARE_EQUAL(L"foo exe.exe", settingsStruct.DefaultSettings().StartingTitle());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
NewTerminalArgs args{};
|
||||||
|
args.Commandline(L"\"\" grand designs");
|
||||||
|
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(settings, args, nullptr) };
|
||||||
|
VERIFY_ARE_EQUAL(L"", settingsStruct.DefaultSettings().StartingTitle());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
NewTerminalArgs args{};
|
||||||
|
args.Commandline(L" imagine a man");
|
||||||
|
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(settings, args, nullptr) };
|
||||||
|
VERIFY_ARE_EQUAL(L"", settingsStruct.DefaultSettings().StartingTitle());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -603,13 +603,6 @@ NewTerminalArgs AppCommandlineArgs::_getNewTerminalArgs(AppCommandlineArgs::NewT
|
||||||
args.Profile(winrt::to_hstring(_profileName));
|
args.Profile(winrt::to_hstring(_profileName));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!*subcommand.profileNameOption && !_commandline.empty())
|
|
||||||
{
|
|
||||||
// If there's no profile, but there IS a command line, set the tab title to the first part of the command
|
|
||||||
// This will ensure that the tab we spawn has a name (since it didn't get one from its profile!)
|
|
||||||
args.TabTitle(winrt::to_hstring(til::at(_commandline, 0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*subcommand.startingDirectoryOption)
|
if (*subcommand.startingDirectoryOption)
|
||||||
{
|
{
|
||||||
args.StartingDirectory(winrt::to_hstring(_startingDirectory));
|
args.StartingDirectory(winrt::to_hstring(_startingDirectory));
|
||||||
|
|
|
@ -124,6 +124,21 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||||
{
|
{
|
||||||
defaultSettings.StartingTitle(newTerminalArgs.TabTitle());
|
defaultSettings.StartingTitle(newTerminalArgs.TabTitle());
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// There was no title, and no profile from which to infer the title.
|
||||||
|
// Per GH#6776, promote the first component of the command line to the title.
|
||||||
|
// This will ensure that the tab we spawn has a name (since it didn't get one from its profile!)
|
||||||
|
if (newTerminalArgs.Profile().empty() && !newTerminalArgs.Commandline().empty())
|
||||||
|
{
|
||||||
|
const std::wstring_view commandLine{ newTerminalArgs.Commandline() };
|
||||||
|
const auto start{ til::at(commandLine, 0) == L'"' ? 1 : 0 };
|
||||||
|
const auto terminator{ commandLine.find_first_of(start ? L'"' : L' ', start) }; // look past the first character if it starts with "
|
||||||
|
// We have to take a copy here; winrt::param::hstring requires a null-terminated string
|
||||||
|
const std::wstring firstComponent{ commandLine.substr(start, terminator - start) };
|
||||||
|
defaultSettings.StartingTitle(firstComponent);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (newTerminalArgs.TabColor())
|
if (newTerminalArgs.TabColor())
|
||||||
{
|
{
|
||||||
defaultSettings.StartingTabColor(winrt::Windows::Foundation::IReference<winrt::Microsoft::Terminal::Core::Color>{ til::color{ newTerminalArgs.TabColor().Value() } });
|
defaultSettings.StartingTabColor(winrt::Windows::Foundation::IReference<winrt::Microsoft::Terminal::Core::Color>{ til::color{ newTerminalArgs.TabColor().Value() } });
|
||||||
|
|
Loading…
Reference in a new issue