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
    const auto bufferSize = _activeBuffer().GetSize();
    const auto mutableViewport = _GetMutableViewport();
    const COORD bottomRightInclusive{ mutableViewport.RightInclusive(), mutableViewport.BottomInclusive() };
    if (bufferSize.CompareInBounds(targetPos, bottomRightInclusive) > 0)
    {
        targetPos.Y = bottomRightInclusive;
    }

    // 3. Actually modify the selection
    // NOTE: targetStart doesn't matter here
    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
        {
            // anchor is below visible viewport, scroll by that amount
            const auto amtBelowView = targetPos.Y - visibleViewport.BottomInclusive();
            _scrollOffset -= amtBelowView;
        }
        _NotifyScrollEvent();
        _activeBuffer().TriggerScroll();
    }
}


Review comment (suggestion):
BTW now that I'm seeing this, if you make such a change in `main` you can just do
```cpp
targetPos = std::min(targetPos, bottomRightInclusive);
```

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
    const auto bufferSize = _activeBuffer().GetSize();
    const auto mutableViewport = _GetMutableViewport();
    const COORD bottomRightInclusive{ mutableViewport.RightInclusive(), mutableViewport.BottomInclusive() };
    if (bufferSize.CompareInBounds(targetPos, bottomRightInclusive) > 0)
    {
        targetPos = bottomRightInclusive;
    }

    // 3. Actually modify the selection
    // NOTE: targetStart doesn't matter here
    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
        {
            // anchor is below visible viewport, scroll by that amount
            const auto amtBelowView = targetPos.Y - visibleViewport.BottomInclusive();
            _scrollOffset -= amtBelowView;
        }
        _NotifyScrollEvent();
        _activeBuffer().TriggerScroll();
    }
}