-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Avoid moving the selection while typing a search query #15998
Avoid moving the selection while typing a search query #15998
Conversation
_caseInsensitive == caseInsensitive && | ||
_lastMutationId == lastMutationId) | ||
{ | ||
_step = reverse ? -1 : 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the new
MoveToCurrentSelection
function would not move past the current selection anymore, changing the direction would not move past the current result either. To fix this, we now don't invalidate the search cache when changing the direction.
void Search::MoveToPoint(const til::point anchor) noexcept | ||
{ | ||
if (_results.empty()) | ||
{ | ||
return; | ||
} | ||
|
||
const auto count = gsl::narrow_cast<ptrdiff_t>(_results.size()); | ||
ptrdiff_t index = 0; | ||
|
||
if (_step < 0) | ||
{ | ||
for (index = count - 1; index >= 0 && til::at(_results, index).start > anchor; --index) | ||
{ | ||
} | ||
} | ||
else | ||
{ | ||
for (index = 0; index < count && til::at(_results, index).start < anchor; ++index) | ||
{ | ||
} | ||
} | ||
|
||
_index = (index + count) % count; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This new function is a copy of the existing one below but with <
instead of <=
.
|
||
if (_reverse) | ||
if (_step < 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I figured that if we don't invalidate on _reverse
anymore we can use _step
as the indicator for whether it's in reverse mode. That's why I slightly moved these variables around because it's now a bit neater.
@@ -119,7 +135,7 @@ const std::vector<til::point_span>& Search::Results() const noexcept | |||
return _results; | |||
} | |||
|
|||
size_t Search::CurrentMatch() const noexcept | |||
ptrdiff_t Search::CurrentMatch() const noexcept |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_index
is a ptrdiff_t
.
void MovePastPoint(til::point anchor) noexcept; | ||
void FindNext() noexcept; | ||
|
||
const til::point_span* GetCurrent() const noexcept; | ||
bool SelectCurrent() const; | ||
|
||
const std::vector<til::point_span>& Results() const noexcept; | ||
size_t CurrentMatch() const noexcept; | ||
bool CurrentDirection() const noexcept; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CurrentDirection()
had no definition?
const auto& internalMarks = _terminal->GetScrollMarks(); | ||
std::vector<Control::ScrollMark> v; | ||
|
||
// sneaky: always evaluate the color of the mark to a real value | ||
// before shoving it into the optional. If the mark doesn't have a | ||
// specific color set, we'll use the value from the color table | ||
// that's appropriate for this category of mark. If we do have a | ||
// color set, then great we'll use that. The TermControl can then | ||
// always use the value in the Mark regardless if it was actually | ||
// set or not. | ||
m.Color = OptionalFromColor(_terminal->GetColorForMark(mark)); | ||
m.Start = mark.start.to_core_point(); | ||
m.End = mark.end.to_core_point(); | ||
v.reserve(internalMarks.size()); | ||
|
||
v.Append(m); | ||
for (const auto& mark : internalMarks) | ||
{ | ||
v.emplace_back( | ||
mark.start.to_core_point(), | ||
mark.end.to_core_point(), | ||
OptionalFromColor(_terminal->GetColorForMark(mark))); | ||
} | ||
|
||
return v; | ||
return winrt::single_threaded_vector(std::move(v)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding this to the PR was a bit of a mistake (I did git restore
from another branch). But it might be something we'd want to keep anyways - up to you all! 😅
The benefits are:
- Much much faster vector creation (without WinRT indirection)
- Reserve the right amount of memory
emplace_back
constructs the trivial struct in-place instead of constructing it on the stack first and then copying it over to the heap
BTW I think this method is missing lock guards. Scroll marks are being written by the VT thread after all. I'm sure my other PR adds them. ^^ Merged the fix from main.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
absolutely fine with me
This commit fixes 2 issues:
ControlCore::ScrollMarks()
would callResetIfStale
again while the search prompt hasn't changed.
This has been fixed by using
_cachedSearchResultRows
asthe indicator for whether it needs to be recreated or not.
results with each typed character, because
MovePastCurrentSelection
would do what its name indicates. It has been renamed and rewritten
to be
MoveToCurrentSelection
. To avoid breaking UIA, the previousMovePastPoint
implementation was kept.Since the new
MoveToCurrentSelection
function would not move past thecurrent selection anymore, changing the direction would not move past
the current result either. To fix this, we now don't invalidate the
search cache when changing the direction.
Closes #15954
Validation Steps Performed
"helloworld`n"*20
in pwsh