mirror of
https://github.com/microsoft/terminal.git
synced 2025-12-11 13:56:33 -06:00
Take wrapping into account when expanding wordwise selections (#17170)
Closes #17165
This commit is contained in:
parent
a9446a12df
commit
6cda6797f8
1
.github/actions/spelling/allow/allow.txt
vendored
1
.github/actions/spelling/allow/allow.txt
vendored
@ -80,6 +80,7 @@ mnt
|
||||
mru
|
||||
nje
|
||||
noreply
|
||||
notwrapped
|
||||
ogonek
|
||||
ok'd
|
||||
overlined
|
||||
|
||||
@ -1440,11 +1440,24 @@ til::point TextBuffer::_GetWordStartForSelection(const til::point target, const
|
||||
// expand left until we hit the left boundary or a different delimiter class
|
||||
while (result != bufferSize.Origin() && _GetDelimiterClassAt(result, wordDelimiters) == initialDelimiter)
|
||||
{
|
||||
//prevent selection wrapping on whitespace selection
|
||||
if (isControlChar && result.x == bufferSize.Left())
|
||||
if (result.x == bufferSize.Left())
|
||||
{
|
||||
// Prevent wrapping to the previous line if the selection begins on whitespace
|
||||
if (isControlChar)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (result.y > 0)
|
||||
{
|
||||
// Prevent wrapping to the previous line if it was hard-wrapped (e.g. not forced by us to wrap)
|
||||
const auto& priorRow = GetRowByOffset(result.y - 1);
|
||||
if (!priorRow.WasWrapForced())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
bufferSize.DecrementInBounds(result);
|
||||
}
|
||||
|
||||
@ -1563,10 +1576,22 @@ til::point TextBuffer::_GetWordEndForSelection(const til::point target, const st
|
||||
// expand right until we hit the right boundary as a ControlChar or a different delimiter class
|
||||
while (result != bufferSize.BottomRightInclusive() && _GetDelimiterClassAt(result, wordDelimiters) == initialDelimiter)
|
||||
{
|
||||
if (isControlChar && result.x == bufferSize.RightInclusive())
|
||||
if (result.x == bufferSize.RightInclusive())
|
||||
{
|
||||
// Prevent wrapping to the next line if the selection begins on whitespace
|
||||
if (isControlChar)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Prevent wrapping to the next line if this one was hard-wrapped (e.g. not forced by us to wrap)
|
||||
const auto& row = GetRowByOffset(result.y);
|
||||
if (!row.WasWrapForced())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bufferSize.IncrementInBoundsCircular(result);
|
||||
}
|
||||
|
||||
|
||||
@ -2336,16 +2336,32 @@ void TextBufferTests::GetWordBoundaries()
|
||||
}
|
||||
|
||||
_buffer->Reset();
|
||||
_buffer->ResizeTraditional({ 10, 5 });
|
||||
_buffer->ResizeTraditional({ 10, 6 });
|
||||
const std::vector<std::wstring> secondText = { L"this wordiswrapped",
|
||||
L"notwrapped"
|
||||
L"spaces wrapped reachEOB" };
|
||||
//Buffer looks like:
|
||||
// this wordi
|
||||
// swrapped
|
||||
// spaces
|
||||
// wrappe
|
||||
// d reachEOB
|
||||
|
||||
WriteLinesToBuffer(secondText, *_buffer);
|
||||
|
||||
//Buffer looks like:
|
||||
// 0123456789
|
||||
// 0|this wordi| < wrapped
|
||||
// 1|swrapped | < not wrapped
|
||||
// 2|notwrapped| < not wrapped
|
||||
// 3|spaces | < wrapped
|
||||
// 4| wrappe| < wrapped
|
||||
// 5|d reachEOB| < wrapped
|
||||
|
||||
VERIFY_IS_TRUE(_buffer->GetRowByOffset(0).WasWrapForced());
|
||||
VERIFY_IS_FALSE(_buffer->GetRowByOffset(1).WasWrapForced());
|
||||
// GH#780 See the comment in WriteLinesToBuffer
|
||||
// VERIFY_IS_FALSE(_buffer->GetRowByOffset(2).WasWrapForced());
|
||||
_buffer->GetMutableRowByOffset(2).SetWrapForced(false); // Ugh
|
||||
VERIFY_IS_TRUE(_buffer->GetRowByOffset(3).WasWrapForced());
|
||||
VERIFY_IS_TRUE(_buffer->GetRowByOffset(4).WasWrapForced());
|
||||
VERIFY_IS_TRUE(_buffer->GetRowByOffset(5).WasWrapForced());
|
||||
|
||||
// clang-format off
|
||||
testData = {
|
||||
{ { 0, 0 }, { { 0, 0 }, { 0, 0 } } },
|
||||
{ { 1, 0 }, { { 0, 0 }, { 0, 0 } } },
|
||||
@ -2358,15 +2374,18 @@ void TextBufferTests::GetWordBoundaries()
|
||||
{ { 9, 1 }, { { 8, 1 }, { 5, 0 } } },
|
||||
|
||||
{ { 0, 2 }, { { 0, 2 }, { 0, 2 } } },
|
||||
{ { 7, 2 }, { { 6, 2 }, { 0, 2 } } },
|
||||
{ { 9, 2 }, { { 0, 2 }, { 0, 2 } } },
|
||||
// v accessibility does not consider wrapping
|
||||
{ { 0, 3 }, { { 0, 3 }, { 0, 2 } } },
|
||||
{ { 7, 3 }, { { 6, 3 }, { 0, 2 } } },
|
||||
// v accessibility does not consider wrapping
|
||||
{ { 1, 4 }, { { 0, 4 }, { 0, 2 } } },
|
||||
{ { 4, 4 }, { { 4, 4 }, { 4, 4 } } },
|
||||
{ { 8, 4 }, { { 4, 4 }, { 4, 4 } } },
|
||||
|
||||
{ { 1, 3 }, { { 0, 3 }, { 0, 2 } } },
|
||||
{ { 4, 3 }, { { 4, 3 }, { 4, 3 } } },
|
||||
{ { 8, 3 }, { { 4, 3 }, { 4, 3 } } },
|
||||
|
||||
{ { 0, 4 }, { { 4, 3 }, { 4, 3 } } },
|
||||
{ { 1, 4 }, { { 1, 4 }, { 4, 3 } } },
|
||||
{ { 9, 4 }, { { 2, 4 }, { 2, 4 } } },
|
||||
{ { 0, 5 }, { { 4, 4 }, { 4, 4 } } },
|
||||
{ { 1, 5 }, { { 1, 5 }, { 4, 4 } } },
|
||||
{ { 9, 5 }, { { 2, 5 }, { 2, 5 } } },
|
||||
};
|
||||
for (const auto& test : testData)
|
||||
{
|
||||
@ -2377,12 +2396,15 @@ void TextBufferTests::GetWordBoundaries()
|
||||
}
|
||||
|
||||
//GetWordEnd for Wrapping Text
|
||||
//Buffer looks like:
|
||||
// this wordi
|
||||
// swrapped
|
||||
// spaces
|
||||
// wrappe
|
||||
// d reachEOB
|
||||
// Buffer:
|
||||
// 0123456789
|
||||
// 0|this wordi| < wrapped
|
||||
// 1|swrapped | < not wrapped
|
||||
// 2|notwrapped| < not wrapped
|
||||
// 3|spaces | < wrapped
|
||||
// 4| wrappe| < wrapped
|
||||
// 5|d reachEOB| < wrapped
|
||||
// clang-format off
|
||||
testData = {
|
||||
// tests for first line of text
|
||||
{ { 0, 0 }, { { 3, 0 }, { 5, 0 } } },
|
||||
@ -2395,17 +2417,20 @@ void TextBufferTests::GetWordBoundaries()
|
||||
{ { 7, 1 }, { { 7, 1 }, { 0, 2 } } },
|
||||
{ { 9, 1 }, { { 9, 1 }, { 0, 2 } } },
|
||||
|
||||
{ { 0, 2 }, { { 5, 2 }, { 4, 3 } } },
|
||||
{ { 7, 2 }, { { 9, 2 }, { 4, 3 } } },
|
||||
{ { 0, 2 }, { { 9, 2 }, { 4, 4 } } },
|
||||
{ { 9, 2 }, { { 9, 2 }, { 4, 4 } } },
|
||||
|
||||
{ { 1, 3 }, { { 3, 3 }, { 4, 3 } } },
|
||||
{ { 4, 3 }, { { 0, 4 }, { 2, 4 } } },
|
||||
{ { 8, 3 }, { { 0, 4 }, { 2, 4 } } },
|
||||
{ { 0, 3 }, { { 5, 3 }, { 4, 4 } } },
|
||||
{ { 7, 3 }, { { 9, 3 }, { 4, 4 } } },
|
||||
|
||||
{ { 0, 4 }, { { 0, 4 }, { 2, 4 } } },
|
||||
{ { 1, 4 }, { { 1, 4 }, { 2, 4 } } },
|
||||
{ { 4, 4 }, { { 9, 4 }, { 0, 5 } } },
|
||||
{ { 9, 4 }, { { 9, 4 }, { 0, 5 } } },
|
||||
{ { 1, 4 }, { { 3, 4 }, { 4, 4 } } },
|
||||
{ { 4, 4 }, { { 0, 5 }, { 2, 5 } } },
|
||||
{ { 8, 4 }, { { 0, 5 }, { 2, 5 } } },
|
||||
|
||||
{ { 0, 5 }, { { 0, 5 }, { 2, 5 } } },
|
||||
{ { 1, 5 }, { { 1, 5 }, { 2, 5 } } },
|
||||
{ { 4, 5 }, { { 9, 5 }, { 0, 6 } } },
|
||||
{ { 9, 5 }, { { 9, 5 }, { 0, 6 } } },
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user