Skip to content

Commit 02f8e5c

Browse files
committed
PRE-MERGE #18106 Make selection an exclusive range
2 parents b2ac328 + 260dc99 commit 02f8e5c

30 files changed

+739
-279
lines changed

.github/actions/spelling/expect/expect.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ CBN
163163
cbt
164164
Ccc
165165
CCCBB
166+
CCCDDD
166167
cch
167168
CCHAR
168169
CCmd
@@ -369,6 +370,7 @@ DColor
369370
dcommon
370371
DComposition
371372
dde
373+
DDDCCC
372374
DDESHARE
373375
DDevice
374376
DEADCHAR

src/buffer/out/Row.cpp

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -80,19 +80,20 @@ constexpr OutIt copy_n_small(InIt first, Diff count, OutIt dest)
8080
return dest;
8181
}
8282

83-
CharToColumnMapper::CharToColumnMapper(const wchar_t* chars, const uint16_t* charOffsets, ptrdiff_t lastCharOffset, til::CoordType currentColumn) noexcept :
83+
CharToColumnMapper::CharToColumnMapper(const wchar_t* chars, const uint16_t* charOffsets, ptrdiff_t charsLength, til::CoordType currentColumn, til::CoordType columnCount) noexcept :
8484
_chars{ chars },
8585
_charOffsets{ charOffsets },
86-
_lastCharOffset{ lastCharOffset },
87-
_currentColumn{ currentColumn }
86+
_charsLength{ charsLength },
87+
_currentColumn{ currentColumn },
88+
_columnCount{ columnCount }
8889
{
8990
}
9091

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

9798
// This code needs to fulfill two conditions on top of the obvious (a forward/backward search):
9899
// A: We never want to stop on a column that is marked with CharOffsetsTrailer (= "GetLeadingColumn").
@@ -130,10 +131,14 @@ til::CoordType CharToColumnMapper::GetLeadingColumnAt(ptrdiff_t targetOffset) no
130131
til::CoordType CharToColumnMapper::GetTrailingColumnAt(ptrdiff_t offset) noexcept
131132
{
132133
auto col = GetLeadingColumnAt(offset);
133-
// This loop is a little redundant with the forward search loop in GetLeadingColumnAt()
134-
// but it's realistically not worth caring about this. This code is not a bottleneck.
135-
for (; WI_IsFlagSet(_charOffsets[col + 1], CharOffsetsTrailer); ++col)
134+
135+
if (col < _columnCount)
136136
{
137+
// This loop is a little redundant with the forward search loop in GetLeadingColumnAt()
138+
// but it's realistically not worth caring about this. This code is not a bottleneck.
139+
for (; WI_IsFlagSet(_charOffsets[col + 1], CharOffsetsTrailer); ++col)
140+
{
141+
}
137142
}
138143
return col;
139144
}
@@ -1114,6 +1119,9 @@ std::wstring_view ROW::GetText() const noexcept
11141119
return { _chars.data(), width };
11151120
}
11161121

1122+
// Arguments:
1123+
// - columnBegin: inclusive
1124+
// - columnEnd: exclusive
11171125
std::wstring_view ROW::GetText(til::CoordType columnBegin, til::CoordType columnEnd) const noexcept
11181126
{
11191127
const auto columns = GetReadableColumnCount();
@@ -1219,15 +1227,15 @@ T ROW::_adjustForward(T column) const noexcept
12191227
}
12201228

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

12331241
const std::optional<ScrollbarData>& ROW::GetScrollbarData() const noexcept

src/buffer/out/Row.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ struct RowCopyTextFromState
7171
// into a ROW's text this class can tell you what cell that pointer belongs to.
7272
struct CharToColumnMapper
7373
{
74-
CharToColumnMapper(const wchar_t* chars, const uint16_t* charOffsets, ptrdiff_t lastCharOffset, til::CoordType currentColumn) noexcept;
74+
CharToColumnMapper(const wchar_t* chars, const uint16_t* charOffsets, ptrdiff_t lastCharOffset, til::CoordType currentColumn, til::CoordType columnCount) noexcept;
7575

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

8686
const wchar_t* _chars;
8787
const uint16_t* _charOffsets;
88-
ptrdiff_t _lastCharOffset;
88+
ptrdiff_t _charsLength;
8989
til::CoordType _currentColumn;
90+
til::CoordType _columnCount;
9091
};
9192

9293
class ROW final

src/buffer/out/UTextAdapter.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -411,16 +411,13 @@ Microsoft::Console::ICU::unique_uregex Microsoft::Console::ICU::CreateRegex(cons
411411
return unique_uregex{ re };
412412
}
413413

414-
// Returns an inclusive point range given a text start and end position.
414+
// Returns a half-open [beg,end) range given a text start and end position.
415415
// This function is designed to be used with uregex_start64/uregex_end64.
416416
til::point_span Microsoft::Console::ICU::BufferRangeFromMatch(UText* ut, URegularExpression* re)
417417
{
418418
UErrorCode status = U_ZERO_ERROR;
419419
const auto nativeIndexBeg = uregex_start64(re, 0, &status);
420-
auto nativeIndexEnd = uregex_end64(re, 0, &status);
421-
422-
// The parameters are given as a half-open [beg,end) range, but the point_span we return in closed [beg,end].
423-
nativeIndexEnd--;
420+
const auto nativeIndexEnd = uregex_end64(re, 0, &status);
424421

425422
const auto& textBuffer = *static_cast<const TextBuffer*>(ut->context);
426423
til::point_span ret;
@@ -439,7 +436,7 @@ til::point_span Microsoft::Console::ICU::BufferRangeFromMatch(UText* ut, URegula
439436
if (utextAccess(ut, nativeIndexEnd, true))
440437
{
441438
const auto y = accessCurrentRow(ut);
442-
ret.end.x = textBuffer.GetRowByOffset(y).GetTrailingColumnAtCharOffset(ut->chunkOffset);
439+
ret.end.x = textBuffer.GetRowByOffset(y).GetLeadingColumnAtCharOffset(ut->chunkOffset);
443440
ret.end.y = y;
444441
}
445442
else

0 commit comments

Comments
 (0)