Repository: microsoft/terminal
File: src/cascadia/TerminalCore/TerminalSelection.cpp (C++)

Code before:

    // 2.A) Perform the movement
    switch (mode)
    {
    case SelectionExpansion::Char:
        _MoveByChar(direction, targetPos);
        break;
    case SelectionExpansion::Word:
        _MoveByWord(direction, targetPos);
        break;
    case SelectionExpansion::Viewport:
        _MoveByViewport(direction, targetPos);
        break;
    case SelectionExpansion::Buffer:
        _MoveByBuffer(direction, targetPos);
        break;
    }

    // 2.B) Clamp the movement to the mutable viewport
    if (const auto mutableViewport = _GetMutableViewport(); targetPos > mutableViewport.BottomRightInclusive())
    {
        targetPos.Y = mutableViewport.BottomInclusive();
    }
    else if (const auto bufferSize = _activeBuffer().GetSize(); targetPos < bufferSize.Origin())
    {
        targetPos.Y = bufferSize.Top();
    }

    // 3. Actually modify the selection
    // NOTE: targetStart doesn't matter here
    if (_markMode)
    {
        // [Mark Mode]
        // - moveSelectionEnd  --> just move end (i.e. shift + arrow keys)
        // - !moveSelectionEnd --> move all three (i.e. just use arrow keys)
        _selection->end = targetPos;
        if (!movingEnd)
        {
            _selection->start = targetPos;
            _selection->pivot = targetPos;
        }
    }
    else
    {
        auto targetStart = false;
        std::tie(_selection->start, _selection->end) = _PivotSelection(targetPos, targetStart);
    }

    // 4. Scroll (if necessary)
    if (const auto visibleViewport = _GetVisibleViewport(); !visibleViewport.IsInBounds(targetPos))
    {

Review comment (suggestion):
This doesn't restrict you from going above the visible area when htere's a scrollbar, right?

Another quick check: should moving UP at the TOP of the screen move you to 0,0? Should moving DOWN at the BOTTOM move you to width,bottom? That is how text editors select. :)

Code after:

    // 2.A) Perform the movement
    switch (mode)
    {
    case SelectionExpansion::Char:
        _MoveByChar(direction, targetPos);
        break;
    case SelectionExpansion::Word:
        _MoveByWord(direction, targetPos);
        break;
    case SelectionExpansion::Viewport:
        _MoveByViewport(direction, targetPos);
        break;
    case SelectionExpansion::Buffer:
        _MoveByBuffer(direction, targetPos);
        break;
    }

    // 2.B) Clamp the movement to the mutable viewport
    targetPos = std::min(targetPos, _GetMutableViewport().BottomRightInclusive());

    // 3. Actually modify the selection
    // NOTE: targetStart doesn't matter here
    if (_markMode)
    {
        // [Mark Mode]
        // - moveSelectionEnd  --> just move end (i.e. shift + arrow keys)
        // - !moveSelectionEnd --> move all three (i.e. just use arrow keys)
        _selection->end = targetPos;
        if (!movingEnd)
        {
            _selection->start = targetPos;
            _selection->pivot = targetPos;
        }
    }
    else
    {
        auto targetStart = false;
        std::tie(_selection->start, _selection->end) = _PivotSelection(targetPos, targetStart);
    }

    // 4. Scroll (if necessary)
    if (const auto visibleViewport = _GetVisibleViewport(); !visibleViewport.IsInBounds(targetPos))
    {
        if (const auto amtAboveView = visibleViewport.Top() - targetPos.Y; amtAboveView > 0)
        {
            // anchor is above visible viewport, scroll by that amount
            _scrollOffset += amtAboveView;
        }
        else
        {