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

Code before:
// Method Description:
// - Given a coord, get the URI at that location
// Arguments:
// - The position relative to the viewport
std::wstring Terminal::GetHyperlinkAtViewportPosition(const til::point viewportPos)
{
    return GetHyperlinkAtBufferPosition(_ConvertToBufferCell(viewportPos, false));
}

std::wstring Terminal::GetHyperlinkAtBufferPosition(const til::point bufferPos)
{
    const auto& buffer = _activeBuffer();

    // Case 1: buffer position has a hyperlink stored in the buffer
    const auto attr = buffer.GetCellDataAt(bufferPos)->TextAttr();
    if (attr.IsHyperlink())
    {
        return buffer.GetHyperlinkUriFromId(attr.GetHyperlinkId());
    }

    // Case 2: buffer position may point to an auto-detected hyperlink
    // GH#18177: Search a wider range to ensure URLs wrapping across multiple lines are fully captured
    const auto bufferSize = buffer.GetSize();
    const auto viewportHeight = _GetVisibleViewport().Height();
    const auto beg = std::max<til::CoordType>(0, bufferPos.y - viewportHeight);
    const auto end = std::min(bufferSize.BottomInclusive(), bufferPos.y + viewportHeight);
    const auto patterns = _getPatterns(beg, end);

    // Intervals use half-open ranges, so query with x+1 to
    // avoid matching past the exclusive end
    const auto results = patterns.findOverlapping({ bufferPos.x + 1, bufferPos.y }, bufferPos);
    for (const auto& result : results)
    {
        if (result.value == _hyperlinkPatternId)
        {
            return buffer.GetPlainText(result.start, result.stop);
        }
    }
    return {};
}

// Method Description:
// - Gets the hyperlink ID of the text at the given terminal position
// Arguments:
// - The position of the text relative to the viewport
// Return value:
// - The hyperlink ID
uint16_t Terminal::GetHyperlinkIdAtViewportPosition(const til::point viewportPos)
{
    return _activeBuffer().GetCellDataAt(_ConvertToBufferCell(viewportPos, false))->TextAttr().GetHyperlinkId();
}

Review comment (performance):
I think we should move the min/max into `UTextFromTextBuffer` itself so that all callers are protected. Then, we can simplify the code here by dropping the min/max.

BTW why doesn't this function use the cached `_patternIntervalTree`?

Code after:
// Method Description:
// - Given a coord, get the URI at that location
// Arguments:
// - The position relative to the viewport
std::wstring Terminal::GetHyperlinkAtViewportPosition(const til::point viewportPos)
{
    return GetHyperlinkAtBufferPosition(_ConvertToBufferCell(viewportPos, false));
}

std::wstring Terminal::GetHyperlinkAtBufferPosition(const til::point bufferPos)
{
    const auto& buffer = _activeBuffer();

    // Case 1: buffer position has a hyperlink stored in the buffer
    const auto attr = buffer.GetCellDataAt(bufferPos)->TextAttr();
    if (attr.IsHyperlink())
    {
        return buffer.GetHyperlinkUriFromId(attr.GetHyperlinkId());
    }

    // Case 2: buffer position may point to an auto-detected hyperlink
    // Check cached interval tree (covers visible viewport +/- viewport height)
    if (const auto results = _patternIntervalTree.findOverlapping({ bufferPos.x + 1, bufferPos.y }, bufferPos); !results.empty())
    {
        for (const auto& result : results)
        {
            if (result.value == _hyperlinkPatternId)
            {
                return buffer.GetPlainText(result.start, result.stop);
            }
        }
    }
    return {};
}

// Method Description:
// - Gets the hyperlink ID of the text at the given terminal position
// Arguments:
// - The position of the text relative to the viewport
// Return value:
// - The hyperlink ID
uint16_t Terminal::GetHyperlinkIdAtViewportPosition(const til::point viewportPos)
{
    return _activeBuffer().GetCellDataAt(_ConvertToBufferCell(viewportPos, false))->TextAttr().GetHyperlinkId();
}

// Method description:
// - Given a position in a URI pattern, gets the start and end coordinates of the URI
// Arguments:
// - The position relative to the viewport
// Return value: