Skip to content

Commit

Permalink
Add ability to select all text in the buffer (#13045)
Browse files Browse the repository at this point in the history
Adds the `selectAll` action which can be used to select all text in the buffer (regardless of whether a selection is present).

## References
#3663 - Mark Mode
#4993 - [Scenario] Keyboard selection

## PR Checklist
* [x] Closes #1469
* [x] Tests added/passed

## Detailed Description of the Pull Request / Additional comments
I've made it such that selecting the "entire buffer" really just selects up to the mutable viewport. This seems like a nice QOL improvement since there's generally nothing past that.

When the user selects all, the viewport does not move. This is consistent with CMD behavior and is intended to allow the user to not lose context when selecting everything.

A minor change had to be made to the DxRenderer because this uncovered an underflow issue. Basically, the selection rects were handed to the DxEngine relative to the viewport (which means that some had a negative y-value). At some point, those rects were stored into `size_t`s, resulting in an underflow issue. This caused the renderer to behave strangely when rendering the selection. Generally, these kinds of issues weren't really noticed because selection would always modify a portion of the viewport.

Funny enough, in a way, this satisfies the "mark mode" scenario because the user now has a way to initiate a selection using only the keyboard. Though this isn't ideal, just a fun thing to point out (that's why I'm not closing the mark mode issue).

## Validation Steps Performed
- Verified using DxEngine and AtlasEngine
- select all --> keyboard selection --> start moving the top-left endpoint (and scroll to there)
- select all --> do not scroll automatically
  • Loading branch information
carlos-zamora committed May 6, 2022
1 parent d072314 commit 60a4837
Show file tree
Hide file tree
Showing 14 changed files with 47 additions and 4 deletions.
10 changes: 10 additions & 0 deletions src/cascadia/TerminalApp/AppActionHandlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1033,4 +1033,14 @@ namespace winrt::TerminalApp::implementation
}
}
}

void TerminalPage::_HandleSelectAll(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
if (const auto& control{ _GetActiveControl() })
{
control.SelectAll();
args.Handled(true);
}
}
}
7 changes: 7 additions & 0 deletions src/cascadia/TerminalControl/ControlCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -994,6 +994,13 @@ namespace winrt::Microsoft::Terminal::Control::implementation
return true;
}

void ControlCore::SelectAll()
{
auto lock = _terminal->LockForWriting();
_terminal->SelectAll();
_renderer->TriggerSelection();
}

// Method Description:
// - Pre-process text pasted (presumably from the clipboard)
// before sending it over the terminal's connection.
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalControl/ControlCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void SendInput(const winrt::hstring& wstr);
void PasteText(const winrt::hstring& hstr);
bool CopySelectionToClipboard(bool singleLine, const Windows::Foundation::IReference<CopyFormat>& formats);
void SelectAll();

void GotFocus();
void LostFocus();
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalControl/ControlCore.idl
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ namespace Microsoft.Terminal.Control
Microsoft.Terminal.Core.ControlKeyStates modifiers);
void SendInput(String text);
void PasteText(String text);
void SelectAll();
void ClearBuffer(ClearBufferType clearType);

void SetHoveredCell(Microsoft.Terminal.Core.Point terminalPosition);
Expand Down
5 changes: 5 additions & 0 deletions src/cascadia/TerminalControl/TermControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1840,6 +1840,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_interactivity.RequestPasteTextFromClipboard();
}

void TermControl::SelectAll()
{
_core.SelectAll();
}

void TermControl::Close()
{
if (!_IsClosing())
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalControl/TermControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation

bool CopySelectionToClipboard(bool singleLine, const Windows::Foundation::IReference<CopyFormat>& formats);
void PasteTextFromClipboard();
void SelectAll();
void Close();
Windows::Foundation::Size CharacterDimensions() const;
Windows::Foundation::Size MinimumSize();
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalControl/TermControl.idl
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ namespace Microsoft.Terminal.Control

Boolean CopySelectionToClipboard(Boolean singleLine, Windows.Foundation.IReference<CopyFormat> formats);
void PasteTextFromClipboard();
void SelectAll();
void ClearBuffer(ClearBufferType clearType);
void Close();
Windows.Foundation.Size CharacterDimensions { get; };
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalCore/Terminal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ class Microsoft::Terminal::Core::Terminal final :
void SetSelectionEnd(const COORD position, std::optional<SelectionExpansion> newExpansionMode = std::nullopt);
void SetBlockSelection(const bool isEnabled) noexcept;
void UpdateSelection(SelectionDirection direction, SelectionExpansion mode);
void SelectAll();

using UpdateSelectionParams = std::optional<std::pair<SelectionDirection, SelectionExpansion>>;
static UpdateSelectionParams ConvertKeyEventToUpdateSelectionParams(const ControlKeyStates mods, const WORD vkey);
Expand Down
9 changes: 9 additions & 0 deletions src/cascadia/TerminalCore/TerminalSelection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,15 @@ void Terminal::UpdateSelection(SelectionDirection direction, SelectionExpansion
}
}

void Terminal::SelectAll()
{
const auto bufferSize{ _activeBuffer().GetSize() };
_selection = SelectionAnchors{};
_selection->start = bufferSize.Origin();
_selection->end = { bufferSize.RightInclusive(), _GetMutableViewport().BottomInclusive() };
_selection->pivot = _selection->end;
}

void Terminal::_MoveByChar(SelectionDirection direction, COORD& pos)
{
switch (direction)
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ static constexpr std::string_view MultipleActionsKey{ "multipleActions" };
static constexpr std::string_view QuitKey{ "quit" };
static constexpr std::string_view AdjustOpacityKey{ "adjustOpacity" };
static constexpr std::string_view RestoreLastClosedKey{ "restoreLastClosed" };
static constexpr std::string_view SelectAllKey{ "selectAll" };

static constexpr std::string_view ActionKey{ "action" };

Expand Down Expand Up @@ -386,6 +387,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{ ShortcutAction::Quit, RS_(L"QuitCommandKey") },
{ ShortcutAction::AdjustOpacity, L"" }, // Intentionally omitted, must be generated by GenerateName
{ ShortcutAction::RestoreLastClosed, RS_(L"RestoreLastClosedCommandKey") },
{ ShortcutAction::SelectAll, RS_(L"SelectAllCommandKey") },
};
}();

Expand Down
3 changes: 2 additions & 1 deletion src/cascadia/TerminalSettingsModel/AllShortcutActions.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@
ON_ALL_ACTIONS(MultipleActions) \
ON_ALL_ACTIONS(Quit) \
ON_ALL_ACTIONS(AdjustOpacity) \
ON_ALL_ACTIONS(RestoreLastClosed)
ON_ALL_ACTIONS(RestoreLastClosed) \
ON_ALL_ACTIONS(SelectAll)

#define ALL_SHORTCUT_ACTIONS_WITH_ARGS \
ON_ALL_ACTIONS_WITH_ARGS(AdjustFontSize) \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -522,4 +522,7 @@
<data name="RestoreLastClosedCommandKey" xml:space="preserve">
<value>Restore the last closed pane or tab</value>
</data>
</root>
<data name="SelectAllCommandKey" xml:space="preserve">
<value>Select all text</value>
</data>
</root>
1 change: 1 addition & 0 deletions src/cascadia/TerminalSettingsModel/defaults.json
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@
{ "command": { "action": "copy", "singleLine": false }, "keys": "ctrl+insert" },
{ "command": "paste", "keys": "ctrl+shift+v" },
{ "command": "paste", "keys": "shift+insert" },
{ "command": "selectAll", "keys": "ctrl+shift+a" },

// Scrollback
{ "command": "scrollDown", "keys": "ctrl+shift+down" },
Expand Down
4 changes: 2 additions & 2 deletions src/renderer/dx/DxRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1064,8 +1064,8 @@ HANDLE DxEngine::GetSwapChainHandle() noexcept
void DxEngine::_InvalidateRectangle(const til::rect& rc)
{
const auto size = _invalidMap.size();
const auto topLeft = til::point{ 0, std::min(size.height, rc.top) };
const auto bottomRight = til::point{ size.width, std::min(size.height, rc.bottom) };
const auto topLeft = til::point{ 0, std::clamp(rc.top, 0, size.height) };
const auto bottomRight = til::point{ size.width, std::clamp(rc.bottom, 0, size.height) };
_invalidMap.set(til::rect{ topLeft, bottomRight });
}

Expand Down

0 comments on commit 60a4837

Please sign in to comment.