diff --git a/src/cascadia/LocalTests_TerminalApp/CommandlineTest.cpp b/src/cascadia/LocalTests_TerminalApp/CommandlineTest.cpp index e9d6e74a3..c8423b47a 100644 --- a/src/cascadia/LocalTests_TerminalApp/CommandlineTest.cpp +++ b/src/cascadia/LocalTests_TerminalApp/CommandlineTest.cpp @@ -714,6 +714,7 @@ namespace TerminalAppLocalTests auto myArgs = actionAndArgs.Args().try_as(); VERIFY_IS_NOT_NULL(myArgs); VERIFY_ARE_EQUAL(SplitState::Automatic, myArgs.SplitStyle()); + VERIFY_ARE_EQUAL(SplitType::Manual, myArgs.SplitMode()); VERIFY_IS_NOT_NULL(myArgs.TerminalArgs()); } { @@ -733,6 +734,7 @@ namespace TerminalAppLocalTests auto myArgs = actionAndArgs.Args().try_as(); VERIFY_IS_NOT_NULL(myArgs); VERIFY_ARE_EQUAL(SplitState::Horizontal, myArgs.SplitStyle()); + VERIFY_ARE_EQUAL(SplitType::Manual, myArgs.SplitMode()); VERIFY_IS_NOT_NULL(myArgs.TerminalArgs()); } { @@ -754,6 +756,28 @@ namespace TerminalAppLocalTests auto myArgs = actionAndArgs.Args().try_as(); VERIFY_IS_NOT_NULL(myArgs); VERIFY_ARE_EQUAL(SplitState::Vertical, myArgs.SplitStyle()); + VERIFY_ARE_EQUAL(SplitType::Manual, myArgs.SplitMode()); + VERIFY_IS_NOT_NULL(myArgs.TerminalArgs()); + } + { + AppCommandlineArgs appArgs{}; + std::vector rawCommands{ L"wt.exe", subcommand, L"-D" }; + auto commandlines = AppCommandlineArgs::BuildCommands(rawCommands); + VERIFY_ARE_EQUAL(1u, commandlines.size()); + _buildCommandlinesHelper(appArgs, 1u, rawCommands); + + VERIFY_ARE_EQUAL(2u, appArgs._startupActions.size()); + + // The first action is going to always be a new-tab action + VERIFY_ARE_EQUAL(ShortcutAction::NewTab, appArgs._startupActions.at(0).Action()); + + // The one we actually want to test here is the SplitPane action we created + auto actionAndArgs = appArgs._startupActions.at(1); + VERIFY_ARE_EQUAL(ShortcutAction::SplitPane, actionAndArgs.Action()); + VERIFY_IS_NOT_NULL(actionAndArgs.Args()); + auto myArgs = actionAndArgs.Args().try_as(); + VERIFY_IS_NOT_NULL(myArgs); + VERIFY_ARE_EQUAL(SplitType::Duplicate, myArgs.SplitMode()); VERIFY_IS_NOT_NULL(myArgs.TerminalArgs()); } { diff --git a/src/cascadia/TerminalApp/AppCommandlineArgs.cpp b/src/cascadia/TerminalApp/AppCommandlineArgs.cpp index 978b33abe..129b5aaf7 100644 --- a/src/cascadia/TerminalApp/AppCommandlineArgs.cpp +++ b/src/cascadia/TerminalApp/AppCommandlineArgs.cpp @@ -255,6 +255,10 @@ void AppCommandlineArgs::_buildSplitPaneParser() auto* sizeOpt = subcommand.subcommand->add_option("-s,--size", _splitPaneSize, RS_A(L"CmdSplitPaneSizeArgDesc")); + + subcommand._duplicateOption = subcommand.subcommand->add_flag("-D,--duplicate", + _splitDuplicate, + RS_A(L"CmdSplitPaneDuplicateArgDesc")); sizeOpt->check(CLI::Range(0.01f, 0.99f)); // When ParseCommand is called, if this subcommand was provided, this @@ -283,7 +287,8 @@ void AppCommandlineArgs::_buildSplitPaneParser() style = SplitState::Vertical; } } - SplitPaneArgs args{ style, _splitPaneSize, terminalArgs }; + const auto splitMode{ subcommand._duplicateOption && _splitDuplicate ? SplitType::Duplicate : SplitType::Manual }; + SplitPaneArgs args{ splitMode, style, _splitPaneSize, terminalArgs }; splitPaneActionAndArgs.Args(args); _startupActions.push_back(splitPaneActionAndArgs); }); @@ -545,6 +550,7 @@ void AppCommandlineArgs::_resetStateToDefault() _splitVertical = false; _splitHorizontal = false; _splitPaneSize = 0.5f; + _splitDuplicate = false; _focusTabIndex = -1; _focusNextTab = false; diff --git a/src/cascadia/TerminalApp/AppCommandlineArgs.h b/src/cascadia/TerminalApp/AppCommandlineArgs.h index a05855134..4ec6a1941 100644 --- a/src/cascadia/TerminalApp/AppCommandlineArgs.h +++ b/src/cascadia/TerminalApp/AppCommandlineArgs.h @@ -70,6 +70,7 @@ private: { CLI::Option* _horizontalOption; CLI::Option* _verticalOption; + CLI::Option* _duplicateOption; }; // --- Subcommands --- @@ -98,6 +99,7 @@ private: bool _splitVertical{ false }; bool _splitHorizontal{ false }; + bool _splitDuplicate{ false }; float _splitPaneSize{ 0.5f }; int _focusTabIndex{ -1 }; diff --git a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw index e969a7a68..7942b2df6 100644 --- a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw @@ -308,6 +308,9 @@ Create the new pane as a vertical split (think [|]) + + Create the new pane by duplicating the profile of the focused pane + Open in the given directory instead of the profile's set "startingDirectory" {Locked="\"startingDirectory\""} diff --git a/src/cascadia/TerminalSettingsModel/ActionArgs.h b/src/cascadia/TerminalSettingsModel/ActionArgs.h index a2a3867bf..ef5378190 100644 --- a/src/cascadia/TerminalSettingsModel/ActionArgs.h +++ b/src/cascadia/TerminalSettingsModel/ActionArgs.h @@ -394,6 +394,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation struct SplitPaneArgs : public SplitPaneArgsT { SplitPaneArgs() = default; + SplitPaneArgs(SplitType splitMode, SplitState style, double size, const Model::NewTerminalArgs& terminalArgs) : + _SplitMode{ splitMode }, + _SplitStyle{ style }, + _SplitSize{ size }, + _TerminalArgs{ terminalArgs } {}; SplitPaneArgs(SplitState style, double size, const Model::NewTerminalArgs& terminalArgs) : _SplitStyle{ style }, _SplitSize{ size }, diff --git a/src/cascadia/TerminalSettingsModel/ActionArgs.idl b/src/cascadia/TerminalSettingsModel/ActionArgs.idl index 7a939c1f1..dcfb0219e 100644 --- a/src/cascadia/TerminalSettingsModel/ActionArgs.idl +++ b/src/cascadia/TerminalSettingsModel/ActionArgs.idl @@ -154,6 +154,7 @@ namespace Microsoft.Terminal.Settings.Model [default_interface] runtimeclass SplitPaneArgs : IActionArgs { + SplitPaneArgs(SplitType splitMode, SplitState split, Double size, NewTerminalArgs terminalArgs); SplitPaneArgs(SplitState split, Double size, NewTerminalArgs terminalArgs); SplitPaneArgs(SplitState split, NewTerminalArgs terminalArgs); SplitPaneArgs(SplitType splitMode);