mirror of
https://github.com/microsoft/terminal.git
synced 2025-12-12 00:07:24 -06:00
Avoid covering current search highlight with search box (#17516)
## Summary of the Pull Request Adds a scroll offset to avoid hiding the current search highlight with the search box. - Offset is based on the number of rows that the search box takes up. (I am not totally sure I am calculating this right) - This won't help when the current highlight is in the first couple rows of the buffer. Fixes: #4407
This commit is contained in:
parent
f6a415511a
commit
0bafab9a0f
@ -1689,22 +1689,22 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
// - resetOnly: If true, only Reset() will be called, if anything. FindNext() will never be called.
|
// - resetOnly: If true, only Reset() will be called, if anything. FindNext() will never be called.
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - <none>
|
// - <none>
|
||||||
SearchResults ControlCore::Search(const std::wstring_view& text, const bool goForward, const bool caseSensitive, const bool regularExpression, const bool resetOnly)
|
SearchResults ControlCore::Search(SearchRequest request)
|
||||||
{
|
{
|
||||||
const auto lock = _terminal->LockForWriting();
|
const auto lock = _terminal->LockForWriting();
|
||||||
SearchFlag flags{};
|
SearchFlag flags{};
|
||||||
WI_SetFlagIf(flags, SearchFlag::CaseInsensitive, !caseSensitive);
|
WI_SetFlagIf(flags, SearchFlag::CaseInsensitive, !request.CaseSensitive);
|
||||||
WI_SetFlagIf(flags, SearchFlag::RegularExpression, regularExpression);
|
WI_SetFlagIf(flags, SearchFlag::RegularExpression, request.RegularExpression);
|
||||||
const auto searchInvalidated = _searcher.IsStale(*_terminal.get(), text, flags);
|
const auto searchInvalidated = _searcher.IsStale(*_terminal.get(), request.Text, flags);
|
||||||
|
|
||||||
if (searchInvalidated || !resetOnly)
|
if (searchInvalidated || !request.Reset)
|
||||||
{
|
{
|
||||||
std::vector<til::point_span> oldResults;
|
std::vector<til::point_span> oldResults;
|
||||||
|
|
||||||
if (searchInvalidated)
|
if (searchInvalidated)
|
||||||
{
|
{
|
||||||
oldResults = _searcher.ExtractResults();
|
oldResults = _searcher.ExtractResults();
|
||||||
_searcher.Reset(*_terminal.get(), text, flags, !goForward);
|
_searcher.Reset(*_terminal.get(), request.Text, flags, !request.GoForward);
|
||||||
|
|
||||||
if (SnapSearchResultToSelection())
|
if (SnapSearchResultToSelection())
|
||||||
{
|
{
|
||||||
@ -1716,12 +1716,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_searcher.FindNext(!goForward);
|
_searcher.FindNext(!request.GoForward);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const auto idx = _searcher.CurrentMatch(); idx >= 0)
|
if (const auto idx = _searcher.CurrentMatch(); idx >= 0)
|
||||||
{
|
{
|
||||||
_terminal->SetSearchHighlightFocused(gsl::narrow<size_t>(idx));
|
_terminal->SetSearchHighlightFocused(gsl::narrow<size_t>(idx), request.ScrollOffset);
|
||||||
}
|
}
|
||||||
_renderer->TriggerSearchHighlight(oldResults);
|
_renderer->TriggerSearchHighlight(oldResults);
|
||||||
}
|
}
|
||||||
@ -1751,7 +1751,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
{
|
{
|
||||||
const auto lock = _terminal->LockForWriting();
|
const auto lock = _terminal->LockForWriting();
|
||||||
_terminal->SetSearchHighlights({});
|
_terminal->SetSearchHighlights({});
|
||||||
_terminal->SetSearchHighlightFocused({});
|
_terminal->SetSearchHighlightFocused({}, 0);
|
||||||
_renderer->TriggerSearchHighlight(_searcher.Results());
|
_renderer->TriggerSearchHighlight(_searcher.Results());
|
||||||
_searcher = {};
|
_searcher = {};
|
||||||
}
|
}
|
||||||
@ -2938,5 +2938,4 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
{
|
{
|
||||||
_terminal->PreviewText(input);
|
_terminal->PreviewText(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -225,7 +225,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
void SetSelectionAnchor(const til::point position);
|
void SetSelectionAnchor(const til::point position);
|
||||||
void SetEndSelectionPoint(const til::point position);
|
void SetEndSelectionPoint(const til::point position);
|
||||||
|
|
||||||
SearchResults Search(const std::wstring_view& text, bool goForward, bool caseSensitive, bool regularExpression, bool reset);
|
SearchResults Search(SearchRequest request);
|
||||||
const std::vector<til::point_span>& SearchResultRows() const noexcept;
|
const std::vector<til::point_span>& SearchResultRows() const noexcept;
|
||||||
void ClearSearch();
|
void ClearSearch();
|
||||||
void SnapSearchResultToSelection(bool snap) noexcept;
|
void SnapSearchResultToSelection(bool snap) noexcept;
|
||||||
|
|||||||
@ -49,6 +49,16 @@ namespace Microsoft.Terminal.Control
|
|||||||
Boolean EndAtRightBoundary;
|
Boolean EndAtRightBoundary;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SearchRequest
|
||||||
|
{
|
||||||
|
String Text;
|
||||||
|
Boolean GoForward;
|
||||||
|
Boolean CaseSensitive;
|
||||||
|
Boolean RegularExpression;
|
||||||
|
Boolean Reset;
|
||||||
|
Int32 ScrollOffset;
|
||||||
|
};
|
||||||
|
|
||||||
struct SearchResults
|
struct SearchResults
|
||||||
{
|
{
|
||||||
Int32 TotalMatches;
|
Int32 TotalMatches;
|
||||||
@ -136,7 +146,7 @@ namespace Microsoft.Terminal.Control
|
|||||||
void ResumeRendering();
|
void ResumeRendering();
|
||||||
void BlinkAttributeTick();
|
void BlinkAttributeTick();
|
||||||
|
|
||||||
SearchResults Search(String text, Boolean goForward, Boolean caseSensitive, Boolean regularExpression, Boolean reset);
|
SearchResults Search(SearchRequest request);
|
||||||
void ClearSearch();
|
void ClearSearch();
|
||||||
Boolean SnapSearchResultToSelection;
|
Boolean SnapSearchResultToSelection;
|
||||||
|
|
||||||
|
|||||||
@ -584,6 +584,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
_searchBox->Open([weakThis = get_weak()]() {
|
_searchBox->Open([weakThis = get_weak()]() {
|
||||||
if (const auto self = weakThis.get(); self && !self->_IsClosing())
|
if (const auto self = weakThis.get(); self && !self->_IsClosing())
|
||||||
{
|
{
|
||||||
|
self->_searchScrollOffset = self->_calculateSearchScrollOffset();
|
||||||
self->_searchBox->SetFocusOnTextbox();
|
self->_searchBox->SetFocusOnTextbox();
|
||||||
self->_refreshSearch();
|
self->_refreshSearch();
|
||||||
}
|
}
|
||||||
@ -605,7 +606,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_handleSearchResults(_core.Search(_searchBox->Text(), goForward, _searchBox->CaseSensitive(), _searchBox->RegularExpression(), false));
|
const auto request = SearchRequest{ _searchBox->Text(), goForward, _searchBox->CaseSensitive(), _searchBox->RegularExpression(), false, _searchScrollOffset };
|
||||||
|
_handleSearchResults(_core.Search(request));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -639,7 +641,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
{
|
{
|
||||||
if (_searchBox && _searchBox->IsOpen())
|
if (_searchBox && _searchBox->IsOpen())
|
||||||
{
|
{
|
||||||
_handleSearchResults(_core.Search(text, goForward, caseSensitive, regularExpression, false));
|
const auto request = SearchRequest{ text, goForward, caseSensitive, regularExpression, false, _searchScrollOffset };
|
||||||
|
_handleSearchResults(_core.Search(request));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -660,7 +663,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
{
|
{
|
||||||
// We only want to update the search results based on the new text. Set
|
// We only want to update the search results based on the new text. Set
|
||||||
// `resetOnly` to true so we don't accidentally update the current match index.
|
// `resetOnly` to true so we don't accidentally update the current match index.
|
||||||
const auto result = _core.Search(text, goForward, caseSensitive, regularExpression, true);
|
const auto request = SearchRequest{ text, goForward, caseSensitive, regularExpression, true, _searchScrollOffset };
|
||||||
|
const auto result = _core.Search(request);
|
||||||
_handleSearchResults(result);
|
_handleSearchResults(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3572,6 +3576,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
QuickFixIcon().FontSize(static_cast<double>(args.Width() / dpiScale));
|
QuickFixIcon().FontSize(static_cast<double>(args.Width() / dpiScale));
|
||||||
RefreshQuickFixMenu();
|
RefreshQuickFixMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_searchScrollOffset = _calculateSearchScrollOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TermControl::_coreRaisedNotice(const IInspectable& /*sender*/,
|
void TermControl::_coreRaisedNotice(const IInspectable& /*sender*/,
|
||||||
@ -3702,7 +3708,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
const auto goForward = _searchBox->GoForward();
|
const auto goForward = _searchBox->GoForward();
|
||||||
const auto caseSensitive = _searchBox->CaseSensitive();
|
const auto caseSensitive = _searchBox->CaseSensitive();
|
||||||
const auto regularExpression = _searchBox->RegularExpression();
|
const auto regularExpression = _searchBox->RegularExpression();
|
||||||
_handleSearchResults(_core.Search(text, goForward, caseSensitive, regularExpression, true));
|
const auto request = SearchRequest{ text, goForward, caseSensitive, regularExpression, true, _calculateSearchScrollOffset() };
|
||||||
|
_handleSearchResults(_core.Search(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TermControl::_handleSearchResults(SearchResults results)
|
void TermControl::_handleSearchResults(SearchResults results)
|
||||||
@ -3982,6 +3989,19 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
SearchMissingCommand.raise(*this, args);
|
SearchMissingCommand.raise(*this, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
til::CoordType TermControl::_calculateSearchScrollOffset() const
|
||||||
|
{
|
||||||
|
auto result = 0;
|
||||||
|
if (_searchBox)
|
||||||
|
{
|
||||||
|
const auto displayInfo = DisplayInformation::GetForCurrentView();
|
||||||
|
const auto scaleFactor = _core.FontSize().Height / displayInfo.RawPixelsPerViewPixel();
|
||||||
|
const auto searchBoxRows = _searchBox->ActualHeight() / scaleFactor;
|
||||||
|
result = static_cast<int32_t>(std::ceil(searchBoxRows));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void TermControl::ClearQuickFix()
|
void TermControl::ClearQuickFix()
|
||||||
{
|
{
|
||||||
_core.ClearQuickFix();
|
_core.ClearQuickFix();
|
||||||
|
|||||||
@ -289,6 +289,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
|
|
||||||
bool _isBackgroundLight{ false };
|
bool _isBackgroundLight{ false };
|
||||||
bool _detached{ false };
|
bool _detached{ false };
|
||||||
|
til::CoordType _searchScrollOffset = 0;
|
||||||
|
|
||||||
Windows::Foundation::Collections::IObservableVector<Windows::UI::Xaml::Controls::ICommandBarElement> _originalPrimaryElements{ nullptr };
|
Windows::Foundation::Collections::IObservableVector<Windows::UI::Xaml::Controls::ICommandBarElement> _originalPrimaryElements{ nullptr };
|
||||||
Windows::Foundation::Collections::IObservableVector<Windows::UI::Xaml::Controls::ICommandBarElement> _originalSecondaryElements{ nullptr };
|
Windows::Foundation::Collections::IObservableVector<Windows::UI::Xaml::Controls::ICommandBarElement> _originalSecondaryElements{ nullptr };
|
||||||
@ -409,6 +410,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
|||||||
void _showContextMenuAt(const til::point& controlRelativePos);
|
void _showContextMenuAt(const til::point& controlRelativePos);
|
||||||
|
|
||||||
void _bubbleSearchMissingCommand(const IInspectable& sender, const Control::SearchMissingCommandEventArgs& args);
|
void _bubbleSearchMissingCommand(const IInspectable& sender, const Control::SearchMissingCommandEventArgs& args);
|
||||||
|
til::CoordType _calculateSearchScrollOffset() const;
|
||||||
|
|
||||||
void _PasteCommandHandler(const IInspectable& sender, const IInspectable& args);
|
void _PasteCommandHandler(const IInspectable& sender, const IInspectable& args);
|
||||||
void _CopyCommandHandler(const IInspectable& sender, const IInspectable& args);
|
void _CopyCommandHandler(const IInspectable& sender, const IInspectable& args);
|
||||||
|
|||||||
@ -1251,7 +1251,7 @@ void Terminal::SetSearchHighlights(const std::vector<til::point_span>& highlight
|
|||||||
// Method Description:
|
// Method Description:
|
||||||
// - Stores the focused search highlighted region in the terminal
|
// - Stores the focused search highlighted region in the terminal
|
||||||
// - If the region isn't empty, it will be brought into view
|
// - If the region isn't empty, it will be brought into view
|
||||||
void Terminal::SetSearchHighlightFocused(const size_t focusedIdx)
|
void Terminal::SetSearchHighlightFocused(const size_t focusedIdx, til::CoordType searchScrollOffset)
|
||||||
{
|
{
|
||||||
_assertLocked();
|
_assertLocked();
|
||||||
_searchHighlightFocused = focusedIdx;
|
_searchHighlightFocused = focusedIdx;
|
||||||
@ -1260,7 +1260,9 @@ void Terminal::SetSearchHighlightFocused(const size_t focusedIdx)
|
|||||||
if (focusedIdx < _searchHighlights.size())
|
if (focusedIdx < _searchHighlights.size())
|
||||||
{
|
{
|
||||||
const auto focused = til::at(_searchHighlights, focusedIdx);
|
const auto focused = til::at(_searchHighlights, focusedIdx);
|
||||||
_ScrollToPoints(focused.start, focused.end);
|
const auto adjustedStart = til::point{ focused.start.x, std::max(0, focused.start.y - searchScrollOffset) };
|
||||||
|
const auto adjustedEnd = til::point{ focused.end.x, std::max(0, focused.end.y - searchScrollOffset) };
|
||||||
|
_ScrollToPoints(adjustedStart, adjustedEnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -232,7 +232,7 @@ public:
|
|||||||
void SetSearchMissingCommandCallback(std::function<void(std::wstring_view)> pfn) noexcept;
|
void SetSearchMissingCommandCallback(std::function<void(std::wstring_view)> pfn) noexcept;
|
||||||
void SetClearQuickFixCallback(std::function<void()> pfn) noexcept;
|
void SetClearQuickFixCallback(std::function<void()> pfn) noexcept;
|
||||||
void SetSearchHighlights(const std::vector<til::point_span>& highlights) noexcept;
|
void SetSearchHighlights(const std::vector<til::point_span>& highlights) noexcept;
|
||||||
void SetSearchHighlightFocused(const size_t focusedIdx);
|
void SetSearchHighlightFocused(const size_t focusedIdx, til::CoordType searchScrollOffset);
|
||||||
|
|
||||||
void BlinkCursor() noexcept;
|
void BlinkCursor() noexcept;
|
||||||
void SetCursorOn(const bool isOn) noexcept;
|
void SetCursorOn(const bool isOn) noexcept;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user