diff --git a/src/cascadia/TerminalApp/App.cpp b/src/cascadia/TerminalApp/App.cpp index 3caf46163..21c0ceebc 100644 --- a/src/cascadia/TerminalApp/App.cpp +++ b/src/cascadia/TerminalApp/App.cpp @@ -503,6 +503,8 @@ namespace winrt::TerminalApp::implementation bindings.ScrollDownPage([this]() { _ScrollPage(1); }); bindings.SwitchToTab([this](const auto index) { _SelectTab({ index }); }); bindings.OpenSettings([this]() { _OpenSettings(); }); + bindings.CopyText([this](const auto trimWhitespace) { _CopyText(trimWhitespace); }); + bindings.PasteText([this]() { _PasteText(); }); } // Method Description: @@ -1015,6 +1017,14 @@ namespace winrt::TerminalApp::implementation control.CopySelectionToClipboard(trimTrailingWhitespace); } + // Method Description: + // - Paste text from the Windows Clipboard to the focused terminal + void App::_PasteText() + { + const auto control = _GetFocusedControl(); + control.PasteTextFromClipboard(); + } + // Method Description: // - Sets focus to the tab to the right or left the currently selected tab. void App::_SelectNextTab(const bool bMoveRight) diff --git a/src/cascadia/TerminalApp/App.h b/src/cascadia/TerminalApp/App.h index 253673d36..ba7e534f0 100644 --- a/src/cascadia/TerminalApp/App.h +++ b/src/cascadia/TerminalApp/App.h @@ -112,9 +112,11 @@ namespace winrt::TerminalApp::implementation void _Scroll(int delta); void _CopyText(const bool trimTrailingWhitespace); + void _PasteText(); void _SplitVertical(const std::optional& profileGuid); void _SplitHorizontal(const std::optional& profileGuid); void _SplitPane(const Pane::SplitState splitType, const std::optional& profileGuid); + // Todo: add more event implementations here // MSFT:20641986: Add keybindings for New Window void _ScrollPage(int delta); diff --git a/src/cascadia/TerminalApp/AppKeyBindings.cpp b/src/cascadia/TerminalApp/AppKeyBindings.cpp index 9430d9f95..0bcb709f1 100644 --- a/src/cascadia/TerminalApp/AppKeyBindings.cpp +++ b/src/cascadia/TerminalApp/AppKeyBindings.cpp @@ -47,7 +47,10 @@ namespace winrt::TerminalApp::implementation switch (action) { case ShortcutAction::CopyText: - _CopyTextHandlers(); + _CopyTextHandlers(true); + return true; + case ShortcutAction::CopyTextWithoutNewlines: + _CopyTextHandlers(false); return true; case ShortcutAction::PasteText: _PasteTextHandlers(); diff --git a/src/cascadia/TerminalApp/AppKeyBindings.idl b/src/cascadia/TerminalApp/AppKeyBindings.idl index 1e91de4ed..76affdf94 100644 --- a/src/cascadia/TerminalApp/AppKeyBindings.idl +++ b/src/cascadia/TerminalApp/AppKeyBindings.idl @@ -6,6 +6,7 @@ namespace TerminalApp enum ShortcutAction { CopyText = 0, + CopyTextWithoutNewlines, PasteText, NewTab, NewTabProfile0, @@ -42,7 +43,7 @@ namespace TerminalApp OpenSettings }; - delegate void CopyTextEventArgs(); + delegate void CopyTextEventArgs(Boolean trimWhitespace); delegate void PasteTextEventArgs(); delegate void NewTabEventArgs(); delegate void NewTabWithProfileEventArgs(Int32 profileIndex); diff --git a/src/cascadia/TerminalApp/AppKeyBindingsSerialization.cpp b/src/cascadia/TerminalApp/AppKeyBindingsSerialization.cpp index ce7fbb6dc..8b355799e 100644 --- a/src/cascadia/TerminalApp/AppKeyBindingsSerialization.cpp +++ b/src/cascadia/TerminalApp/AppKeyBindingsSerialization.cpp @@ -14,6 +14,7 @@ static constexpr std::string_view KeysKey{ "keys" }; static constexpr std::string_view CommandKey{ "command" }; static constexpr std::string_view CopyTextKey{ "copy" }; +static constexpr std::string_view CopyTextWithoutNewlinesKey{ "copyTextWithoutNewlines" }; static constexpr std::string_view PasteTextKey{ "paste" }; static constexpr std::string_view NewTabKey{ "newTab" }; static constexpr std::string_view NewTabWithProfile0Key{ "newTabProfile0" }; @@ -60,6 +61,7 @@ static constexpr std::string_view SplitVerticalKey{ "splitVertical" }; // about here. static const std::map> commandNames{ { CopyTextKey, ShortcutAction::CopyText }, + { CopyTextWithoutNewlinesKey, ShortcutAction::CopyTextWithoutNewlines }, { PasteTextKey, ShortcutAction::PasteText }, { NewTabKey, ShortcutAction::NewTab }, { NewTabWithProfile0Key, ShortcutAction::NewTabProfile0 }, diff --git a/src/cascadia/TerminalApp/CascadiaSettings.cpp b/src/cascadia/TerminalApp/CascadiaSettings.cpp index e778d226d..a0d591d4d 100644 --- a/src/cascadia/TerminalApp/CascadiaSettings.cpp +++ b/src/cascadia/TerminalApp/CascadiaSettings.cpp @@ -257,6 +257,15 @@ void CascadiaSettings::_CreateDefaultKeybindings() keyBindings.SetKeyBinding(ShortcutAction::CloseTab, KeyChord{ KeyModifiers::Ctrl, static_cast('W') }); + + keyBindings.SetKeyBinding(ShortcutAction::CopyText, + KeyChord{ KeyModifiers::Ctrl | KeyModifiers::Shift, + static_cast('C') }); + + keyBindings.SetKeyBinding(ShortcutAction::PasteText, + KeyChord{ KeyModifiers::Ctrl | KeyModifiers::Shift, + static_cast('V') }); + keyBindings.SetKeyBinding(ShortcutAction::OpenSettings, KeyChord{ KeyModifiers::Ctrl, VK_OEM_COMMA }); diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index ecd1ef130..103e22ed6 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -721,13 +721,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation // paste selection, otherwise else { - // attach TermControl::_SendInputToConnection() as the clipboardDataHandler. - // This is called when the clipboard data is loaded. - auto clipboardDataHandler = std::bind(&TermControl::_SendInputToConnection, this, std::placeholders::_1); - auto pasteArgs = winrt::make_self(clipboardDataHandler); - - // send paste event up to TermApp - _clipboardPasteHandlers(*this, *pasteArgs); + PasteTextFromClipboard(); } } } @@ -1209,6 +1203,19 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation _clipboardCopyHandlers(copiedData); } + // Method Description: + // - Initiate a paste operation. + void TermControl::PasteTextFromClipboard() + { + // attach TermControl::_SendInputToConnection() as the clipboardDataHandler. + // This is called when the clipboard data is loaded. + auto clipboardDataHandler = std::bind(&TermControl::_SendInputToConnection, this, std::placeholders::_1); + auto pasteArgs = winrt::make_self(clipboardDataHandler); + + // send paste event up to TermApp + _clipboardPasteHandlers(*this, *pasteArgs); + } + void TermControl::Close() { if (!_closing.exchange(true)) diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index f473c4753..0cd1a921c 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -41,6 +41,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation hstring Title(); void CopySelectionToClipboard(bool trimTrailingWhitespace); + void PasteTextFromClipboard(); void Close(); bool ShouldCloseOnExit() const noexcept; diff --git a/src/cascadia/TerminalControl/TermControl.idl b/src/cascadia/TerminalControl/TermControl.idl index c098fe339..790457b6f 100644 --- a/src/cascadia/TerminalControl/TermControl.idl +++ b/src/cascadia/TerminalControl/TermControl.idl @@ -32,6 +32,7 @@ namespace Microsoft.Terminal.TerminalControl String Title { get; }; void CopySelectionToClipboard(Boolean trimTrailingWhitespace); + void PasteTextFromClipboard(); void Close(); Boolean ShouldCloseOnExit { get; };