Repository: microsoft/terminal
File: src/cascadia/TerminalControl/ControlCore.cpp (C++)

Code before:
        {
            UserScrollViewport(tgt->start.y);
            _terminalScrollPositionChanged(tgt->start.y, viewHeight, bufferSize);
        }
        else
        {
            if (direction == ScrollToMarkDirection::Last || direction == ScrollToMarkDirection::Next)
            {
                UserScrollViewport(BufferHeight());
                _terminalScrollPositionChanged(BufferHeight(), viewHeight, bufferSize);
            }
            else if (direction == ScrollToMarkDirection::First || direction == ScrollToMarkDirection::Previous)
            {
                UserScrollViewport(0);
                _terminalScrollPositionChanged(0, viewHeight, bufferSize);
            }
        }
    }

    void ControlCore::SelectCommand(const bool goUp)
    {
        const til::point start = HasSelection() ? (goUp ? _terminal->GetSelectionAnchor() : _terminal->GetSelectionEnd()) :
                                                  _terminal->GetTextBuffer().GetCursor().GetPosition();
        std::optional<DispatchTypes::ScrollMark> nearest{ std::nullopt };
        const auto marks{ std::ranges::reverse_view(_terminal->GetScrollMarks()) };
        for (auto&& m : marks)
        {
            // If this mark doesn't know anything about the position of its
            // command, OR it does but thinks that it was empty, then just skip
            // it.
            if (!m.commandEnd.has_value() || *m.commandEnd == m.end)
            {
                continue;
            }
            // If this mark is before/after the start of our search in the
            // buffer, ...

            auto inTheRightDirection = (goUp && (m.commandEnd < start)) || // prev
                                       (!goUp && (m.end > start)); // next
            // (If we're going down, we need to compare the end, not the
            // commandEnd, to actually find the next one. Otherwise we'll just
            // find the mark of the current selection again.
            if (inTheRightDirection)
            {
                // ... and we either haven't found a match, or the current nearest
                // is after/before this mark in the buffer
                if (!nearest.has_value() ||
                    ((goUp && (*m.commandEnd > *nearest->commandEnd)) || // prev
                     (!goUp && (m.end < *nearest->commandEnd)))) // next
                {
                    // stash this as the new match

Review comment (suggestion):
```suggestion
        for (const auto&& m : marks)
```

Code after:
            m.end = til::point{ _terminal->GetSelectionEnd() };
        }
        else
        {
            m.start = m.end = til::point{ _terminal->GetTextBuffer().GetCursor().GetPosition() };
        }

        // The version of this that only accepts a ScrollMark will automatically
        // set the start & end to the cursor position.
        _terminal->AddMark(m, m.start, m.end, true);
    }
    void ControlCore::ClearMark() { _terminal->ClearMark(); }
    void ControlCore::ClearAllMarks() { _terminal->ClearAllMarks(); }

    void ControlCore::ScrollToMark(const Control::ScrollToMarkDirection& direction)
    {
        const auto currentOffset = ScrollOffset();
        const auto& marks{ _terminal->GetScrollMarks() };

        std::optional<DispatchTypes::ScrollMark> tgt;

        switch (direction)
        {
        case ScrollToMarkDirection::Last:
        {
            int highest = currentOffset;
            for (const auto& mark : marks)
            {
                const auto newY = mark.start.y;
                if (newY > highest)
                {
                    tgt = mark;
                    highest = newY;
                }
            }
            break;
        }
        case ScrollToMarkDirection::First:
        {
            int lowest = currentOffset;
            for (const auto& mark : marks)
            {
                const auto newY = mark.start.y;
                if (newY < lowest)
                {
                    tgt = mark;
                    lowest = newY;
                }
            }
            break;
        }