Skip to content

Commit

Permalink
Implement Keyboard Selection
Browse files Browse the repository at this point in the history
  • Loading branch information
carlos-zamora committed Jul 31, 2021
1 parent 3f5f37d commit 841cd2a
Show file tree
Hide file tree
Showing 24 changed files with 453 additions and 56 deletions.
42 changes: 42 additions & 0 deletions doc/cascadia/profiles.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@
"togglePaneZoom",
"toggleReadOnlyMode",
"toggleShaderEffects",
"updateSelection",
"wt",
"unbound"
],
Expand All @@ -297,6 +298,24 @@
],
"type": "string"
},
"SelectionDirection": {
"enum": [
"left",
"right",
"up",
"down"
],
"type": "string"
},
"SelectionMode": {
"enum": [
"cell",
"word",
"view",
"buffer"
],
"type": "string"
},
"MoveTabDirection": {
"enum": [
"forward",
Expand Down Expand Up @@ -532,6 +551,28 @@
],
"required": [ "direction" ]
},
"UpdateSelectionAction": {
"description": "Arguments corresponding to a Update Selection Action",
"allOf": [
{ "$ref": "#/definitions/ShortcutAction" },
{
"properties": {
"action": { "type": "string", "pattern": "updateSelection" },
"direction": {
"$ref": "#/definitions/SelectionDirection",
"default": "left",
"description": "The direction to move the selection endpoint in."
},
"mode": {
"$ref": "#/definitions/SelectionMode",
"default": "cell",
"description": "The expansion mode to move the selection endpoint by."
}
}
}
],
"required": [ "direction" ]
},
"ResizePaneAction": {
"description": "Arguments corresponding to a Resize Pane Action",
"allOf": [
Expand Down Expand Up @@ -993,6 +1034,7 @@
{ "$ref": "#/definitions/FocusPaneAction" },
{ "$ref": "#/definitions/GlobalSummonAction" },
{ "$ref": "#/definitions/QuakeModeAction" },
{ "$ref": "#/definitions/UpdateSelectionAction" },
{ "type": "null" }
]
},
Expand Down
10 changes: 7 additions & 3 deletions src/buffer/out/textBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1414,12 +1414,13 @@ const til::point TextBuffer::GetGlyphStart(const til::point pos) const
}

// Method Description:
// - Update pos to be the end of the current glyph/character. This is used for accessibility
// - Update pos to be the end of the current glyph/character.
// Arguments:
// - pos - a COORD on the word you are currently on
// - accessibilityMode - this is being used for accessibility; make the end exclusive.
// Return Value:
// - pos - The COORD for the last cell of the current glyph (exclusive)
const til::point TextBuffer::GetGlyphEnd(const til::point pos) const
const til::point TextBuffer::GetGlyphEnd(const til::point pos, bool accessibilityMode) const
{
COORD resultPos = pos;

Expand All @@ -1430,7 +1431,10 @@ const til::point TextBuffer::GetGlyphEnd(const til::point pos) const
}

// increment one more time to become exclusive
bufferSize.IncrementInBounds(resultPos, true);
if (accessibilityMode)
{
bufferSize.IncrementInBounds(resultPos, true);
}
return resultPos;
}

Expand Down
2 changes: 1 addition & 1 deletion src/buffer/out/textBuffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ class TextBuffer final
bool MoveToPreviousWord(COORD& pos, const std::wstring_view wordDelimiters) const;

const til::point GetGlyphStart(const til::point pos) const;
const til::point GetGlyphEnd(const til::point pos) const;
const til::point GetGlyphEnd(const til::point pos, bool accessibilityMode = false) const;
bool MoveToNextGlyph(til::point& pos, bool allowBottomExclusive = false) const;
bool MoveToPreviousGlyph(til::point& pos) const;

Expand Down
15 changes: 15 additions & 0 deletions src/cascadia/TerminalApp/AppActionHandlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -851,4 +851,19 @@ namespace winrt::TerminalApp::implementation
}
}
}

void TerminalPage::_HandleUpdateSelection(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
if (args)
{
if (const auto& realArgs = args.ActionArgs().try_as<UpdateSelectionArgs>())
{
if (const auto termControl{ _GetActiveControl() })
{
args.Handled(termControl.UpdateSelection(realArgs.Direction(), realArgs.Mode()));
}
}
}
}
}
25 changes: 20 additions & 5 deletions src/cascadia/TerminalControl/ControlCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -845,6 +845,21 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_renderer->TriggerSelection();
}

bool ControlCore::UpdateSelection(Core::SelectionDirection direction, Core::SelectionExpansion mode)
{
// - SelectionDirection cannot be none
// - A selection must be active for us to update it
if (direction == Core::SelectionDirection::None || !HasSelection())
{
return false;
}

auto lock = _terminal->LockForWriting();
_terminal->UpdateSelection(direction, mode);
_renderer->TriggerSelection();
return true;
}

// Called when the Terminal wants to set something to the clipboard, i.e.
// when an OSC 52 is emitted.
void ControlCore::_terminalCopyToClipboard(std::wstring_view wstr)
Expand Down Expand Up @@ -1325,18 +1340,18 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// handle ALT key
_terminal->SetBlockSelection(altEnabled);

::Terminal::SelectionExpansionMode mode = ::Terminal::SelectionExpansionMode::Cell;
Core::SelectionExpansion mode = Core::SelectionExpansion::Cell;
if (numberOfClicks == 1)
{
mode = ::Terminal::SelectionExpansionMode::Cell;
mode = Core::SelectionExpansion::Cell;
}
else if (numberOfClicks == 2)
{
mode = ::Terminal::SelectionExpansionMode::Word;
mode = Core::SelectionExpansion::Word;
}
else if (numberOfClicks == 3)
{
mode = ::Terminal::SelectionExpansionMode::Line;
mode = Core::SelectionExpansion::Line;
}

// Update the selection appropriately
Expand All @@ -1361,7 +1376,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_terminal->SetSelectionEnd(terminalPosition, mode);
selectionNeedsToBeCopied = true;
}
else if (mode != ::Terminal::SelectionExpansionMode::Cell || shiftEnabled)
else if (mode != Core::SelectionExpansion::Cell || shiftEnabled)
{
// If we are handling a double / triple-click or shift+single click
// we establish selection using the selected mode
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 @@ -127,6 +127,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
Windows::Foundation::Collections::IVector<winrt::hstring> SelectedText(bool trimTrailingWhitespace) const;
void SetSelectionAnchor(til::point const& position);
void SetEndSelectionPoint(til::point const& position);
bool UpdateSelection(Core::SelectionDirection direction, Core::SelectionExpansion mode);

void Search(const winrt::hstring& text,
const bool goForward,
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 @@ -71,6 +71,7 @@ namespace Microsoft.Terminal.Control

Boolean HasSelection { get; };
IVector<String> SelectedText(Boolean trimTrailingWhitespace);
Boolean UpdateSelection(Microsoft.Terminal.Core.SelectionDirection direction, Microsoft.Terminal.Core.SelectionExpansion mode);

String HoveredUriText { get; };
Windows.Foundation.IReference<Microsoft.Terminal.Core.Point> HoveredCell { get; };
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 @@ -2554,4 +2554,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
{
_playWarningBell->Run();
}

bool TermControl::UpdateSelection(Core::SelectionDirection direction, Core::SelectionExpansion mode)
{
return _core.UpdateSelection(direction, mode);
}
}
1 change: 1 addition & 0 deletions src/cascadia/TerminalControl/TermControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation

hstring GetProfileName() const;

bool UpdateSelection(Core::SelectionDirection direction, Core::SelectionExpansion mode);
bool CopySelectionToClipboard(bool singleLine, const Windows::Foundation::IReference<CopyFormat>& formats);
void PasteTextFromClipboard();
void Close();
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 @@ -44,6 +44,7 @@ namespace Microsoft.Terminal.Control
// We expose this and ConnectionState here so that it might eventually be data bound.
event Windows.Foundation.TypedEventHandler<Object, IInspectable> ConnectionStateChanged;

Boolean UpdateSelection(Microsoft.Terminal.Core.SelectionDirection direction, Microsoft.Terminal.Core.SelectionExpansion mode);
Boolean CopySelectionToClipboard(Boolean singleLine, Windows.Foundation.IReference<CopyFormat> formats);
void PasteTextFromClipboard();
void Close();
Expand Down
18 changes: 18 additions & 0 deletions src/cascadia/TerminalCore/ICoreSettings.idl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,24 @@ import "..\ICoreAppearance.idl";

namespace Microsoft.Terminal.Core
{
enum SelectionDirection
{
None = 0,
Left,
Right,
Up,
Down,
};

enum SelectionExpansion
{
Cell,
Word,
Line, // Mouse selection only! Not a setting!
Viewport,
Buffer
};

interface ICoreSettings requires ICoreAppearance
{
// TODO:MSFT:20642297 - define a sentinel for Infinite Scrollback
Expand Down
19 changes: 9 additions & 10 deletions src/cascadia/TerminalCore/Terminal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,16 +227,11 @@ class Microsoft::Terminal::Core::Terminal final :

#pragma region TextSelection
// These methods are defined in TerminalSelection.cpp
enum class SelectionExpansionMode
{
Cell,
Word,
Line
};
void MultiClickSelection(const COORD viewportPos, SelectionExpansionMode expansionMode);
void MultiClickSelection(const COORD viewportPos, winrt::Microsoft::Terminal::Core::SelectionExpansion expansionMode);
void SetSelectionAnchor(const COORD position);
void SetSelectionEnd(const COORD position, std::optional<SelectionExpansionMode> newExpansionMode = std::nullopt);
void SetSelectionEnd(const COORD position, std::optional<winrt::Microsoft::Terminal::Core::SelectionExpansion> newExpansionMode = std::nullopt);
void SetBlockSelection(const bool isEnabled) noexcept;
void UpdateSelection(winrt::Microsoft::Terminal::Core::SelectionDirection direction, winrt::Microsoft::Terminal::Core::SelectionExpansion mode);

const TextBuffer::TextAndColor RetrieveSelectedTextFromBuffer(bool trimTrailingWhitespace);
#pragma endregion
Expand Down Expand Up @@ -307,7 +302,7 @@ class Microsoft::Terminal::Core::Terminal final :
std::optional<SelectionAnchors> _selection;
bool _blockSelection;
std::wstring _wordDelimiters;
SelectionExpansionMode _multiClickSelectionMode;
winrt::Microsoft::Terminal::Core::SelectionExpansion _multiClickSelectionMode;
#pragma endregion

// TODO: These members are not shared by an alt-buffer. They should be
Expand Down Expand Up @@ -371,9 +366,13 @@ class Microsoft::Terminal::Core::Terminal final :
#pragma region TextSelection
// These methods are defined in TerminalSelection.cpp
std::vector<SMALL_RECT> _GetSelectionRects() const noexcept;
std::pair<COORD, COORD> _PivotSelection(const COORD targetPos, bool& targetStart) const;
std::tuple<COORD, COORD, bool> _PivotSelection(const COORD targetPos) const;
std::pair<COORD, COORD> _ExpandSelectionAnchors(std::pair<COORD, COORD> anchors) const;
COORD _ConvertToBufferCell(const COORD viewportPos) const;
void _MoveByChar(winrt::Microsoft::Terminal::Core::SelectionDirection direction, COORD& pos);
void _MoveByWord(winrt::Microsoft::Terminal::Core::SelectionDirection direction, COORD& pos);
void _MoveByViewport(winrt::Microsoft::Terminal::Core::SelectionDirection direction, COORD& pos);
void _MoveByBuffer(winrt::Microsoft::Terminal::Core::SelectionDirection direction, COORD& pos);
#pragma endregion

Microsoft::Console::VirtualTerminal::SgrStack _sgrStack;
Expand Down
Loading

0 comments on commit 841cd2a

Please sign in to comment.