mirror of
https://github.com/microsoft/terminal.git
synced 2025-12-10 18:43:54 -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
|
mru
|
||||||
nje
|
nje
|
||||||
noreply
|
noreply
|
||||||
|
notwrapped
|
||||||
ogonek
|
ogonek
|
||||||
ok'd
|
ok'd
|
||||||
overlined
|
overlined
|
||||||
|
|||||||
@ -1440,10 +1440,23 @@ til::point TextBuffer::_GetWordStartForSelection(const til::point target, const
|
|||||||
// expand left until we hit the left boundary or a different delimiter class
|
// expand left until we hit the left boundary or a different delimiter class
|
||||||
while (result != bufferSize.Origin() && _GetDelimiterClassAt(result, wordDelimiters) == initialDelimiter)
|
while (result != bufferSize.Origin() && _GetDelimiterClassAt(result, wordDelimiters) == initialDelimiter)
|
||||||
{
|
{
|
||||||
//prevent selection wrapping on whitespace selection
|
if (result.x == bufferSize.Left())
|
||||||
if (isControlChar && result.x == bufferSize.Left())
|
|
||||||
{
|
{
|
||||||
break;
|
// 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);
|
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
|
// expand right until we hit the right boundary as a ControlChar or a different delimiter class
|
||||||
while (result != bufferSize.BottomRightInclusive() && _GetDelimiterClassAt(result, wordDelimiters) == initialDelimiter)
|
while (result != bufferSize.BottomRightInclusive() && _GetDelimiterClassAt(result, wordDelimiters) == initialDelimiter)
|
||||||
{
|
{
|
||||||
if (isControlChar && result.x == bufferSize.RightInclusive())
|
if (result.x == bufferSize.RightInclusive())
|
||||||
{
|
{
|
||||||
break;
|
// 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);
|
bufferSize.IncrementInBoundsCircular(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2336,16 +2336,32 @@ void TextBufferTests::GetWordBoundaries()
|
|||||||
}
|
}
|
||||||
|
|
||||||
_buffer->Reset();
|
_buffer->Reset();
|
||||||
_buffer->ResizeTraditional({ 10, 5 });
|
_buffer->ResizeTraditional({ 10, 6 });
|
||||||
const std::vector<std::wstring> secondText = { L"this wordiswrapped",
|
const std::vector<std::wstring> secondText = { L"this wordiswrapped",
|
||||||
|
L"notwrapped"
|
||||||
L"spaces wrapped reachEOB" };
|
L"spaces wrapped reachEOB" };
|
||||||
//Buffer looks like:
|
|
||||||
// this wordi
|
|
||||||
// swrapped
|
|
||||||
// spaces
|
|
||||||
// wrappe
|
|
||||||
// d reachEOB
|
|
||||||
WriteLinesToBuffer(secondText, *_buffer);
|
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 = {
|
testData = {
|
||||||
{ { 0, 0 }, { { 0, 0 }, { 0, 0 } } },
|
{ { 0, 0 }, { { 0, 0 }, { 0, 0 } } },
|
||||||
{ { 1, 0 }, { { 0, 0 }, { 0, 0 } } },
|
{ { 1, 0 }, { { 0, 0 }, { 0, 0 } } },
|
||||||
@ -2358,15 +2374,18 @@ void TextBufferTests::GetWordBoundaries()
|
|||||||
{ { 9, 1 }, { { 8, 1 }, { 5, 0 } } },
|
{ { 9, 1 }, { { 8, 1 }, { 5, 0 } } },
|
||||||
|
|
||||||
{ { 0, 2 }, { { 0, 2 }, { 0, 2 } } },
|
{ { 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 } } },
|
{ { 0, 5 }, { { 4, 4 }, { 4, 4 } } },
|
||||||
{ { 4, 3 }, { { 4, 3 }, { 4, 3 } } },
|
{ { 1, 5 }, { { 1, 5 }, { 4, 4 } } },
|
||||||
{ { 8, 3 }, { { 4, 3 }, { 4, 3 } } },
|
{ { 9, 5 }, { { 2, 5 }, { 2, 5 } } },
|
||||||
|
|
||||||
{ { 0, 4 }, { { 4, 3 }, { 4, 3 } } },
|
|
||||||
{ { 1, 4 }, { { 1, 4 }, { 4, 3 } } },
|
|
||||||
{ { 9, 4 }, { { 2, 4 }, { 2, 4 } } },
|
|
||||||
};
|
};
|
||||||
for (const auto& test : testData)
|
for (const auto& test : testData)
|
||||||
{
|
{
|
||||||
@ -2377,12 +2396,15 @@ void TextBufferTests::GetWordBoundaries()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//GetWordEnd for Wrapping Text
|
//GetWordEnd for Wrapping Text
|
||||||
//Buffer looks like:
|
// Buffer:
|
||||||
// this wordi
|
// 0123456789
|
||||||
// swrapped
|
// 0|this wordi| < wrapped
|
||||||
// spaces
|
// 1|swrapped | < not wrapped
|
||||||
// wrappe
|
// 2|notwrapped| < not wrapped
|
||||||
// d reachEOB
|
// 3|spaces | < wrapped
|
||||||
|
// 4| wrappe| < wrapped
|
||||||
|
// 5|d reachEOB| < wrapped
|
||||||
|
// clang-format off
|
||||||
testData = {
|
testData = {
|
||||||
// tests for first line of text
|
// tests for first line of text
|
||||||
{ { 0, 0 }, { { 3, 0 }, { 5, 0 } } },
|
{ { 0, 0 }, { { 3, 0 }, { 5, 0 } } },
|
||||||
@ -2395,17 +2417,20 @@ void TextBufferTests::GetWordBoundaries()
|
|||||||
{ { 7, 1 }, { { 7, 1 }, { 0, 2 } } },
|
{ { 7, 1 }, { { 7, 1 }, { 0, 2 } } },
|
||||||
{ { 9, 1 }, { { 9, 1 }, { 0, 2 } } },
|
{ { 9, 1 }, { { 9, 1 }, { 0, 2 } } },
|
||||||
|
|
||||||
{ { 0, 2 }, { { 5, 2 }, { 4, 3 } } },
|
{ { 0, 2 }, { { 9, 2 }, { 4, 4 } } },
|
||||||
{ { 7, 2 }, { { 9, 2 }, { 4, 3 } } },
|
{ { 9, 2 }, { { 9, 2 }, { 4, 4 } } },
|
||||||
|
|
||||||
{ { 1, 3 }, { { 3, 3 }, { 4, 3 } } },
|
{ { 0, 3 }, { { 5, 3 }, { 4, 4 } } },
|
||||||
{ { 4, 3 }, { { 0, 4 }, { 2, 4 } } },
|
{ { 7, 3 }, { { 9, 3 }, { 4, 4 } } },
|
||||||
{ { 8, 3 }, { { 0, 4 }, { 2, 4 } } },
|
|
||||||
|
|
||||||
{ { 0, 4 }, { { 0, 4 }, { 2, 4 } } },
|
{ { 1, 4 }, { { 3, 4 }, { 4, 4 } } },
|
||||||
{ { 1, 4 }, { { 1, 4 }, { 2, 4 } } },
|
{ { 4, 4 }, { { 0, 5 }, { 2, 5 } } },
|
||||||
{ { 4, 4 }, { { 9, 4 }, { 0, 5 } } },
|
{ { 8, 4 }, { { 0, 5 }, { 2, 5 } } },
|
||||||
{ { 9, 4 }, { { 9, 4 }, { 0, 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
|
// clang-format on
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user