-
Notifications
You must be signed in to change notification settings - Fork 8.4k
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
Fix search constantly triggering a scroll #17132
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1654,30 +1654,41 @@ namespace winrt::Microsoft::Terminal::Control::implementation | |
// - text: the text to search | ||
// - goForward: boolean that represents if the current search direction is forward | ||
// - caseSensitive: boolean that represents if the current search is case sensitive | ||
// - resetOnly: If true, only Reset() will be called, if anything. FindNext() will never be called. | ||
// Return Value: | ||
// - <none> | ||
SearchResults ControlCore::Search(const std::wstring_view& text, const bool goForward, const bool caseSensitive, const bool reset) | ||
SearchResults ControlCore::Search(const std::wstring_view& text, const bool goForward, const bool caseSensitive, const bool resetOnly) | ||
{ | ||
const auto lock = _terminal->LockForWriting(); | ||
const auto searchInvalidated = _searcher.IsStale(*_terminal.get(), text, !caseSensitive); | ||
|
||
bool searchInvalidated = false; | ||
std::vector<til::point_span> oldResults; | ||
if (_searcher.ResetIfStale(*GetRenderData(), text, !goForward, !caseSensitive, &oldResults)) | ||
if (searchInvalidated || !resetOnly) | ||
{ | ||
searchInvalidated = true; | ||
std::vector<til::point_span> oldResults; | ||
|
||
_cachedSearchResultRows = {}; | ||
if (SnapSearchResultToSelection()) | ||
if (searchInvalidated) | ||
{ | ||
_searcher.MoveToCurrentSelection(); | ||
SnapSearchResultToSelection(false); | ||
oldResults = _searcher.ExtractResults(); | ||
_searcher.Reset(*_terminal.get(), text, !caseSensitive, !goForward); | ||
|
||
if (SnapSearchResultToSelection()) | ||
{ | ||
_searcher.MoveToCurrentSelection(); | ||
SnapSearchResultToSelection(false); | ||
} | ||
|
||
_terminal->SetSearchHighlights(_searcher.Results()); | ||
} | ||
else | ||
{ | ||
_searcher.FindNext(!goForward); | ||
} | ||
|
||
_terminal->SetSearchHighlights(_searcher.Results()); | ||
} | ||
else if (!reset) | ||
{ | ||
_searcher.FindNext(); | ||
if (const auto idx = _searcher.CurrentMatch(); idx >= 0) | ||
{ | ||
_terminal->SetSearchHighlightFocused(gsl::narrow<size_t>(idx)); | ||
} | ||
_renderer->TriggerSearchHighlight(oldResults); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. won't There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You mean what happens if Now that I think about it, I think we could also just remove the parameter to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Nice 😃 TriggerSearchHighlight() also isn't completely correct in that the old highlights are supposed to be invalidated w.r.t old line renditions, but we currently don't store old line renditions so we're just using the current line renditions. I'm sure this can be fixed with buffer snapshot based rendering where we would pass in the line rendition from the current snapshot of the buffer that render engine has access to. |
||
} | ||
|
||
int32_t totalMatches = 0; | ||
|
@@ -1686,39 +1697,18 @@ namespace winrt::Microsoft::Terminal::Control::implementation | |
{ | ||
totalMatches = gsl::narrow<int32_t>(_searcher.Results().size()); | ||
currentMatch = gsl::narrow<int32_t>(idx); | ||
_terminal->SetSearchHighlightFocused(gsl::narrow<size_t>(idx)); | ||
} | ||
|
||
_renderer->TriggerSearchHighlight(oldResults); | ||
|
||
return { | ||
.TotalMatches = totalMatches, | ||
.CurrentMatch = currentMatch, | ||
.SearchInvalidated = searchInvalidated, | ||
}; | ||
} | ||
|
||
Windows::Foundation::Collections::IVector<int32_t> ControlCore::SearchResultRows() | ||
const std::vector<til::point_span>& ControlCore::SearchResultRows() const noexcept | ||
{ | ||
if (!_cachedSearchResultRows) | ||
{ | ||
auto results = std::vector<int32_t>(); | ||
auto lastRow = til::CoordTypeMin; | ||
|
||
for (const auto& match : _searcher.Results()) | ||
{ | ||
const auto row{ match.start.y }; | ||
if (row != lastRow) | ||
{ | ||
results.push_back(row); | ||
lastRow = row; | ||
} | ||
} | ||
|
||
_cachedSearchResultRows = winrt::single_threaded_vector<int32_t>(std::move(results)); | ||
} | ||
|
||
return _cachedSearchResultRows; | ||
return _searcher.Results(); | ||
} | ||
|
||
void ControlCore::ClearSearch() | ||
|
@@ -1728,7 +1718,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation | |
_terminal->SetSearchHighlightFocused({}); | ||
_renderer->TriggerSearchHighlight(_searcher.Results()); | ||
_searcher = {}; | ||
_cachedSearchResultRows = {}; | ||
} | ||
|
||
// Method Description: | ||
|
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.
right?
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.
No, actually the comment is correct, but the boolean logic inside the function is very difficult to read. Basically, if
resetOnly
is true thenif (searchInvalidated || !resetOnly)
is only entered ifsearchInvalidated
is true. IfsearchInvalidated
is true then onlyReset()
will be called.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.
oh yea that's hard to parse