From 06897b7c4bfd5cadef7638b9d1f6454f7f8ce388 Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Tue, 11 Aug 2020 20:24:59 +0200 Subject: [PATCH 1/4] Fixed #3799: Introduce sendInput command --- doc/cascadia/SettingsSchema.md | 1 + doc/cascadia/profiles.schema.json | 24 ++++++++++++++++ src/cascadia/TerminalApp/ActionAndArgs.cpp | 5 ++++ src/cascadia/TerminalApp/ActionArgs.cpp | 11 ++++++++ src/cascadia/TerminalApp/ActionArgs.h | 28 +++++++++++++++++++ src/cascadia/TerminalApp/ActionArgs.idl | 5 ++++ .../TerminalApp/AppActionHandlers.cpp | 15 ++++++++++ .../Resources/en-US/Resources.resw | 3 ++ .../TerminalApp/ShortcutActionDispatch.cpp | 6 ++++ .../TerminalApp/ShortcutActionDispatch.h | 1 + .../TerminalApp/ShortcutActionDispatch.idl | 2 ++ src/cascadia/TerminalApp/TerminalPage.cpp | 1 + src/cascadia/TerminalApp/TerminalPage.h | 1 + src/cascadia/TerminalControl/TermControl.cpp | 14 +++++++++- src/cascadia/TerminalControl/TermControl.h | 3 +- src/cascadia/TerminalControl/TermControl.idl | 1 + 16 files changed, 119 insertions(+), 2 deletions(-) diff --git a/doc/cascadia/SettingsSchema.md b/doc/cascadia/SettingsSchema.md index 9c58edc89f4..66e5cb67113 100644 --- a/doc/cascadia/SettingsSchema.md +++ b/doc/cascadia/SettingsSchema.md @@ -142,6 +142,7 @@ For commands with arguments: | `scrollUp` | Move the screen up. | | | | | `scrollUpPage` | Move the screen up a whole page. | | | | | `scrollDownPage` | Move the screen down a whole page. | | | | +| `sendInput` | Sends some text input to the shell. | `input` | string | The text input to feed into the shell.
ANSI escape sequences may be used. Escape codes like `\x1b` must be written as `\u001b`.
For instance the input `"text\n"` will write "text" followed by a newline. `"\u001b[D"` will behave as if the left arrow button had been pressed. | | `splitPane` | Halve the size of the active pane and open another. Without any arguments, this will open the default profile in the new pane. | 1. `split`*
2. `commandLine`
3. `startingDirectory`
4. `tabTitle`
5. `index`
6. `profile`
7. `splitMode` | 1. `vertical`, `horizontal`, `auto`
2. string
3. string
4. string
5. integer
6. string
7. string | 1. How the pane will split. `auto` will split in the direction that provides the most surface area.
2. Executable run within the pane.
3. Directory in which the pane will open.
4. Title of the tab when the new pane is focused.
5. Profile that will open based on its position in the dropdown (starting at 0).
6. Profile that will open based on its GUID or name.
7. Controls how the pane splits. Only accepts `duplicate` which will duplicate the focused pane's profile into a new pane. | | `switchToTab` | Open a specific tab depending on index. | `index`* | integer | Tab that will open based on its position in the tab bar (starting at 0). | | `toggleFullscreen` | Switch between fullscreen and default window sizes. | | | | diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index f1e1843bf96..e2253724a54 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -52,6 +52,7 @@ "scrollDownPage", "scrollUp", "scrollUpPage", + "sendInput", "splitPane", "switchToTab", "toggleFocusMode", @@ -230,6 +231,28 @@ ], "required": [ "direction" ] }, + "SendInputAction": { + "description": "Arguments corresponding to a Send Input Action", + "allOf": [ + { + "$ref": "#/definitions/ShortcutAction" + }, + { + "properties": { + "action": { + "type": "string", + "pattern": "sendInput" + }, + "input": { + "type": "string", + "default": "", + "description": "The text input to feed into the shell. ANSI escape sequences may be used. Escape codes like \\x1b must be written as \\u001b." + } + } + } + ], + "required": [ "input" ] + }, "SplitPaneAction": { "description": "Arguments corresponding to a Split Pane Action", "allOf": [ @@ -390,6 +413,7 @@ { "$ref": "#/definitions/SwitchToTabAction" }, { "$ref": "#/definitions/MoveFocusAction" }, { "$ref": "#/definitions/ResizePaneAction" }, + { "$ref": "#/definitions/SendInputAction" }, { "$ref": "#/definitions/SplitPaneAction" }, { "$ref": "#/definitions/OpenSettingsAction" }, { "$ref": "#/definitions/SetTabColorAction" }, diff --git a/src/cascadia/TerminalApp/ActionAndArgs.cpp b/src/cascadia/TerminalApp/ActionAndArgs.cpp index fadadac3b24..1d6d03cbc35 100644 --- a/src/cascadia/TerminalApp/ActionAndArgs.cpp +++ b/src/cascadia/TerminalApp/ActionAndArgs.cpp @@ -27,6 +27,7 @@ static constexpr std::string_view ScrolluppageKey{ "scrollUpPage" }; static constexpr std::string_view ScrolldownpageKey{ "scrollDownPage" }; static constexpr std::string_view SwitchToTabKey{ "switchToTab" }; static constexpr std::string_view OpenSettingsKey{ "openSettings" }; // TODO GH#2557: Add args for OpenSettings +static constexpr std::string_view SendInputKey{ "sendInput" }; static constexpr std::string_view SplitPaneKey{ "splitPane" }; static constexpr std::string_view TogglePaneZoomKey{ "togglePaneZoom" }; static constexpr std::string_view ResizePaneKey{ "resizePane" }; @@ -90,6 +91,7 @@ namespace winrt::TerminalApp::implementation { ToggleFocusModeKey, ShortcutAction::ToggleFocusMode }, { ToggleFullscreenKey, ShortcutAction::ToggleFullscreen }, { ToggleAlwaysOnTopKey, ShortcutAction::ToggleAlwaysOnTop }, + { SendInputKey, ShortcutAction::SendInput }, { SplitPaneKey, ShortcutAction::SplitPane }, { TogglePaneZoomKey, ShortcutAction::TogglePaneZoom }, { SetTabColorKey, ShortcutAction::SetTabColor }, @@ -125,6 +127,8 @@ namespace winrt::TerminalApp::implementation { ShortcutAction::AdjustFontSize, winrt::TerminalApp::implementation::AdjustFontSizeArgs::FromJson }, + { ShortcutAction::SendInput, winrt::TerminalApp::implementation::SendInputArgs::FromJson }, + { ShortcutAction::SplitPane, winrt::TerminalApp::implementation::SplitPaneArgs::FromJson }, { ShortcutAction::OpenSettings, winrt::TerminalApp::implementation::OpenSettingsArgs::FromJson }, @@ -284,6 +288,7 @@ namespace winrt::TerminalApp::implementation { ShortcutAction::ToggleFocusMode, RS_(L"ToggleFocusModeCommandKey") }, { ShortcutAction::ToggleFullscreen, RS_(L"ToggleFullscreenCommandKey") }, { ShortcutAction::ToggleAlwaysOnTop, RS_(L"ToggleAlwaysOnTopCommandKey") }, + { ShortcutAction::SendInput, RS_(L"SendInputCommandKey") }, { ShortcutAction::SplitPane, RS_(L"SplitPaneCommandKey") }, { ShortcutAction::TogglePaneZoom, RS_(L"TogglePaneZoomCommandKey") }, { ShortcutAction::Invalid, L"" }, diff --git a/src/cascadia/TerminalApp/ActionArgs.cpp b/src/cascadia/TerminalApp/ActionArgs.cpp index d6e7219fd13..59fab9a9199 100644 --- a/src/cascadia/TerminalApp/ActionArgs.cpp +++ b/src/cascadia/TerminalApp/ActionArgs.cpp @@ -13,6 +13,7 @@ #include "ResizePaneArgs.g.cpp" #include "MoveFocusArgs.g.cpp" #include "AdjustFontSizeArgs.g.cpp" +#include "SendInputArgs.g.cpp" #include "SplitPaneArgs.g.cpp" #include "OpenSettingsArgs.g.cpp" #include "SetColorSchemeArgs.g.cpp" @@ -167,6 +168,16 @@ namespace winrt::TerminalApp::implementation } } + winrt::hstring SendInputArgs::GenerateName() const + { + // The string will be similar to the following: + // * "Send Input: ...input..." + + return winrt::hstring{ + fmt::format(L"{}: {}", RS_(L"SendInputCommandKey"), _Input) + }; + } + winrt::hstring SplitPaneArgs::GenerateName() const { // The string will be similar to the following: diff --git a/src/cascadia/TerminalApp/ActionArgs.h b/src/cascadia/TerminalApp/ActionArgs.h index 7c768d58054..c2cf498b82e 100644 --- a/src/cascadia/TerminalApp/ActionArgs.h +++ b/src/cascadia/TerminalApp/ActionArgs.h @@ -13,6 +13,7 @@ #include "ResizePaneArgs.g.h" #include "MoveFocusArgs.g.h" #include "AdjustFontSizeArgs.g.h" +#include "SendInputArgs.g.h" #include "SplitPaneArgs.g.h" #include "OpenSettingsArgs.g.h" #include "SetColorSchemeArgs.g.h" @@ -270,6 +271,33 @@ namespace winrt::TerminalApp::implementation } }; + struct SendInputArgs : public SendInputArgsT + { + SendInputArgs() = default; + GETSET_PROPERTY(winrt::hstring, Input, L""); + + static constexpr std::string_view InputKey{ "input" }; + + public: + hstring GenerateName() const; + + bool Equals(const IActionArgs& other) + { + if (auto otherAsUs = other.try_as(); otherAsUs) + { + return otherAsUs->_Input == _Input; + } + return false; + }; + static FromJsonResult FromJson(const Json::Value& json) + { + // LOAD BEARING: Not using make_self here _will_ break you in the future! + auto args = winrt::make_self(); + JsonUtils::GetValueForKey(json, InputKey, args->_Input); + return { *args, {} }; + } + }; + struct SplitPaneArgs : public SplitPaneArgsT { SplitPaneArgs() = default; diff --git a/src/cascadia/TerminalApp/ActionArgs.idl b/src/cascadia/TerminalApp/ActionArgs.idl index a460d712a92..ee50771eb94 100644 --- a/src/cascadia/TerminalApp/ActionArgs.idl +++ b/src/cascadia/TerminalApp/ActionArgs.idl @@ -94,6 +94,11 @@ namespace TerminalApp Int32 Delta { get; }; }; + [default_interface] runtimeclass SendInputArgs : IActionArgs + { + String Input { get; }; + }; + [default_interface] runtimeclass SplitPaneArgs : IActionArgs { SplitState SplitStyle { get; }; diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index 19a8c44f2ad..80a06e733de 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -89,6 +89,21 @@ namespace winrt::TerminalApp::implementation args.Handled(true); } + void TerminalPage::_HandleSendInput(const IInspectable& /*sender*/, + const TerminalApp::ActionEventArgs& args) + { + if (args == nullptr) + { + args.Handled(false); + } + else if (const auto& realArgs = args.ActionArgs().try_as()) + { + const auto termControl = _GetActiveControl(); + termControl.SendInput(realArgs.Input()); + args.Handled(true); + } + } + void TerminalPage::_HandleSplitPane(const IInspectable& /*sender*/, const TerminalApp::ActionEventArgs& args) { diff --git a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw index c891d53df6a..d010b10197f 100644 --- a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw @@ -449,6 +449,9 @@ New tab + + Send Input + Split pane diff --git a/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp b/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp index e8b9eb778c4..20a43791c2d 100644 --- a/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp +++ b/src/cascadia/TerminalApp/ShortcutActionDispatch.cpp @@ -113,6 +113,12 @@ namespace winrt::TerminalApp::implementation break; } + case ShortcutAction::SendInput: + { + _SendInputHandlers(*this, *eventArgs); + break; + } + case ShortcutAction::SplitVertical: case ShortcutAction::SplitHorizontal: case ShortcutAction::SplitPane: diff --git a/src/cascadia/TerminalApp/ShortcutActionDispatch.h b/src/cascadia/TerminalApp/ShortcutActionDispatch.h index fa139848e63..9da3aadcdf2 100644 --- a/src/cascadia/TerminalApp/ShortcutActionDispatch.h +++ b/src/cascadia/TerminalApp/ShortcutActionDispatch.h @@ -35,6 +35,7 @@ namespace winrt::TerminalApp::implementation TYPED_EVENT(SwitchToTab, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); TYPED_EVENT(NextTab, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); TYPED_EVENT(PrevTab, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); + TYPED_EVENT(SendInput, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); TYPED_EVENT(SplitPane, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); TYPED_EVENT(TogglePaneZoom, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); TYPED_EVENT(AdjustFontSize, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs); diff --git a/src/cascadia/TerminalApp/ShortcutActionDispatch.idl b/src/cascadia/TerminalApp/ShortcutActionDispatch.idl index b0341d4bf81..e13c0433565 100644 --- a/src/cascadia/TerminalApp/ShortcutActionDispatch.idl +++ b/src/cascadia/TerminalApp/ShortcutActionDispatch.idl @@ -20,6 +20,7 @@ namespace TerminalApp PrevTab, SplitVertical, SplitHorizontal, + SendInput, SplitPane, TogglePaneZoom, SwitchToTab, @@ -71,6 +72,7 @@ namespace TerminalApp event Windows.Foundation.TypedEventHandler SwitchToTab; event Windows.Foundation.TypedEventHandler NextTab; event Windows.Foundation.TypedEventHandler PrevTab; + event Windows.Foundation.TypedEventHandler SendInput; event Windows.Foundation.TypedEventHandler SplitPane; event Windows.Foundation.TypedEventHandler TogglePaneZoom; event Windows.Foundation.TypedEventHandler AdjustFontSize; diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 3838e4ccf50..22547b2e005 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -889,6 +889,7 @@ namespace winrt::TerminalApp::implementation _actionDispatch->ScrollDown({ this, &TerminalPage::_HandleScrollDown }); _actionDispatch->NextTab({ this, &TerminalPage::_HandleNextTab }); _actionDispatch->PrevTab({ this, &TerminalPage::_HandlePrevTab }); + _actionDispatch->SendInput({ this, &TerminalPage::_HandleSendInput }); _actionDispatch->SplitPane({ this, &TerminalPage::_HandleSplitPane }); _actionDispatch->TogglePaneZoom({ this, &TerminalPage::_HandleTogglePaneZoom }); _actionDispatch->ScrollUpPage({ this, &TerminalPage::_HandleScrollUpPage }); diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 984f1064245..d89f96ca931 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -203,6 +203,7 @@ namespace winrt::TerminalApp::implementation void _HandleScrollDown(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); void _HandleNextTab(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); void _HandlePrevTab(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); + void _HandleSendInput(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); void _HandleSplitPane(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); void _HandleTogglePaneZoom(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); void _HandleScrollUpPage(const IInspectable& sender, const TerminalApp::ActionEventArgs& args); diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index 245413fe75c..6a73943062b 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -296,6 +296,18 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation } } } + + // Method Description: + // - Writes the given sequence as input to the active terminal connection, + // Arguments: + // - wstr: the string of characters to write to the terminal connection. + // Return Value: + // - + void TermControl::SendInput(const winrt::hstring& input) + { + _SendInputToConnection(input); + } + void TermControl::ToggleRetroEffect() { auto lock = _terminal->LockForWriting(); @@ -1769,7 +1781,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation // - wstr: the string of characters to write to the terminal connection. // Return Value: // - - void TermControl::_SendInputToConnection(const std::wstring& wstr) + void TermControl::_SendInputToConnection(const winrt::param::hstring& wstr) { _connection.WriteInput(wstr); } diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index a3f26712962..174c3cf4f41 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -81,6 +81,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation void AdjustFontSize(int fontSizeDelta); void ResetFontSize(); + void SendInput(const winrt::hstring& input); void ToggleRetroEffect(); winrt::fire_and_forget RenderEngineSwapChainChanged(); @@ -221,7 +222,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation void _CursorTimerTick(Windows::Foundation::IInspectable const& sender, Windows::Foundation::IInspectable const& e); void _SetEndSelectionPointAtCursor(Windows::Foundation::Point const& cursorPosition); - void _SendInputToConnection(const std::wstring& wstr); + void _SendInputToConnection(const winrt::param::hstring& wstr); void _SendPastedTextToConnection(const std::wstring& wstr); void _SwapChainSizeChanged(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::SizeChangedEventArgs const& e); void _SwapChainScaleChanged(Windows::UI::Xaml::Controls::SwapChainPanel const& sender, Windows::Foundation::IInspectable const& args); diff --git a/src/cascadia/TerminalControl/TermControl.idl b/src/cascadia/TerminalControl/TermControl.idl index 85b6e602cfd..4e3eefa0c44 100644 --- a/src/cascadia/TerminalControl/TermControl.idl +++ b/src/cascadia/TerminalControl/TermControl.idl @@ -71,6 +71,7 @@ namespace Microsoft.Terminal.TerminalControl void AdjustFontSize(Int32 fontSizeDelta); void ResetFontSize(); + void SendInput(String input); void ToggleRetroEffect(); Windows.Foundation.IReference TabColor { get; }; From 01c9dce97cffb757df376693e87f290bec874f14 Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Tue, 11 Aug 2020 21:03:33 +0200 Subject: [PATCH 2/4] Addressed review comments --- src/cascadia/TerminalApp/ActionArgs.h | 4 ++++ src/cascadia/TerminalControl/TermControl.cpp | 14 ++++++++++---- src/cascadia/TerminalControl/TermControl.h | 3 ++- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/cascadia/TerminalApp/ActionArgs.h b/src/cascadia/TerminalApp/ActionArgs.h index c2cf498b82e..d52cc3f4494 100644 --- a/src/cascadia/TerminalApp/ActionArgs.h +++ b/src/cascadia/TerminalApp/ActionArgs.h @@ -294,6 +294,10 @@ namespace winrt::TerminalApp::implementation // LOAD BEARING: Not using make_self here _will_ break you in the future! auto args = winrt::make_self(); JsonUtils::GetValueForKey(json, InputKey, args->_Input); + if (args->_Input.empty()) + { + return { nullptr, { ::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter } }; + } return { *args, {} }; } }; diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index 6a73943062b..b0cff98901c 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -303,9 +303,9 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation // - wstr: the string of characters to write to the terminal connection. // Return Value: // - - void TermControl::SendInput(const winrt::hstring& input) + void TermControl::SendInput(const winrt::hstring& wstr) { - _SendInputToConnection(input); + _SendInputToConnection(wstr); } void TermControl::ToggleRetroEffect() @@ -1776,12 +1776,18 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation } // Method Description: - // - Writes the given sequence as input to the active terminal connection, + // - Writes the given sequence as input to the active terminal connection. + // - This method has been overloaded to allow zero-copy winrt::param::hstring optimizations. // Arguments: // - wstr: the string of characters to write to the terminal connection. // Return Value: // - - void TermControl::_SendInputToConnection(const winrt::param::hstring& wstr) + void TermControl::_SendInputToConnection(const winrt::hstring& wstr) + { + _connection.WriteInput(wstr); + } + + void TermControl::_SendInputToConnection(std::wstring_view wstr) { _connection.WriteInput(wstr); } diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index 174c3cf4f41..b34ea7b813c 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -222,7 +222,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation void _CursorTimerTick(Windows::Foundation::IInspectable const& sender, Windows::Foundation::IInspectable const& e); void _SetEndSelectionPointAtCursor(Windows::Foundation::Point const& cursorPosition); - void _SendInputToConnection(const winrt::param::hstring& wstr); + void _SendInputToConnection(const winrt::hstring& wstr); + void _SendInputToConnection(std::wstring_view wstr); void _SendPastedTextToConnection(const std::wstring& wstr); void _SwapChainSizeChanged(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::SizeChangedEventArgs const& e); void _SwapChainScaleChanged(Windows::UI::Xaml::Controls::SwapChainPanel const& sender, Windows::Foundation::IInspectable const& args); From 3cb7b82678630e21d49ac292b18deeffe1490430 Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Tue, 11 Aug 2020 22:49:46 +0200 Subject: [PATCH 3/4] Addressed review comments --- src/cascadia/TerminalApp/ActionAndArgs.cpp | 2 +- src/cascadia/TerminalApp/ActionArgs.cpp | 8 +++--- .../TerminalApp/DebugTapConnection.cpp | 26 +++---------------- .../Resources/en-US/Resources.resw | 3 ++- src/cascadia/TerminalApp/Utils.cpp | 25 ++++++++++++++++++ src/cascadia/TerminalApp/Utils.h | 6 +++++ .../TerminalApp/lib/TerminalAppLib.vcxproj | 1 + .../lib/TerminalAppLib.vcxproj.filters | 3 ++- src/cascadia/TerminalControl/TermControl.cpp | 5 ++-- 9 files changed, 48 insertions(+), 31 deletions(-) create mode 100644 src/cascadia/TerminalApp/Utils.cpp diff --git a/src/cascadia/TerminalApp/ActionAndArgs.cpp b/src/cascadia/TerminalApp/ActionAndArgs.cpp index 1d6d03cbc35..150a31c92ea 100644 --- a/src/cascadia/TerminalApp/ActionAndArgs.cpp +++ b/src/cascadia/TerminalApp/ActionAndArgs.cpp @@ -288,7 +288,7 @@ namespace winrt::TerminalApp::implementation { ShortcutAction::ToggleFocusMode, RS_(L"ToggleFocusModeCommandKey") }, { ShortcutAction::ToggleFullscreen, RS_(L"ToggleFullscreenCommandKey") }, { ShortcutAction::ToggleAlwaysOnTop, RS_(L"ToggleAlwaysOnTopCommandKey") }, - { ShortcutAction::SendInput, RS_(L"SendInputCommandKey") }, + { ShortcutAction::SendInput, L"" }, { ShortcutAction::SplitPane, RS_(L"SplitPaneCommandKey") }, { ShortcutAction::TogglePaneZoom, RS_(L"TogglePaneZoomCommandKey") }, { ShortcutAction::Invalid, L"" }, diff --git a/src/cascadia/TerminalApp/ActionArgs.cpp b/src/cascadia/TerminalApp/ActionArgs.cpp index 59fab9a9199..4e1e2f6258b 100644 --- a/src/cascadia/TerminalApp/ActionArgs.cpp +++ b/src/cascadia/TerminalApp/ActionArgs.cpp @@ -22,6 +22,8 @@ #include "ExecuteCommandlineArgs.g.cpp" #include "ToggleTabSwitcherArgs.g.h" +#include "Utils.h" + #include namespace winrt::TerminalApp::implementation @@ -173,9 +175,9 @@ namespace winrt::TerminalApp::implementation // The string will be similar to the following: // * "Send Input: ...input..." - return winrt::hstring{ - fmt::format(L"{}: {}", RS_(L"SendInputCommandKey"), _Input) - }; + auto escapedInput = VisualizeControlCodes(_Input); + auto name = fmt::format(std::wstring_view(RS_(L"SendInputCommandKey")), escapedInput); + return winrt::hstring{name}; } winrt::hstring SplitPaneArgs::GenerateName() const diff --git a/src/cascadia/TerminalApp/DebugTapConnection.cpp b/src/cascadia/TerminalApp/DebugTapConnection.cpp index 21994920ecd..d149ad46213 100644 --- a/src/cascadia/TerminalApp/DebugTapConnection.cpp +++ b/src/cascadia/TerminalApp/DebugTapConnection.cpp @@ -3,6 +3,7 @@ #include "pch.h" #include "DebugTapConnection.h" +#include "Utils.h" using namespace ::winrt::Microsoft::Terminal::TerminalConnection; using namespace ::winrt::Windows::Foundation; @@ -91,36 +92,15 @@ namespace winrt::Microsoft::TerminalApp::implementation return ConnectionState::Failed; } - static std::wstring _sanitizeString(const std::wstring_view str) - { - std::wstring newString{ str.begin(), str.end() }; - for (auto& ch : newString) - { - if (ch < 0x20) - { - ch += 0x2400; - } - else if (ch == 0x20) - { - ch = 0x2423; // replace space with ␣ - } - else if (ch == 0x7f) - { - ch = 0x2421; // replace del with ␡ - } - } - return newString; - } - void DebugTapConnection::_OutputHandler(const hstring str) { - _TerminalOutputHandlers(_sanitizeString(str)); + _TerminalOutputHandlers(VisualizeControlCodes(str)); } // Called by the DebugInputTapConnection to print user input void DebugTapConnection::_PrintInput(const hstring& str) { - auto clean{ _sanitizeString(str) }; + auto clean{ VisualizeControlCodes(str) }; auto formatted{ wil::str_printf(L"\x1b[91m%ls\x1b[m", clean.data()) }; _TerminalOutputHandlers(formatted); } diff --git a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw index d010b10197f..c8951fac9f2 100644 --- a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw @@ -450,7 +450,8 @@ New tab - Send Input + Send Input: "{0}" + {0} will be replaced with a string of input as defined by the user Split pane diff --git a/src/cascadia/TerminalApp/Utils.cpp b/src/cascadia/TerminalApp/Utils.cpp new file mode 100644 index 00000000000..46f07b9bd93 --- /dev/null +++ b/src/cascadia/TerminalApp/Utils.cpp @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation +// Licensed under the MIT license. + +#include "pch.h" +#include "Utils.h" + +std::wstring VisualizeControlCodes(std::wstring str) noexcept +{ + for (auto& ch : str) + { + if (ch < 0x20) + { + ch += 0x2400; + } + else if (ch == 0x20) + { + ch = 0x2423; // replace space with ␣ + } + else if (ch == 0x7f) + { + ch = 0x2421; // replace del with ␡ + } + } + return str; +} diff --git a/src/cascadia/TerminalApp/Utils.h b/src/cascadia/TerminalApp/Utils.h index cb23bac450d..835b07f1672 100644 --- a/src/cascadia/TerminalApp/Utils.h +++ b/src/cascadia/TerminalApp/Utils.h @@ -115,3 +115,9 @@ TIconSource GetColoredIcon(const winrt::hstring& path) return nullptr; } + +std::wstring VisualizeControlCodes(std::wstring str) noexcept; + +inline std::wstring VisualizeControlCodes(std::wstring_view str) noexcept { + return VisualizeControlCodes(std::wstring{ str }); +} diff --git a/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj b/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj index f3c98e58e4e..aecf0ef0847 100644 --- a/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj +++ b/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj @@ -189,6 +189,7 @@ + ../TerminalSettings.idl diff --git a/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj.filters b/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj.filters index fea379bc66c..9a80a146c43 100644 --- a/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj.filters +++ b/src/cascadia/TerminalApp/lib/TerminalAppLib.vcxproj.filters @@ -59,6 +59,7 @@ + settings @@ -202,4 +203,4 @@ app - \ No newline at end of file + diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index b0cff98901c..058e478bc72 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -104,8 +104,9 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation }; _connectionOutputEventToken = _connection.TerminalOutput(onReceiveOutputFn); - auto inputFn = std::bind(&TermControl::_SendInputToConnection, this, std::placeholders::_1); - _terminal->SetWriteInputCallback(inputFn); + _terminal->SetWriteInputCallback([this](std::wstring& wstr) { + _SendInputToConnection(wstr); + }); _terminal->UpdateSettings(settings); From 6c4f58d5df3f8ead8127f79fa6f1d656e9ed2cbb Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Tue, 11 Aug 2020 22:54:11 +0200 Subject: [PATCH 4/4] Addressed review comments --- src/cascadia/TerminalApp/ActionArgs.cpp | 2 +- src/cascadia/TerminalApp/Utils.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cascadia/TerminalApp/ActionArgs.cpp b/src/cascadia/TerminalApp/ActionArgs.cpp index 4e1e2f6258b..1bc3983481d 100644 --- a/src/cascadia/TerminalApp/ActionArgs.cpp +++ b/src/cascadia/TerminalApp/ActionArgs.cpp @@ -177,7 +177,7 @@ namespace winrt::TerminalApp::implementation auto escapedInput = VisualizeControlCodes(_Input); auto name = fmt::format(std::wstring_view(RS_(L"SendInputCommandKey")), escapedInput); - return winrt::hstring{name}; + return winrt::hstring{ name }; } winrt::hstring SplitPaneArgs::GenerateName() const diff --git a/src/cascadia/TerminalApp/Utils.h b/src/cascadia/TerminalApp/Utils.h index 835b07f1672..91915804139 100644 --- a/src/cascadia/TerminalApp/Utils.h +++ b/src/cascadia/TerminalApp/Utils.h @@ -118,6 +118,7 @@ TIconSource GetColoredIcon(const winrt::hstring& path) std::wstring VisualizeControlCodes(std::wstring str) noexcept; -inline std::wstring VisualizeControlCodes(std::wstring_view str) noexcept { +inline std::wstring VisualizeControlCodes(std::wstring_view str) noexcept +{ return VisualizeControlCodes(std::wstring{ str }); }