diff --git a/.github/actions/spell-check/whitelist/whitelist.txt b/.github/actions/spell-check/whitelist/whitelist.txt index 0dd7b3477bb..f71dde01479 100644 --- a/.github/actions/spell-check/whitelist/whitelist.txt +++ b/.github/actions/spell-check/whitelist/whitelist.txt @@ -1,5 +1,7 @@ AAAAAABBBBBBCCC AAAAABBBBBBBCCC +AAAAABCCCCCCCCC +AAAAADCCCCCCCCC AAD ABANDONFONT ABCDEFGHIJKLMNO diff --git a/src/buffer/out/AttrRow.cpp b/src/buffer/out/AttrRow.cpp index b67789576ed..89cd1e1d441 100644 --- a/src/buffer/out/AttrRow.cpp +++ b/src/buffer/out/AttrRow.cpp @@ -280,7 +280,7 @@ void ATTR_ROW::ReplaceAttrs(const TextAttribute& toBeReplacedAttr, const TextAtt } // .. otherwise if we internally have a list of 2 or more and we're about to insert a single color // it's possible that we just walk left-to-right through the row and find a quick exit. - else if (iStart > 0 && iStart == iEnd) + else if (iStart >= 0 && iStart == iEnd) { // First we try to find the run where the insertion happens, using lowerBound and upperBound to track // where we are currently at. @@ -306,8 +306,22 @@ void ATTR_ROW::ReplaceAttrs(const TextAttribute& toBeReplacedAttr, const TextAtt return S_OK; } + // If the current run has length of exactly one, we can simply change the attribute + // of the current run. + // e.g. + // AAAAABCCCCCCCCC + // ^ + // AAAAADCCCCCCCCC + // + // Here 'D' is the new color. + if (curr->GetLength() == 1) + { + curr->SetAttributes(NewAttr); + return S_OK; + } + // If the insertion happens at current run's lower boundary... - if (iStart == lowerBound) + if (iStart == lowerBound && i > 0) { const auto prev = std::prev(curr, 1); // ... and the previous run has the same color as the new one, we can @@ -332,6 +346,32 @@ void ATTR_ROW::ReplaceAttrs(const TextAttribute& toBeReplacedAttr, const TextAtt return S_OK; } } + + // If the insertion happens at current run's upper boundary... + if (iStart == upperBound - 1 && i + 1 < _list.size()) + { + // ...then let's try our luck with the next run if possible. This is basically the opposite + // of what we did with the previous run. + // e.g. + // AAAAAABBBBBBCCC + // ^ + // AAAAABBBBBBBCCC + // + // Here 'B' is the new color. + const auto next = std::next(curr, 1); + if (NewAttr == next->GetAttributes()) + { + curr->DecrementLength(); + next->IncrementLength(); + + if (curr->GetLength() == 0) + { + _list.erase(curr); + } + + return S_OK; + } + } } // Advance one run in the _list.