Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reimplement TextBuffer::Reflow #15701

Merged
merged 16 commits into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/actions/spelling/expect/expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2280,6 +2280,7 @@ YCast
YCENTER
YCount
YDPI
YLimit
YOffset
YSubstantial
YVIRTUALSCREEN
Expand Down
38 changes: 32 additions & 6 deletions src/buffer/out/Row.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -364,11 +364,16 @@ void ROW::TransferAttributes(const til::small_rle<TextAttribute, uint16_t, 1>& a

void ROW::CopyFrom(const ROW& source)
{
RowCopyTextFromState state{ .source = source };
CopyTextFrom(state);
TransferAttributes(source.Attributes(), _columnCount);
_lineRendition = source._lineRendition;
_wrapForced = source._wrapForced;

RowCopyTextFromState state{
.source = source,
.sourceColumnLimit = source.GetReadableColumnCount(),
};
CopyTextFrom(state);

TransferAttributes(source.Attributes(), _columnCount);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change ensures that we take the line rendition into account when determining the capacity of the row in CopyTextFrom.

}

// Returns the previous possible cursor position, preceding the given column.
Expand All @@ -382,7 +387,17 @@ til::CoordType ROW::NavigateToPrevious(til::CoordType column) const noexcept
// Returns the row width if column is beyond the width of the row.
til::CoordType ROW::NavigateToNext(til::CoordType column) const noexcept
{
return _adjustForward(_clampedColumn(column + 1));
return _adjustForward(_clampedColumnInclusive(column + 1));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will allow us to "navigate" the cursor into the past-the-end column.

}

til::CoordType ROW::AdjustBackward(til::CoordType column) const noexcept
{
return _adjustBackward(_clampedColumn(column));
}

til::CoordType ROW::AdjustForward(til::CoordType column) const noexcept
{
return _adjustForward(_clampedColumnInclusive(column));
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These might warrant a comment as to why they're different than the Navigate* versions. If I'm reading this right:

  • the Navigate ones act like "move one cell forward/backward, then find the end/start of the glyph in that cell"
  • while the Adjust ones are just "find the end/start of the glyph in THIS cell"

correct?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep.

I've removed AdjustForward (it's unused) and renamed AdjustBackward to AdjustToGlyphStart and added a comment. That should hopefully make it easier to read the code.


// Routine Description:
Expand Down Expand Up @@ -719,11 +734,12 @@ try
if (sourceColBeg < sourceColLimit)
{
charOffsets = source._charOffsets.subspan(sourceColBeg, static_cast<size_t>(sourceColLimit) - sourceColBeg + 1);
const auto charsOffset = charOffsets.front() & CharOffsetsMask;
const auto beg = size_t{ charOffsets.front() } & CharOffsetsMask;
const auto end = size_t{ charOffsets.back() } & CharOffsetsMask;
// We _are_ using span. But C++ decided that string_view and span aren't convertible.
// _chars is a std::span for performance and because it refers to raw, shared memory.
#pragma warning(suppress : 26481) // Don't use pointer arithmetic. Use span instead (bounds.1).
chars = { source._chars.data() + charsOffset, source._chars.size() - charsOffset };
chars = { source._chars.data() + beg, end - beg };
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a h.charsConsumed == chars.size() check at the end of this function. That check only works if the chars.size() is correct, which this change now fixes. The string will now contain the exact amount of text we're allowed to copy.

}

WriteHelper h{ *this, state.columnBegin, state.columnLimit, chars };
Expand Down Expand Up @@ -939,6 +955,16 @@ til::CoordType ROW::MeasureLeft() const noexcept

til::CoordType ROW::MeasureRight() const noexcept
{
if (_wrapForced)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

brilliant

{
auto width = _columnCount;
if (_doubleBytePadded)
{
width--;
}
return width;
}

const auto text = GetText();
const auto beg = text.begin();
const auto end = text.end();
Expand Down
2 changes: 2 additions & 0 deletions src/buffer/out/Row.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ class ROW final

til::CoordType NavigateToPrevious(til::CoordType column) const noexcept;
til::CoordType NavigateToNext(til::CoordType column) const noexcept;
til::CoordType AdjustBackward(til::CoordType column) const noexcept;
til::CoordType AdjustForward(til::CoordType column) const noexcept;

void ClearCell(til::CoordType column);
OutputCellIterator WriteCells(OutputCellIterator it, til::CoordType columnBegin, std::optional<bool> wrap = std::nullopt, std::optional<til::CoordType> limitRight = std::nullopt);
Expand Down
Loading