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

Code before:
{
    if (IsSelectionActive())
    {
        if (WI_IsFlagSet(_selectionEndpoint, SelectionEndpoint::Start) && WI_IsFlagSet(_selectionEndpoint, SelectionEndpoint::End))
        {
            // moving cursor --> anchor start, move end
            _selectionEndpoint = SelectionEndpoint::End;
            _anchorSelectionEndpoint = true;
        }
        else if (WI_IsFlagSet(_selectionEndpoint, SelectionEndpoint::End))
        {
            // moving end --> now we're moving start
            _selectionEndpoint = SelectionEndpoint::Start;
            _selection->pivot = _selection->end;
        }
        else if (WI_IsFlagSet(_selectionEndpoint, SelectionEndpoint::Start))
        {
            // moving start --> now we're moving end
            _selectionEndpoint = SelectionEndpoint::End;
            _selection->pivot = _selection->start;
        }
    }
}

// Method Description:
// - selects the next/previous hyperlink, if one is available
// Arguments:
// - searchForward: if true, we're scanning forward towards the end of the buffer. Otherwise, we're scanning backwards towards the top.
// Return Value:
// - true if we found a hyperlink to select (and selected it). False otherwise.
void Terminal::SelectHyperlink(const bool searchForward)
{
    if (!_markMode)
    {
        // This feature only works in mark mode
        _isTargetingUrl = false;
        return;
    }

    // 0. Useful tools/vars
    const auto bufferSize = _activeBuffer().GetSize();
    const auto viewportHeight = _GetMutableViewport().Height();

    // extracts the next/previous hyperlink from the list of hyperlink ranges provided
    auto extractResultFromList = [&, onUrl = _isTargetingUrl, selectionStart = _selection->start](const std::vector<interval_tree::Interval<til::point, size_t>>& list, bool forward, bool useViewportCoords) {
        // checks if we're already on the hyperlink and if we're trying to set it to the same one
        auto isAlreadySelected = [onUrl, selectionStartForValidation = useViewportCoords ? _ConvertToViewportCell(selectionStart) : selectionStart](const interval_tree::Interval<til::point, size_t> range) {
            return onUrl && selectionStartForValidation == range.start;
        };

        std::optional<std::pair<til::point, til::point>> resultFromList;

Review comment (suggestion):
You can make this API more descriptive if you introduce a tiny `enum class` which has a `Forward` and `Backward` member.

Code after:
        if (WI_IsFlagSet(_selectionEndpoint, SelectionEndpoint::Start) && WI_IsFlagSet(_selectionEndpoint, SelectionEndpoint::End))
        {
            // moving cursor --> anchor start, move end
            _selectionEndpoint = SelectionEndpoint::End;
            _anchorInactiveSelectionEndpoint = true;
        }
        else if (WI_IsFlagSet(_selectionEndpoint, SelectionEndpoint::End))
        {
            // moving end --> now we're moving start
            _selectionEndpoint = SelectionEndpoint::Start;
            _selection->pivot = _selection->end;
        }
        else if (WI_IsFlagSet(_selectionEndpoint, SelectionEndpoint::Start))
        {
            // moving start --> now we're moving end
            _selectionEndpoint = SelectionEndpoint::End;
            _selection->pivot = _selection->start;
        }
    }
}

// Method Description:
// - selects the next/previous hyperlink, if one is available
// Arguments:
// - dir: the direction we're scanning the buffer in to find the hyperlink of interest
// Return Value:
// - true if we found a hyperlink to select (and selected it). False otherwise.
void Terminal::SelectHyperlink(const SearchDirection dir)
{
    if (_selectionMode != SelectionInteractionMode::Mark)
    {
        // This feature only works in mark mode
        _isTargetingUrl = false;
        return;
    }

    // 0. Useful tools/vars
    const auto bufferSize = _activeBuffer().GetSize();
    const auto viewportHeight = _GetMutableViewport().Height();

    // The patterns are stored relative to the "search area". Initially, this search area will be the viewport,
    // but as we progressively search through more of the buffer, this will change.
    // Keep track of the search area here, and use the lambda below to convert points to the search area coordinate space.
    auto searchArea = _GetVisibleViewport();
    auto convertToSearchArea = [&searchArea](const til::point pt) {
        auto copy = pt;
        searchArea.ConvertToOrigin(&copy);
        return copy;
    };

    // extracts the next/previous hyperlink from the list of hyperlink ranges provided