Skip to content

Commit

Permalink
PRE-MERGE #18106 Make selection an exclusive range
Browse files Browse the repository at this point in the history
  • Loading branch information
carlos-zamora committed Jan 20, 2025
2 parents b2ac328 + 260dc99 commit 02f8e5c
Show file tree
Hide file tree
Showing 30 changed files with 739 additions and 279 deletions.
2 changes: 2 additions & 0 deletions .github/actions/spelling/expect/expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ CBN
cbt
Ccc
CCCBB
CCCDDD
cch
CCHAR
CCmd
Expand Down Expand Up @@ -369,6 +370,7 @@ DColor
dcommon
DComposition
dde
DDDCCC
DDESHARE
DDevice
DEADCHAR
Expand Down
28 changes: 18 additions & 10 deletions src/buffer/out/Row.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,19 +80,20 @@ constexpr OutIt copy_n_small(InIt first, Diff count, OutIt dest)
return dest;
}

CharToColumnMapper::CharToColumnMapper(const wchar_t* chars, const uint16_t* charOffsets, ptrdiff_t lastCharOffset, til::CoordType currentColumn) noexcept :
CharToColumnMapper::CharToColumnMapper(const wchar_t* chars, const uint16_t* charOffsets, ptrdiff_t charsLength, til::CoordType currentColumn, til::CoordType columnCount) noexcept :
_chars{ chars },
_charOffsets{ charOffsets },
_lastCharOffset{ lastCharOffset },
_currentColumn{ currentColumn }
_charsLength{ charsLength },
_currentColumn{ currentColumn },
_columnCount{ columnCount }
{
}

// If given a position (`offset`) inside the ROW's text, this function will return the corresponding column.
// This function in particular returns the glyph's first column.
til::CoordType CharToColumnMapper::GetLeadingColumnAt(ptrdiff_t targetOffset) noexcept
{
targetOffset = clamp(targetOffset, 0, _lastCharOffset);
targetOffset = clamp(targetOffset, 0, _charsLength);

// This code needs to fulfill two conditions on top of the obvious (a forward/backward search):
// A: We never want to stop on a column that is marked with CharOffsetsTrailer (= "GetLeadingColumn").
Expand Down Expand Up @@ -130,10 +131,14 @@ til::CoordType CharToColumnMapper::GetLeadingColumnAt(ptrdiff_t targetOffset) no
til::CoordType CharToColumnMapper::GetTrailingColumnAt(ptrdiff_t offset) noexcept
{
auto col = GetLeadingColumnAt(offset);
// This loop is a little redundant with the forward search loop in GetLeadingColumnAt()
// but it's realistically not worth caring about this. This code is not a bottleneck.
for (; WI_IsFlagSet(_charOffsets[col + 1], CharOffsetsTrailer); ++col)

if (col < _columnCount)
{
// This loop is a little redundant with the forward search loop in GetLeadingColumnAt()
// but it's realistically not worth caring about this. This code is not a bottleneck.
for (; WI_IsFlagSet(_charOffsets[col + 1], CharOffsetsTrailer); ++col)
{
}
}
return col;
}
Expand Down Expand Up @@ -1114,6 +1119,9 @@ std::wstring_view ROW::GetText() const noexcept
return { _chars.data(), width };
}

// Arguments:
// - columnBegin: inclusive
// - columnEnd: exclusive
std::wstring_view ROW::GetText(til::CoordType columnBegin, til::CoordType columnEnd) const noexcept
{
const auto columns = GetReadableColumnCount();
Expand Down Expand Up @@ -1219,15 +1227,15 @@ T ROW::_adjustForward(T column) const noexcept
}

// Creates a CharToColumnMapper given an offset into _chars.data().
// In other words, for a 120 column ROW with just ASCII text, the offset should be [0,120).
// In other words, for a 120 column ROW with just ASCII text, the offset should be [0,120].
CharToColumnMapper ROW::_createCharToColumnMapper(ptrdiff_t offset) const noexcept
{
const auto charsSize = _charSize();
const auto lastChar = gsl::narrow_cast<ptrdiff_t>(charsSize - 1);
const auto lastChar = gsl::narrow_cast<ptrdiff_t>(charsSize);
// We can sort of guess what column belongs to what offset because BMP glyphs are very common and
// UTF-16 stores them in 1 char. In other words, usually a ROW will have N chars for N columns.
const auto guessedColumn = gsl::narrow_cast<til::CoordType>(clamp(offset, 0, _columnCount));
return CharToColumnMapper{ _chars.data(), _charOffsets.data(), lastChar, guessedColumn };
return CharToColumnMapper{ _chars.data(), _charOffsets.data(), lastChar, guessedColumn, _columnCount };
}

const std::optional<ScrollbarData>& ROW::GetScrollbarData() const noexcept
Expand Down
5 changes: 3 additions & 2 deletions src/buffer/out/Row.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ struct RowCopyTextFromState
// into a ROW's text this class can tell you what cell that pointer belongs to.
struct CharToColumnMapper
{
CharToColumnMapper(const wchar_t* chars, const uint16_t* charOffsets, ptrdiff_t lastCharOffset, til::CoordType currentColumn) noexcept;
CharToColumnMapper(const wchar_t* chars, const uint16_t* charOffsets, ptrdiff_t lastCharOffset, til::CoordType currentColumn, til::CoordType columnCount) noexcept;

til::CoordType GetLeadingColumnAt(ptrdiff_t targetOffset) noexcept;
til::CoordType GetTrailingColumnAt(ptrdiff_t offset) noexcept;
Expand All @@ -85,8 +85,9 @@ struct CharToColumnMapper

const wchar_t* _chars;
const uint16_t* _charOffsets;
ptrdiff_t _lastCharOffset;
ptrdiff_t _charsLength;
til::CoordType _currentColumn;
til::CoordType _columnCount;
};

class ROW final
Expand Down
9 changes: 3 additions & 6 deletions src/buffer/out/UTextAdapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -411,16 +411,13 @@ Microsoft::Console::ICU::unique_uregex Microsoft::Console::ICU::CreateRegex(cons
return unique_uregex{ re };
}

// Returns an inclusive point range given a text start and end position.
// Returns a half-open [beg,end) range given a text start and end position.
// This function is designed to be used with uregex_start64/uregex_end64.
til::point_span Microsoft::Console::ICU::BufferRangeFromMatch(UText* ut, URegularExpression* re)
{
UErrorCode status = U_ZERO_ERROR;
const auto nativeIndexBeg = uregex_start64(re, 0, &status);
auto nativeIndexEnd = uregex_end64(re, 0, &status);

// The parameters are given as a half-open [beg,end) range, but the point_span we return in closed [beg,end].
nativeIndexEnd--;
const auto nativeIndexEnd = uregex_end64(re, 0, &status);

const auto& textBuffer = *static_cast<const TextBuffer*>(ut->context);
til::point_span ret;
Expand All @@ -439,7 +436,7 @@ til::point_span Microsoft::Console::ICU::BufferRangeFromMatch(UText* ut, URegula
if (utextAccess(ut, nativeIndexEnd, true))
{
const auto y = accessCurrentRow(ut);
ret.end.x = textBuffer.GetRowByOffset(y).GetTrailingColumnAtCharOffset(ut->chunkOffset);
ret.end.x = textBuffer.GetRowByOffset(y).GetLeadingColumnAtCharOffset(ut->chunkOffset);
ret.end.y = y;
}
else
Expand Down
Loading

0 comments on commit 02f8e5c

Please sign in to comment.