Repository: microsoft/terminal
File: src/buffer/out/AttrRow.cpp (C++)

Code before:

// Routine Description:
// - Finds the hyperlink IDs present in this row and returns them
// Return value:
// - An unordered set containing the hyperlink IDs present in this row
std::unordered_set<uint16_t> ATTR_ROW::GetHyperlinks()
{
    std::unordered_set<uint16_t> ids;
    for (const auto& run : _list)
    {
        if (run.GetAttributes().IsHyperlink())
        {
            ids.emplace(run.GetAttributes().GetHyperlinkId());
        }
    }
    return ids;
}

// Method description:
// - Gets the start and endpoint of a particular link in this row, ignoring other attributes
// - Use this to get the full hyperlinked text from just one cell (for example, if the user hovers over a
//   cell in the middle of a link and we need the entire link)
// Arguments:
// - The column in the link
// Return value:
// - A pair where the first value is the start point and the second value is the endpoint of the link
const std::pair<size_t, size_t> ATTR_ROW::GetLinkEndPoints(size_t column)
{
    const auto runPos = FindAttrIndex(column, nullptr);
    const auto id = _list.at(runPos).GetAttributes().GetHyperlinkId();
    size_t startPos = 0;
    for (size_t i = 0; i < runPos; i++)
    {
        startPos += _list.at(i).GetLength();
    }
    size_t endPos = startPos + _list.at(runPos).GetLength();

    // the link might extend to before this specific run, so check for that
    for (auto it = _list.rend() - runPos; it != _list.rend(); ++it)
    {
        if (it->GetAttributes().GetHyperlinkId() == id)
        {
            startPos -= it->GetLength();
        }
        else
        {
            // the moment we hit a region with a different hyperlink id, we break
            break;
        }
    }
    // the link might also extend to after this specific run, so check for that

Review comment (suggestion):
**NOTE**

Currently, this function is not called anywhere. I wrote it because I thought it might be useful to have the border cover the entire link instead of the cell that the user is hovering over, but we do not actually need that for now. 

Regardless, I thought this function could potentially be useful in the future so I left it in. Can remove it if anyone feels strongly about it!

Code after:

// Routine Description:
// - Finds the hyperlink IDs present in this row and returns them
// Return value:
// - An unordered set containing the hyperlink IDs present in this row
std::unordered_set<uint16_t> ATTR_ROW::GetHyperlinks()
{
    std::unordered_set<uint16_t> ids;
    for (const auto& run : _list)
    {
        if (run.GetAttributes().IsHyperlink())
        {
            ids.emplace(run.GetAttributes().GetHyperlinkId());
        }
    }
    return ids;
}

// Routine Description:
// - Sets the attributes (colors) of all character positions from the given position through the end of the row.
// Arguments:
// - iStart - Starting index position within the row
// - attr - Attribute (color) to fill remaining characters with
// Return Value:
// - <none>
bool ATTR_ROW::SetAttrToEnd(const UINT iStart, const TextAttribute attr)
{
    size_t const length = _cchRowWidth - iStart;

    const TextAttributeRun run(length, attr);
    return SUCCEEDED(InsertAttrRuns({ &run, 1 }, iStart, _cchRowWidth - 1, _cchRowWidth));
}

// Method Description:
// - Replaces all runs in the row with the given toBeReplacedAttr with the new
//      attribute replaceWith.
// Arguments:
// - toBeReplacedAttr - the attribute to replace in this row.
// - replaceWith - the new value for the matching runs' attributes.
// Return Value:
// - <none>
void ATTR_ROW::ReplaceAttrs(const TextAttribute& toBeReplacedAttr, const TextAttribute& replaceWith) noexcept
{
    for (auto& run : _list)
    {
        if (run.GetAttributes() == toBeReplacedAttr)
        {
            run.SetAttributes(replaceWith);
        }
    }
}