diff --git a/src/interactivity/win32/ut_interactivity_win32/GeneratedUiaTextRangeMovementTests.g.cpp b/src/interactivity/win32/ut_interactivity_win32/GeneratedUiaTextRangeMovementTests.g.cpp index 34cffaf97..a1339bb8c 100644 --- a/src/interactivity/win32/ut_interactivity_win32/GeneratedUiaTextRangeMovementTests.g.cpp +++ b/src/interactivity/win32/ut_interactivity_win32/GeneratedUiaTextRangeMovementTests.g.cpp @@ -89,7 +89,9 @@ constexpr til::point segment1LmidHistory{ segment1, midHistory.y() }; constexpr til::point segment1LmidTop{ segment1, midTop.y() }; constexpr til::point segment1LmidTopP1L{ segment1, midTopP1L.y() }; constexpr til::point segment2LmidDocEnd{ segment2, midDocEnd.y() }; +constexpr til::point segment2LmidDocEndM1L{ segment2, midDocEndM1L.y() }; constexpr til::point segment2LmidHistory{ segment2, midHistory.y() }; +constexpr til::point segment2LmidHistoryM1L{ segment2, midHistoryM1L.y() }; constexpr til::point segment2LmidHistoryP1L{ segment2, midHistoryP1L.y() }; constexpr til::point segment2LmidTop{ segment2, midTop.y() }; constexpr til::point segment2LmidTopP1L{ segment2, midTopP1L.y() }; @@ -102,9 +104,7 @@ constexpr til::point segment3LmidTop{ segment3, midTop.y() }; constexpr til::point segment3LmidTopP1L{ segment3, midTopP1L.y() }; constexpr til::point segment4LlastCharPosM1L{ segment4, lastCharPosM1L.y() }; constexpr til::point segment4LmidDocEnd{ segment4, midDocEnd.y() }; -constexpr til::point segment4LmidDocEndM1L{ segment4, midDocEndM1L.y() }; constexpr til::point segment4LmidHistory{ segment4, midHistory.y() }; -constexpr til::point segment4LmidHistoryM1L{ segment4, midHistoryM1L.y() }; constexpr til::point segment4LmidTop{ segment4, midTop.y() }; struct GeneratedMovementTestInput { @@ -3319,7 +3319,7 @@ static constexpr std::array s_movementTests{ -3, origin, origin }, - true }, + false }, GeneratedMovementTest{ L"Move degenerate range at position 2 -1 times by Word", GeneratedMovementTestInput{ @@ -3331,7 +3331,7 @@ static constexpr std::array s_movementTests{ -1, segment2LmidTop, segment2LmidTop }, - true }, + false }, GeneratedMovementTest{ L"Move degenerate range at position 2 0 times by Word", GeneratedMovementTestInput{ @@ -3439,7 +3439,7 @@ static constexpr std::array s_movementTests{ -5, segment3LmidHistoryM1L, segment3LmidHistoryM1L }, - true }, + false }, GeneratedMovementTest{ L"Move degenerate range at position 3 -1 times by Word", GeneratedMovementTestInput{ @@ -3451,7 +3451,7 @@ static constexpr std::array s_movementTests{ -1, segment2LmidHistory, segment2LmidHistory }, - true }, + false }, GeneratedMovementTest{ L"Move degenerate range at position 3 0 times by Word", GeneratedMovementTestInput{ @@ -3497,9 +3497,9 @@ static constexpr std::array s_movementTests{ midHistoryP1C }, GeneratedMovementTestExpected{ -5, - segment3LmidHistoryM1L, - segment4LmidHistoryM1L }, - true }, + segment2LmidHistoryM1L, + segment3LmidHistoryM1L }, + false }, GeneratedMovementTest{ L"Move non-degenerate range at position 3 -1 times by Word", GeneratedMovementTestInput{ @@ -3559,7 +3559,7 @@ static constexpr std::array s_movementTests{ -5, segment3LmidDocEndM1L, segment3LmidDocEndM1L }, - true }, + false }, GeneratedMovementTest{ L"Move degenerate range at position 4 -1 times by Word", GeneratedMovementTestInput{ @@ -3571,7 +3571,7 @@ static constexpr std::array s_movementTests{ -1, segment2LmidDocEnd, segment2LmidDocEnd }, - true }, + false }, GeneratedMovementTest{ L"Move degenerate range at position 4 0 times by Word", GeneratedMovementTestInput{ @@ -3617,9 +3617,9 @@ static constexpr std::array s_movementTests{ midDocEndP1C }, GeneratedMovementTestExpected{ -5, - segment3LmidDocEndM1L, - segment4LmidDocEndM1L }, - true }, + segment2LmidDocEndM1L, + segment3LmidDocEndM1L }, + false }, GeneratedMovementTest{ L"Move non-degenerate range at position 4 -1 times by Word", GeneratedMovementTestInput{ @@ -3679,7 +3679,7 @@ static constexpr std::array s_movementTests{ -5, lastCharPosLeft, lastCharPosLeft }, - true }, + false }, GeneratedMovementTest{ L"Move degenerate range at position 5 -1 times by Word", GeneratedMovementTestInput{ @@ -3691,7 +3691,7 @@ static constexpr std::array s_movementTests{ -1, segment4LmidDocEnd, segment4LmidDocEnd }, - true }, + false }, GeneratedMovementTest{ L"Move degenerate range at position 5 0 times by Word", GeneratedMovementTestInput{ @@ -3799,7 +3799,7 @@ static constexpr std::array s_movementTests{ -5, midDocEndLeft, midDocEndLeft }, - true }, + false }, GeneratedMovementTest{ L"Move degenerate range at position 6 -1 times by Word", GeneratedMovementTestInput{ @@ -3811,7 +3811,7 @@ static constexpr std::array s_movementTests{ -1, segment4LmidDocEnd, segment4LmidDocEnd }, - true }, + false }, GeneratedMovementTest{ L"Move degenerate range at position 6 0 times by Word", GeneratedMovementTestInput{ @@ -3859,7 +3859,7 @@ static constexpr std::array s_movementTests{ -5, midDocEndLeft, midDocEndLeft }, - true }, + false }, GeneratedMovementTest{ L"Move non-degenerate range at position 6 -1 times by Word", GeneratedMovementTestInput{ @@ -3871,7 +3871,7 @@ static constexpr std::array s_movementTests{ -1, segment4LmidDocEnd, segment4LmidDocEnd }, - true }, + false }, GeneratedMovementTest{ L"Move non-degenerate range at position 6 0 times by Word", GeneratedMovementTestInput{ @@ -3919,7 +3919,7 @@ static constexpr std::array s_movementTests{ -5, midDocEndLeft, midDocEndLeft }, - true }, + false }, GeneratedMovementTest{ L"Move degenerate range at position 7 -1 times by Word", GeneratedMovementTestInput{ @@ -3931,7 +3931,7 @@ static constexpr std::array s_movementTests{ -1, segment4LmidDocEnd, segment4LmidDocEnd }, - true }, + false }, GeneratedMovementTest{ L"Move degenerate range at position 7 0 times by Word", GeneratedMovementTestInput{ @@ -3979,7 +3979,7 @@ static constexpr std::array s_movementTests{ -5, midDocEndLeft, midDocEndLeft }, - true }, + false }, GeneratedMovementTest{ L"Move non-degenerate range at position 7 -1 times by Word", GeneratedMovementTestInput{ @@ -3991,7 +3991,7 @@ static constexpr std::array s_movementTests{ -1, segment4LmidDocEnd, segment4LmidDocEnd }, - true }, + false }, GeneratedMovementTest{ L"Move non-degenerate range at position 7 0 times by Word", GeneratedMovementTestInput{ @@ -4039,7 +4039,7 @@ static constexpr std::array s_movementTests{ -5, midDocEndLeft, midDocEndLeft }, - true }, + false }, GeneratedMovementTest{ L"Move degenerate range at position 8 -1 times by Word", GeneratedMovementTestInput{ @@ -4051,7 +4051,7 @@ static constexpr std::array s_movementTests{ -1, segment4LmidDocEnd, segment4LmidDocEnd }, - true }, + false }, GeneratedMovementTest{ L"Move degenerate range at position 8 0 times by Word", GeneratedMovementTestInput{ @@ -4099,7 +4099,7 @@ static constexpr std::array s_movementTests{ -5, midDocEndLeft, midDocEndLeft }, - true }, + false }, GeneratedMovementTest{ L"Move non-degenerate range at position 8 -1 times by Word", GeneratedMovementTestInput{ @@ -4111,7 +4111,7 @@ static constexpr std::array s_movementTests{ -1, segment4LmidDocEnd, segment4LmidDocEnd }, - true }, + false }, GeneratedMovementTest{ L"Move non-degenerate range at position 8 0 times by Word", GeneratedMovementTestInput{ @@ -4159,7 +4159,7 @@ static constexpr std::array s_movementTests{ -5, midDocEndLeft, midDocEndLeft }, - true }, + false }, GeneratedMovementTest{ L"Move degenerate range at position 9 -1 times by Word", GeneratedMovementTestInput{ @@ -4171,7 +4171,7 @@ static constexpr std::array s_movementTests{ -1, segment4LmidDocEnd, segment4LmidDocEnd }, - true }, + false }, GeneratedMovementTest{ L"Move degenerate range at position 9 0 times by Word", GeneratedMovementTestInput{ diff --git a/src/interactivity/win32/ut_interactivity_win32/UiaTextRangeTests.cpp b/src/interactivity/win32/ut_interactivity_win32/UiaTextRangeTests.cpp index 816913825..99ae12628 100644 --- a/src/interactivity/win32/ut_interactivity_win32/UiaTextRangeTests.cpp +++ b/src/interactivity/win32/ut_interactivity_win32/UiaTextRangeTests.cpp @@ -1417,11 +1417,13 @@ class UiaTextRangeTests // reset the UTR if (degenerate) { + // UTR: (exclusive, exclusive) range const auto utrStart{ atDocumentEnd ? documentEndExclusive : endExclusive }; THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize(&utr, _pUiaData, &_dummyProvider, utrStart, utrEnd)); } else { + // UTR: (inclusive, exclusive) range const auto utrStart{ atDocumentEnd ? documentEndInclusive : endInclusive }; THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize(&utr, _pUiaData, &_dummyProvider, utrStart, utrEnd)); } @@ -1443,8 +1445,8 @@ class UiaTextRangeTests else if (textUnit <= TextUnit::TextUnit_Word) { VERIFY_ARE_EQUAL(-1, moveAmt); - VERIFY_ARE_EQUAL(origin, til::point{ utr->_start }); - VERIFY_ARE_EQUAL(degenerate || !atDocumentEnd ? origin : writeTarget, til::point{ utr->_end }); + VERIFY_ARE_EQUAL(degenerate || !atDocumentEnd ? writeTarget : origin, til::point{ utr->_start }); + VERIFY_ARE_EQUAL(writeTarget, til::point{ utr->_end }); } else if (textUnit <= TextUnit::TextUnit_Line) { diff --git a/src/types/UiaTextRangeBase.cpp b/src/types/UiaTextRangeBase.cpp index ace7002c2..860dabcd7 100644 --- a/src/types/UiaTextRangeBase.cpp +++ b/src/types/UiaTextRangeBase.cpp @@ -1522,6 +1522,14 @@ void UiaTextRangeBase::_moveEndpointByUnitWord(_In_ const int moveCount, { success = false; } + else if (allowBottomExclusive && _tryMoveToWordStart(buffer, documentEnd, resultPos)) + { + // IMPORTANT: _tryMoveToWordStart modifies resultPos if successful + // Degenerate ranges first move to the beginning of the word, + // but if we're already at the beginning of the word, we continue + // to the next branch and move to the previous word! + (*pAmountMoved)--; + } else if (buffer.MoveToPreviousWord(nextPos, _wordDelimiters)) { resultPos = nextPos; @@ -1541,6 +1549,26 @@ void UiaTextRangeBase::_moveEndpointByUnitWord(_In_ const int moveCount, SetEndpoint(endpoint, resultPos); } +// Routine Description: +// - tries to move resultingPos to the beginning of the word +// Arguments: +// - buffer - the text buffer we're operating on +// - documentEnd - the document end of the buffer (see _getDocumentEnd()) +// - resultingPos - the position we're starting from and modifying +// Return Value: +// - true --> we were not at the beginning of the word, and we updated resultingPos to be so +// - false --> otherwise (we're already at the beginning of the word) +bool UiaTextRangeBase::_tryMoveToWordStart(const TextBuffer& buffer, const til::point documentEnd, COORD& resultingPos) const +{ + const auto wordStart{ buffer.GetWordStart(resultingPos, _wordDelimiters, true, documentEnd) }; + if (resultingPos != wordStart) + { + resultingPos = wordStart; + return true; + } + return false; +} + // Routine Description: // - moves the UTR's endpoint by moveCount times by line. // - if endpoints crossed, the degenerate range is created and both endpoints are moved diff --git a/src/types/UiaTextRangeBase.hpp b/src/types/UiaTextRangeBase.hpp index b3a171b98..24756648f 100644 --- a/src/types/UiaTextRangeBase.hpp +++ b/src/types/UiaTextRangeBase.hpp @@ -182,6 +182,7 @@ namespace Microsoft::Console::Types std::optional _verifyAttr(TEXTATTRIBUTEID attributeId, VARIANT val, const TextAttribute& attr) const; bool _initializeAttrQuery(TEXTATTRIBUTEID attributeId, VARIANT* pRetVal, const TextAttribute& attr) const; + bool _tryMoveToWordStart(const TextBuffer& buffer, const til::point documentEnd, COORD& resultingPos) const; COORD _getInclusiveEnd() noexcept; diff --git a/tools/TestTableWriter/UiaTests.csv b/tools/TestTableWriter/UiaTests.csv index 088283b25..44108c96a 100644 --- a/tools/TestTableWriter/UiaTests.csv +++ b/tools/TestTableWriter/UiaTests.csv @@ -264,8 +264,8 @@ FALSE,1,TextUnit_Word,-1,origin,originP1C,0,origin,segment1LmidTop,FALSE FALSE,1,TextUnit_Word,0,origin,originP1C,0,origin,segment1LmidTop,FALSE FALSE,1,TextUnit_Word,1,origin,originP1C,1,segment1LmidTop,segment2LmidTop,FALSE FALSE,1,TextUnit_Word,5,origin,originP1C,5,segment0LmidTopP1L,segment1LmidTopP1L,FALSE -TRUE,2,TextUnit_Word,-5,midTop,midTop,-3,origin,origin,TRUE -TRUE,2,TextUnit_Word,-1,midTop,midTop,-1,segment2LmidTop,segment2LmidTop,TRUE +TRUE,2,TextUnit_Word,-5,midTop,midTop,-3,origin,origin,FALSE +TRUE,2,TextUnit_Word,-1,midTop,midTop,-1,segment2LmidTop,segment2LmidTop,FALSE TRUE,2,TextUnit_Word,0,midTop,midTop,0,midTop,midTop,FALSE TRUE,2,TextUnit_Word,1,midTop,midTop,1,segment3LmidTop,segment3LmidTop,FALSE TRUE,2,TextUnit_Word,5,midTop,midTop,5,segment2LmidTopP1L,segment2LmidTopP1L,FALSE @@ -274,28 +274,28 @@ FALSE,2,TextUnit_Word,-1,midTop,midTopP1C,-1,segment1LmidTop,segment2LmidTop,FAL FALSE,2,TextUnit_Word,0,midTop,midTopP1C,0,segment2LmidTop,segment3LmidTop,FALSE FALSE,2,TextUnit_Word,1,midTop,midTopP1C,1,segment3LmidTop,segment4LmidTop,FALSE FALSE,2,TextUnit_Word,5,midTop,midTopP1C,5,segment2LmidTopP1L,segment3LmidTopP1L,FALSE -TRUE,3,TextUnit_Word,-5,midHistory,midHistory,-5,segment3LmidHistoryM1L,segment3LmidHistoryM1L,TRUE -TRUE,3,TextUnit_Word,-1,midHistory,midHistory,-1,segment2LmidHistory,segment2LmidHistory,TRUE +TRUE,3,TextUnit_Word,-5,midHistory,midHistory,-5,segment3LmidHistoryM1L,segment3LmidHistoryM1L,FALSE +TRUE,3,TextUnit_Word,-1,midHistory,midHistory,-1,segment2LmidHistory,segment2LmidHistory,FALSE TRUE,3,TextUnit_Word,0,midHistory,midHistory,0,midHistory,midHistory,FALSE TRUE,3,TextUnit_Word,1,midHistory,midHistory,1,segment3LmidHistory,segment3LmidHistory,FALSE TRUE,3,TextUnit_Word,5,midHistory,midHistory,5,segment2LmidHistoryP1L,segment2LmidHistoryP1L,FALSE -FALSE,3,TextUnit_Word,-5,midHistory,midHistoryP1C,-5,segment3LmidHistoryM1L,segment4LmidHistoryM1L,TRUE +FALSE,3,TextUnit_Word,-5,midHistory,midHistoryP1C,-5,segment2LmidHistoryM1L,segment3LmidHistoryM1L,FALSE FALSE,3,TextUnit_Word,-1,midHistory,midHistoryP1C,-1,segment1LmidHistory,segment2LmidHistory,FALSE FALSE,3,TextUnit_Word,0,midHistory,midHistoryP1C,0,segment2LmidHistory,segment3LmidHistory,FALSE FALSE,3,TextUnit_Word,1,midHistory,midHistoryP1C,1,segment3LmidHistory,segment4LmidHistory,FALSE FALSE,3,TextUnit_Word,5,midHistory,midHistoryP1C,5,segment2LmidHistoryP1L,segment3LmidHistoryP1L,FALSE -TRUE,4,TextUnit_Word,-5,midDocEnd,midDocEnd,-5,segment3LmidDocEndM1L,segment3LmidDocEndM1L,TRUE -TRUE,4,TextUnit_Word,-1,midDocEnd,midDocEnd,-1,segment2LmidDocEnd,segment2LmidDocEnd,TRUE +TRUE,4,TextUnit_Word,-5,midDocEnd,midDocEnd,-5,segment3LmidDocEndM1L,segment3LmidDocEndM1L,FALSE +TRUE,4,TextUnit_Word,-1,midDocEnd,midDocEnd,-1,segment2LmidDocEnd,segment2LmidDocEnd,FALSE TRUE,4,TextUnit_Word,0,midDocEnd,midDocEnd,0,midDocEnd,midDocEnd,FALSE TRUE,4,TextUnit_Word,1,midDocEnd,midDocEnd,1,segment3LmidDocEnd,segment3LmidDocEnd,FALSE TRUE,4,TextUnit_Word,5,midDocEnd,midDocEnd,3,docEnd,docEnd,FALSE -FALSE,4,TextUnit_Word,-5,midDocEnd,midDocEndP1C,-5,segment3LmidDocEndM1L,segment4LmidDocEndM1L,TRUE +FALSE,4,TextUnit_Word,-5,midDocEnd,midDocEndP1C,-5,segment2LmidDocEndM1L,segment3LmidDocEndM1L,FALSE FALSE,4,TextUnit_Word,-1,midDocEnd,midDocEndP1C,-1,segment1LmidDocEnd,segment2LmidDocEnd,FALSE FALSE,4,TextUnit_Word,0,midDocEnd,midDocEndP1C,0,segment2LmidDocEnd,segment3LmidDocEnd,FALSE FALSE,4,TextUnit_Word,1,midDocEnd,midDocEndP1C,1,segment3LmidDocEnd,segment4LmidDocEnd,FALSE FALSE,4,TextUnit_Word,5,midDocEnd,midDocEndP1C,2,segment4LmidDocEnd,docEnd,FALSE -TRUE,5,TextUnit_Word,-5,lastCharPos,lastCharPos,-5,lastCharPosLeft,lastCharPosLeft,TRUE -TRUE,5,TextUnit_Word,-1,lastCharPos,lastCharPos,-1,segment4LmidDocEnd,segment4LmidDocEnd,TRUE +TRUE,5,TextUnit_Word,-5,lastCharPos,lastCharPos,-5,lastCharPosLeft,lastCharPosLeft,FALSE +TRUE,5,TextUnit_Word,-1,lastCharPos,lastCharPos,-1,segment4LmidDocEnd,segment4LmidDocEnd,FALSE TRUE,5,TextUnit_Word,0,lastCharPos,lastCharPos,0,lastCharPos,lastCharPos,FALSE TRUE,5,TextUnit_Word,1,lastCharPos,lastCharPos,1,docEnd,docEnd,FALSE TRUE,5,TextUnit_Word,5,lastCharPos,lastCharPos,1,docEnd,docEnd,FALSE @@ -304,38 +304,38 @@ FALSE,5,TextUnit_Word,-1,lastCharPos,lastCharPosP1C,-1,segment3LmidDocEnd,segmen FALSE,5,TextUnit_Word,0,lastCharPos,lastCharPosP1C,0,segment4LmidDocEnd,docEnd,FALSE FALSE,5,TextUnit_Word,1,lastCharPos,lastCharPosP1C,0,segment4LmidDocEnd,docEnd,FALSE FALSE,5,TextUnit_Word,5,lastCharPos,lastCharPosP1C,0,segment4LmidDocEnd,docEnd,FALSE -TRUE,6,TextUnit_Word,-5,docEnd,docEnd,-5,midDocEndLeft,midDocEndLeft,TRUE -TRUE,6,TextUnit_Word,-1,docEnd,docEnd,-1,segment4LmidDocEnd,segment4LmidDocEnd,TRUE +TRUE,6,TextUnit_Word,-5,docEnd,docEnd,-5,midDocEndLeft,midDocEndLeft,FALSE +TRUE,6,TextUnit_Word,-1,docEnd,docEnd,-1,segment4LmidDocEnd,segment4LmidDocEnd,FALSE TRUE,6,TextUnit_Word,0,docEnd,docEnd,0,docEnd,docEnd,FALSE TRUE,6,TextUnit_Word,1,docEnd,docEnd,0,docEnd,docEnd,FALSE TRUE,6,TextUnit_Word,5,docEnd,docEnd,0,docEnd,docEnd,FALSE -FALSE,6,TextUnit_Word,-5,docEnd,docEndP1C,-5,midDocEndLeft,midDocEndLeft,TRUE -FALSE,6,TextUnit_Word,-1,docEnd,docEndP1C,-1,segment4LmidDocEnd,segment4LmidDocEnd,TRUE +FALSE,6,TextUnit_Word,-5,docEnd,docEndP1C,-5,midDocEndLeft,midDocEndLeft,FALSE +FALSE,6,TextUnit_Word,-1,docEnd,docEndP1C,-1,segment4LmidDocEnd,segment4LmidDocEnd,FALSE FALSE,6,TextUnit_Word,0,docEnd,docEndP1C,0,docEnd,docEnd,FALSE FALSE,6,TextUnit_Word,1,docEnd,docEndP1C,0,docEnd,docEnd,FALSE FALSE,6,TextUnit_Word,5,docEnd,docEndP1C,0,docEnd,docEnd,FALSE -TRUE,7,TextUnit_Word,-5,midEmptySpace,midEmptySpace,-5,midDocEndLeft,midDocEndLeft,TRUE -TRUE,7,TextUnit_Word,-1,midEmptySpace,midEmptySpace,-1,segment4LmidDocEnd,segment4LmidDocEnd,TRUE +TRUE,7,TextUnit_Word,-5,midEmptySpace,midEmptySpace,-5,midDocEndLeft,midDocEndLeft,FALSE +TRUE,7,TextUnit_Word,-1,midEmptySpace,midEmptySpace,-1,segment4LmidDocEnd,segment4LmidDocEnd,FALSE TRUE,7,TextUnit_Word,0,midEmptySpace,midEmptySpace,0,docEnd,docEnd,FALSE TRUE,7,TextUnit_Word,1,midEmptySpace,midEmptySpace,0,docEnd,docEnd,FALSE TRUE,7,TextUnit_Word,5,midEmptySpace,midEmptySpace,0,docEnd,docEnd,FALSE -FALSE,7,TextUnit_Word,-5,midEmptySpace,midEmptySpaceP1C,-5,midDocEndLeft,midDocEndLeft,TRUE -FALSE,7,TextUnit_Word,-1,midEmptySpace,midEmptySpaceP1C,-1,segment4LmidDocEnd,segment4LmidDocEnd,TRUE +FALSE,7,TextUnit_Word,-5,midEmptySpace,midEmptySpaceP1C,-5,midDocEndLeft,midDocEndLeft,FALSE +FALSE,7,TextUnit_Word,-1,midEmptySpace,midEmptySpaceP1C,-1,segment4LmidDocEnd,segment4LmidDocEnd,FALSE FALSE,7,TextUnit_Word,0,midEmptySpace,midEmptySpaceP1C,0,docEnd,docEnd,FALSE FALSE,7,TextUnit_Word,1,midEmptySpace,midEmptySpaceP1C,0,docEnd,docEnd,FALSE FALSE,7,TextUnit_Word,5,midEmptySpace,midEmptySpaceP1C,0,docEnd,docEnd,FALSE -TRUE,8,TextUnit_Word,-5,bufferEnd,bufferEnd,-5,midDocEndLeft,midDocEndLeft,TRUE -TRUE,8,TextUnit_Word,-1,bufferEnd,bufferEnd,-1,segment4LmidDocEnd,segment4LmidDocEnd,TRUE +TRUE,8,TextUnit_Word,-5,bufferEnd,bufferEnd,-5,midDocEndLeft,midDocEndLeft,FALSE +TRUE,8,TextUnit_Word,-1,bufferEnd,bufferEnd,-1,segment4LmidDocEnd,segment4LmidDocEnd,FALSE TRUE,8,TextUnit_Word,0,bufferEnd,bufferEnd,0,docEnd,docEnd,FALSE TRUE,8,TextUnit_Word,1,bufferEnd,bufferEnd,0,docEnd,docEnd,FALSE TRUE,8,TextUnit_Word,5,bufferEnd,bufferEnd,0,docEnd,docEnd,FALSE -FALSE,8,TextUnit_Word,-5,bufferEnd,endExclusive,-5,midDocEndLeft,midDocEndLeft,TRUE -FALSE,8,TextUnit_Word,-1,bufferEnd,endExclusive,-1,segment4LmidDocEnd,segment4LmidDocEnd,TRUE +FALSE,8,TextUnit_Word,-5,bufferEnd,endExclusive,-5,midDocEndLeft,midDocEndLeft,FALSE +FALSE,8,TextUnit_Word,-1,bufferEnd,endExclusive,-1,segment4LmidDocEnd,segment4LmidDocEnd,FALSE FALSE,8,TextUnit_Word,0,bufferEnd,endExclusive,0,docEnd,docEnd,FALSE FALSE,8,TextUnit_Word,1,bufferEnd,endExclusive,0,docEnd,docEnd,FALSE FALSE,8,TextUnit_Word,5,bufferEnd,endExclusive,0,docEnd,docEnd,FALSE -TRUE,9,TextUnit_Word,-5,endExclusive,endExclusive,-5,midDocEndLeft,midDocEndLeft,TRUE -TRUE,9,TextUnit_Word,-1,endExclusive,endExclusive,-1,segment4LmidDocEnd,segment4LmidDocEnd,TRUE +TRUE,9,TextUnit_Word,-5,endExclusive,endExclusive,-5,midDocEndLeft,midDocEndLeft,FALSE +TRUE,9,TextUnit_Word,-1,endExclusive,endExclusive,-1,segment4LmidDocEnd,segment4LmidDocEnd,FALSE TRUE,9,TextUnit_Word,0,endExclusive,endExclusive,0,docEnd,docEnd,FALSE TRUE,9,TextUnit_Word,1,endExclusive,endExclusive,0,docEnd,docEnd,FALSE TRUE,9,TextUnit_Word,5,endExclusive,endExclusive,0,docEnd,docEnd,FALSE