From 11e7bbc1f319093d80b0bb35b9b658bc9a95b4cb Mon Sep 17 00:00:00 2001 From: Carlos Zamora Date: Wed, 31 Aug 2022 12:06:05 -0700 Subject: [PATCH] Introduce ExpandSelectionToWord action (#13765) ## Summary of the Pull Request Introduces a new action `expandSelectionToWord()` which expands the beginning and end of the selection to encompass the word(s) it's on. This was implemented as a conditional keybinding where the key chord is passed through to the terminal if no selection is active (similar to `copy()`). It is not bound to anything by default. ## PR Checklist * [x] Closes #8274 * [x] Schema updated. ## Validation Steps Performed - Scenario in #8274: - search for some text in the find dialog - ESC to close the dialog - execute `expandSelectionToWord()` - the new selection encompasses the whole word - mark mode - move onto a word - execute `expandSelectionToWord()` - mouse selection (same as above) - select a portion of two words --> new selection fully encompasses both words --- doc/cascadia/profiles.schema.json | 1 + src/cascadia/TerminalApp/AppActionHandlers.cpp | 10 ++++++++++ src/cascadia/TerminalControl/ControlCore.cpp | 11 +++++++++++ src/cascadia/TerminalControl/ControlCore.h | 1 + src/cascadia/TerminalControl/ControlCore.idl | 1 + src/cascadia/TerminalControl/TermControl.cpp | 5 +++++ src/cascadia/TerminalControl/TermControl.h | 1 + src/cascadia/TerminalControl/TermControl.idl | 1 + src/cascadia/TerminalCore/Terminal.hpp | 1 + src/cascadia/TerminalCore/TerminalSelection.cpp | 10 ++++++++++ src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp | 2 ++ .../TerminalSettingsModel/AllShortcutActions.h | 1 + .../Resources/en-US/Resources.resw | 3 +++ src/cascadia/TerminalSettingsModel/defaults.json | 1 + 14 files changed, 49 insertions(+) diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index 9a502c422b8..311ad53a79a 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -315,6 +315,7 @@ "commandPalette", "copy", "duplicateTab", + "expandSelectionToWord", "exportBuffer", "find", "findMatch", diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index 81fc005ea3b..23960046f49 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -1156,4 +1156,14 @@ namespace winrt::TerminalApp::implementation args.Handled(handled); } } + + void TerminalPage::_HandleExpandSelectionToWord(const IInspectable& /*sender*/, + const ActionEventArgs& args) + { + if (const auto& control{ _GetActiveControl() }) + { + const auto handled = control.ExpandSelectionToWord(); + args.Handled(handled); + } + } } diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index 28fc6ae5154..fdf5d082fc8 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -1147,6 +1147,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation return false; } + bool ControlCore::ExpandSelectionToWord() + { + if (_terminal->IsSelectionActive()) + { + _terminal->ExpandSelectionToWord(); + _updateSelectionUI(); + return true; + } + return false; + } + // Method Description: // - Pre-process text pasted (presumably from the clipboard) // before sending it over the terminal's connection. diff --git a/src/cascadia/TerminalControl/ControlCore.h b/src/cascadia/TerminalControl/ControlCore.h index 383d415c430..f9a6297bd57 100644 --- a/src/cascadia/TerminalControl/ControlCore.h +++ b/src/cascadia/TerminalControl/ControlCore.h @@ -87,6 +87,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation void ToggleMarkMode(); Control::SelectionInteractionMode SelectionMode() const; bool SwitchSelectionEndpoint(); + bool ExpandSelectionToWord(); bool TryMarkModeKeybinding(const WORD vkey, const ::Microsoft::Terminal::Core::ControlKeyStates modifiers); diff --git a/src/cascadia/TerminalControl/ControlCore.idl b/src/cascadia/TerminalControl/ControlCore.idl index c52c4d4b410..cb61cd2a3af 100644 --- a/src/cascadia/TerminalControl/ControlCore.idl +++ b/src/cascadia/TerminalControl/ControlCore.idl @@ -91,6 +91,7 @@ namespace Microsoft.Terminal.Control Boolean ToggleBlockSelection(); void ToggleMarkMode(); Boolean SwitchSelectionEndpoint(); + Boolean ExpandSelectionToWord(); void ClearBuffer(ClearBufferType clearType); void SetHoveredCell(Microsoft.Terminal.Core.Point terminalPosition); diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index e053fd10720..d8f25cace1d 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -1981,6 +1981,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation return _core.SwitchSelectionEndpoint(); } + bool TermControl::ExpandSelectionToWord() + { + return _core.ExpandSelectionToWord(); + } + void TermControl::Close() { if (!_IsClosing()) diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index 4e5891aa66d..34ac6dc3520 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -41,6 +41,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation bool ToggleBlockSelection(); void ToggleMarkMode(); bool SwitchSelectionEndpoint(); + bool ExpandSelectionToWord(); void Close(); Windows::Foundation::Size CharacterDimensions() const; Windows::Foundation::Size MinimumSize(); diff --git a/src/cascadia/TerminalControl/TermControl.idl b/src/cascadia/TerminalControl/TermControl.idl index 101359b30e9..e4b65735ab6 100644 --- a/src/cascadia/TerminalControl/TermControl.idl +++ b/src/cascadia/TerminalControl/TermControl.idl @@ -55,6 +55,7 @@ namespace Microsoft.Terminal.Control Boolean ToggleBlockSelection(); void ToggleMarkMode(); Boolean SwitchSelectionEndpoint(); + Boolean ExpandSelectionToWord(); void ClearBuffer(ClearBufferType clearType); void Close(); Windows.Foundation.Size CharacterDimensions { get; }; diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp index c0b18594e5b..5608f51db4f 100644 --- a/src/cascadia/TerminalCore/Terminal.hpp +++ b/src/cascadia/TerminalCore/Terminal.hpp @@ -281,6 +281,7 @@ class Microsoft::Terminal::Core::Terminal final : void SelectAll(); SelectionInteractionMode SelectionMode() const noexcept; void SwitchSelectionEndpoint(); + void ExpandSelectionToWord(); void ToggleMarkMode(); void SelectHyperlink(const SearchDirection dir); bool SelectionIsTargetingUrl() const noexcept; diff --git a/src/cascadia/TerminalCore/TerminalSelection.cpp b/src/cascadia/TerminalCore/TerminalSelection.cpp index 2e34e5195ba..38fa2446786 100644 --- a/src/cascadia/TerminalCore/TerminalSelection.cpp +++ b/src/cascadia/TerminalCore/TerminalSelection.cpp @@ -340,6 +340,16 @@ void Terminal::SwitchSelectionEndpoint() } } +void Terminal::ExpandSelectionToWord() +{ + if (IsSelectionActive()) + { + const auto& buffer = _activeBuffer(); + _selection->start = buffer.GetWordStart(_selection->start, _wordDelimiters); + _selection->end = buffer.GetWordEnd(_selection->end, _wordDelimiters); + } +} + // Method Description: // - selects the next/previous hyperlink, if one is available // Arguments: diff --git a/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp b/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp index b9aaaf1aae3..10dc2b4b31f 100644 --- a/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp +++ b/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp @@ -84,6 +84,7 @@ static constexpr std::string_view SelectAllKey{ "selectAll" }; static constexpr std::string_view MarkModeKey{ "markMode" }; static constexpr std::string_view ToggleBlockSelectionKey{ "toggleBlockSelection" }; static constexpr std::string_view SwitchSelectionEndpointKey{ "switchSelectionEndpoint" }; +static constexpr std::string_view ExpandSelectionToWordKey{ "expandSelectionToWord" }; static constexpr std::string_view ActionKey{ "action" }; @@ -404,6 +405,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation { ShortcutAction::MarkMode, RS_(L"MarkModeCommandKey") }, { ShortcutAction::ToggleBlockSelection, RS_(L"ToggleBlockSelectionCommandKey") }, { ShortcutAction::SwitchSelectionEndpoint, RS_(L"SwitchSelectionEndpointCommandKey") }, + { ShortcutAction::ExpandSelectionToWord, RS_(L"ExpandSelectionToWordCommandKey") }, }; }(); diff --git a/src/cascadia/TerminalSettingsModel/AllShortcutActions.h b/src/cascadia/TerminalSettingsModel/AllShortcutActions.h index 800e4352878..21c857971e8 100644 --- a/src/cascadia/TerminalSettingsModel/AllShortcutActions.h +++ b/src/cascadia/TerminalSettingsModel/AllShortcutActions.h @@ -97,6 +97,7 @@ ON_ALL_ACTIONS(MarkMode) \ ON_ALL_ACTIONS(ToggleBlockSelection) \ ON_ALL_ACTIONS(SwitchSelectionEndpoint) \ + ON_ALL_ACTIONS(ExpandSelectionToWord) \ ON_ALL_ACTIONS(CloseOtherPanes) #define ALL_SHORTCUT_ACTIONS_WITH_ARGS \ diff --git a/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw b/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw index 4f1514af722..12fac66fa82 100644 --- a/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw @@ -567,6 +567,9 @@ Switch selection endpoint + + Expand selection to word + Close all other panes diff --git a/src/cascadia/TerminalSettingsModel/defaults.json b/src/cascadia/TerminalSettingsModel/defaults.json index 117248e4d7c..59a7f231c81 100644 --- a/src/cascadia/TerminalSettingsModel/defaults.json +++ b/src/cascadia/TerminalSettingsModel/defaults.json @@ -428,6 +428,7 @@ { "command": "markMode", "keys": "ctrl+shift+m" }, { "command": "toggleBlockSelection" }, { "command": "switchSelectionEndpoint" }, + { "command": "expandSelectionToWord" }, // Scrollback { "command": "scrollDown", "keys": "ctrl+shift+down" },