Skip to content

Commit

Permalink
search: move caseInsensitive (boolean) to a flags field
Browse files Browse the repository at this point in the history
  • Loading branch information
DHowett committed May 30, 2024
1 parent e826203 commit fc41d3a
Show file tree
Hide file tree
Showing 11 changed files with 52 additions and 38 deletions.
10 changes: 5 additions & 5 deletions src/buffer/out/search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,24 @@

using namespace Microsoft::Console::Types;

bool Search::IsStale(const Microsoft::Console::Render::IRenderData& renderData, const std::wstring_view& needle, bool caseInsensitive) const noexcept
bool Search::IsStale(const Microsoft::Console::Render::IRenderData& renderData, const std::wstring_view& needle, SearchFlag flags) const noexcept
{
return _renderData != &renderData ||
_needle != needle ||
_caseInsensitive != caseInsensitive ||
_flags != flags ||
_lastMutationId != renderData.GetTextBuffer().GetLastMutationId();
}

bool Search::Reset(Microsoft::Console::Render::IRenderData& renderData, const std::wstring_view& needle, bool caseInsensitive, bool reverse)
bool Search::Reset(Microsoft::Console::Render::IRenderData& renderData, const std::wstring_view& needle, SearchFlag flags, bool reverse)
{
const auto& textBuffer = renderData.GetTextBuffer();

_renderData = &renderData;
_needle = needle;
_caseInsensitive = caseInsensitive;
_flags = flags;
_lastMutationId = textBuffer.GetLastMutationId();

_results = textBuffer.SearchText(needle, caseInsensitive);
_ok = textBuffer.SearchText(needle, _flags, _results);
_index = reverse ? gsl::narrow_cast<ptrdiff_t>(_results.size()) - 1 : 0;
_step = reverse ? -1 : 1;
return true;
Expand Down
15 changes: 12 additions & 3 deletions src/buffer/out/search.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,22 @@ Revision History:
#include "textBuffer.hpp"
#include "../renderer/inc/IRenderData.hpp"

enum class SearchFlag : unsigned int
{
None = 0,

CaseInsensitive = 1 << 0,
};

DEFINE_ENUM_FLAG_OPERATORS(SearchFlag);

class Search final
{
public:
Search() = default;

bool IsStale(const Microsoft::Console::Render::IRenderData& renderData, const std::wstring_view& needle, bool caseInsensitive) const noexcept;
bool Reset(Microsoft::Console::Render::IRenderData& renderData, const std::wstring_view& needle, bool caseInsensitive, bool reverse);
bool IsStale(const Microsoft::Console::Render::IRenderData& renderData, const std::wstring_view& needle, SearchFlag flags) const noexcept;
bool Reset(Microsoft::Console::Render::IRenderData& renderData, const std::wstring_view& needle, SearchFlag flags, bool reverse);

void MoveToCurrentSelection();
void MoveToPoint(til::point anchor) noexcept;
Expand All @@ -44,7 +53,7 @@ class Search final
// _renderData is a pointer so that Search() is constexpr default constructable.
Microsoft::Console::Render::IRenderData* _renderData = nullptr;
std::wstring _needle;
bool _caseInsensitive = false;
SearchFlag _flags{};
uint64_t _lastMutationId = 0;

std::vector<til::point_span> _results;
Expand Down
13 changes: 7 additions & 6 deletions src/buffer/out/textBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "../../types/inc/GlyphWidth.hpp"
#include "../renderer/base/renderer.hpp"
#include "../types/inc/utils.hpp"
#include "search.h"

using namespace Microsoft::Console;
using namespace Microsoft::Console::Types;
Expand Down Expand Up @@ -3184,14 +3185,14 @@ void TextBuffer::CopyHyperlinkMaps(const TextBuffer& other)

// Searches through the entire (committed) text buffer for `needle` and returns the coordinates in absolute coordinates.
// The end coordinates of the returned ranges are considered inclusive.
std::vector<til::point_span> TextBuffer::SearchText(const std::wstring_view& needle, bool caseInsensitive) const
std::vector<til::point_span> TextBuffer::SearchText(const std::wstring_view& needle, SearchFlag flags) const
{
return SearchText(needle, caseInsensitive, 0, til::CoordTypeMax);
return SearchText(needle, flags, 0, til::CoordTypeMax);
}

// Searches through the given rows [rowBeg,rowEnd) for `needle` and returns the coordinates in absolute coordinates.
// While the end coordinates of the returned ranges are considered inclusive, the [rowBeg,rowEnd) range is half-open.
std::vector<til::point_span> TextBuffer::SearchText(const std::wstring_view& needle, bool caseInsensitive, til::CoordType rowBeg, til::CoordType rowEnd) const
std::vector<til::point_span> TextBuffer::SearchText(const std::wstring_view& needle, SearchFlag flags, til::CoordType rowBeg, til::CoordType rowEnd) const
{
rowEnd = std::min(rowEnd, _estimateOffsetOfLastCommittedRow() + 1);

Expand All @@ -3205,11 +3206,11 @@ std::vector<til::point_span> TextBuffer::SearchText(const std::wstring_view& nee

auto text = ICU::UTextFromTextBuffer(*this, rowBeg, rowEnd);

uint32_t flags = UREGEX_LITERAL;
WI_SetFlagIf(flags, UREGEX_CASE_INSENSITIVE, caseInsensitive);
uint32_t icuFlags{ UREGEX_LITERAL };
WI_SetFlagIf(icuFlags, UREGEX_CASE_INSENSITIVE, WI_IsFlagSet(flags, SearchFlag::CaseInsensitive));

UErrorCode status = U_ZERO_ERROR;
const auto re = ICU::CreateRegex(needle, flags, &status);
const auto re = ICU::CreateRegex(needle, icuFlags, &status);
uregex_setUText(re.get(), &text, &status);

if (uregex_find(re.get(), -1, &status))
Expand Down
5 changes: 3 additions & 2 deletions src/buffer/out/textBuffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ filling in the last row, and updating the screen.
#include "../buffer/out/textBufferTextIterator.hpp"

struct URegularExpression;
enum class SearchFlag : unsigned int;

namespace Microsoft::Console::Render
{
Expand Down Expand Up @@ -293,8 +294,8 @@ class TextBuffer final

static void Reflow(TextBuffer& oldBuffer, TextBuffer& newBuffer, const Microsoft::Console::Types::Viewport* lastCharacterViewport = nullptr, PositionInformation* positionInfo = nullptr);

std::vector<til::point_span> SearchText(const std::wstring_view& needle, bool caseInsensitive) const;
std::vector<til::point_span> SearchText(const std::wstring_view& needle, bool caseInsensitive, til::CoordType rowBeg, til::CoordType rowEnd) const;
std::vector<til::point_span> SearchText(const std::wstring_view& needle, SearchFlag flags) const;
std::vector<til::point_span> SearchText(const std::wstring_view& needle, SearchFlag flags, til::CoordType rowBeg, til::CoordType rowEnd) const;

// Mark handling
std::vector<ScrollMark> GetMarkRows() const;
Expand Down
7 changes: 4 additions & 3 deletions src/buffer/out/ut_textbuffer/UTextAdapterTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "WexTestClass.h"
#include "../textBuffer.hpp"
#include "../../renderer/inc/DummyRenderer.hpp"
#include "../search.h"

template<>
class WEX::TestExecution::VerifyOutputTraits<std::vector<til::point_span>>
Expand Down Expand Up @@ -49,15 +50,15 @@ class UTextAdapterTests
};

auto expected = std::vector{ s(0, 2), s(8, 10) };
auto actual = buffer.SearchText(L"abc", false);
auto actual = buffer.SearchText(L"abc", SearchFlag::None);
VERIFY_ARE_EQUAL(expected, actual);

expected = std::vector{ s(5, 5) };
actual = buffer.SearchText(L"𝒷", false);
actual = buffer.SearchText(L"𝒷", SearchFlag::None);
VERIFY_ARE_EQUAL(expected, actual);

expected = std::vector{ s(12, 15) };
actual = buffer.SearchText(L"ネコ", false);
actual = buffer.SearchText(L"ネコ", SearchFlag::None);
VERIFY_ARE_EQUAL(expected, actual);
}
};
6 changes: 4 additions & 2 deletions src/cascadia/TerminalControl/ControlCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1657,7 +1657,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
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);
SearchFlag flags{};
WI_SetFlagIf(flags, SearchFlag::CaseInsensitive, !caseSensitive);
const auto searchInvalidated = _searcher.IsStale(*_terminal.get(), text, flags);

if (searchInvalidated || !resetOnly)
{
Expand All @@ -1666,7 +1668,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
if (searchInvalidated)
{
oldResults = _searcher.ExtractResults();
_searcher.Reset(*_terminal.get(), text, !caseSensitive, !goForward);
_searcher.Reset(*_terminal.get(), text, flags, !goForward);

if (SnapSearchResultToSelection())
{
Expand Down
2 changes: 1 addition & 1 deletion src/cascadia/TerminalCore/Terminal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1559,7 +1559,7 @@ void Terminal::ColorSelection(const TextAttribute& attr, winrt::Microsoft::Termi

if (!textView.empty())
{
const auto hits = textBuffer.SearchText(textView, true);
const auto hits = textBuffer.SearchText(textView, SearchFlag::CaseInsensitive);
for (const auto& s : hits)
{
colorSelection(s.start, s.end, attr);
Expand Down
2 changes: 1 addition & 1 deletion src/host/selectionInput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -701,7 +701,7 @@ bool Selection::_HandleColorSelection(const INPUT_KEY_INFO* const pInputKeyInfo)
ClearSelection();

const auto& textBuffer = gci.renderData.GetTextBuffer();
const auto hits = textBuffer.SearchText(str, true);
const auto hits = textBuffer.SearchText(str, SearchFlag::CaseInsensitive);
for (const auto& s : hits)
{
ColorSelection(s.start, s.end, selectionAttr);
Expand Down
16 changes: 8 additions & 8 deletions src/host/ut_host/SearchTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,15 @@ class SearchTests
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();

Search s;
s.Reset(gci.renderData, L"AB", false, false);
s.Reset(gci.renderData, L"AB", SearchFlag::None, false);
DoFoundChecks(s, {}, 1, false);
}

TEST_METHOD(ForwardCaseSensitiveJapanese)
{
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
Search s;
s.Reset(gci.renderData, L"\x304b", false, false);
s.Reset(gci.renderData, L"\x304b", SearchFlag::None, false);
DoFoundChecks(s, { 2, 0 }, 1, false);
}

Expand All @@ -115,47 +115,47 @@ class SearchTests
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();

Search s;
s.Reset(gci.renderData, L"ab", true, false);
s.Reset(gci.renderData, L"ab", SearchFlag::CaseInsensitive, false);
DoFoundChecks(s, {}, 1, false);
}

TEST_METHOD(ForwardCaseInsensitiveJapanese)
{
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
Search s;
s.Reset(gci.renderData, L"\x304b", true, false);
s.Reset(gci.renderData, L"\x304b", SearchFlag::CaseInsensitive, false);
DoFoundChecks(s, { 2, 0 }, 1, false);
}

TEST_METHOD(BackwardCaseSensitive)
{
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
Search s;
s.Reset(gci.renderData, L"AB", false, true);
s.Reset(gci.renderData, L"AB", SearchFlag::None, true);
DoFoundChecks(s, { 0, 3 }, -1, true);
}

TEST_METHOD(BackwardCaseSensitiveJapanese)
{
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
Search s;
s.Reset(gci.renderData, L"\x304b", false, true);
s.Reset(gci.renderData, L"\x304b", SearchFlag::None, true);
DoFoundChecks(s, { 2, 3 }, -1, true);
}

TEST_METHOD(BackwardCaseInsensitive)
{
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
Search s;
s.Reset(gci.renderData, L"ab", true, true);
s.Reset(gci.renderData, L"ab", SearchFlag::CaseInsensitive, true);
DoFoundChecks(s, { 0, 3 }, -1, true);
}

TEST_METHOD(BackwardCaseInsensitiveJapanese)
{
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
Search s;
s.Reset(gci.renderData, L"\x304b", true, true);
s.Reset(gci.renderData, L"\x304b", SearchFlag::CaseInsensitive, true);
DoFoundChecks(s, { 2, 3 }, -1, true);
}
};
10 changes: 5 additions & 5 deletions src/interactivity/win32/find.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ INT_PTR CALLBACK FindDialogProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM l
// This bool is used to track which option - up or down - was used to perform the last search. That way, the next time the
// find dialog is opened, it will default to the last used option.
static auto reverse = true;
static auto caseInsensitive = true;
static SearchFlag flags{ SearchFlag::CaseInsensitive };
static std::wstring lastFindString;
static Search searcher;

Expand All @@ -32,7 +32,7 @@ INT_PTR CALLBACK FindDialogProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM l
case WM_INITDIALOG:
SetWindowLongPtrW(hWnd, DWLP_USER, lParam);
CheckRadioButton(hWnd, ID_CONSOLE_FINDUP, ID_CONSOLE_FINDDOWN, (reverse ? ID_CONSOLE_FINDUP : ID_CONSOLE_FINDDOWN));
CheckDlgButton(hWnd, ID_CONSOLE_FINDCASE, !caseInsensitive);
CheckDlgButton(hWnd, ID_CONSOLE_FINDCASE, WI_IsFlagClear(flags, SearchFlag::CaseInsensitive));
SetDlgItemTextW(hWnd, ID_CONSOLE_FINDSTR, lastFindString.c_str());
return TRUE;
case WM_COMMAND:
Expand All @@ -46,15 +46,15 @@ INT_PTR CALLBACK FindDialogProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM l
length = GetDlgItemTextW(hWnd, ID_CONSOLE_FINDSTR, lastFindString.data(), gsl::narrow_cast<int>(length + 1));
lastFindString.resize(length);

caseInsensitive = IsDlgButtonChecked(hWnd, ID_CONSOLE_FINDCASE) == 0;
WI_UpdateFlag(flags, SearchFlag::CaseInsensitive, IsDlgButtonChecked(hWnd, ID_CONSOLE_FINDCASE) == 0);
reverse = IsDlgButtonChecked(hWnd, ID_CONSOLE_FINDDOWN) == 0;

LockConsole();
auto Unlock = wil::scope_exit([&] { UnlockConsole(); });

if (searcher.IsStale(gci.renderData, lastFindString, caseInsensitive))
if (searcher.IsStale(gci.renderData, lastFindString, flags))
{
searcher.Reset(gci.renderData, lastFindString, caseInsensitive, reverse);
searcher.Reset(gci.renderData, lastFindString, flags, reverse);
searcher.MoveToCurrentSelection();
}
else
Expand Down
4 changes: 2 additions & 2 deletions src/types/UiaTextRangeBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -631,9 +631,9 @@ try
// -> We need to turn [_beg,_end) into (_beg,_end).
exclusiveBegin.x--;

if (_searcher.IsStale(*_pData, queryText, ignoreCase))
if (_searcher.IsStale(*_pData, queryText, ignoreCase ? SearchFlag::CaseInsensitive : SearchFlag::None))
{
_searcher.Reset(*_pData, queryText, ignoreCase, searchBackward);
_searcher.Reset(*_pData, queryText, ignoreCase ? SearchFlag::CaseInsensitive : SearchFlag::None, searchBackward);
}
_searcher.MovePastPoint(searchBackward ? _end : exclusiveBegin);

Expand Down

0 comments on commit fc41d3a

Please sign in to comment.