Skip to content
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

Migrate Search module as a shared component for Terminal Search #3279

Merged
merged 11 commits into from
Nov 14, 2019
Merged
2 changes: 2 additions & 0 deletions src/buffer/out/lib/bufferout.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<ClCompile Include="..\OutputCellView.cpp" />
<ClCompile Include="..\Row.cpp" />
<ClCompile Include="..\RowCellIterator.cpp" />
<ClCompile Include="..\search.cpp" />
<ClCompile Include="..\TextColor.cpp" />
<ClCompile Include="..\TextAttribute.cpp" />
<ClCompile Include="..\TextAttributeRun.cpp" />
Expand All @@ -37,6 +38,7 @@
<ClInclude Include="..\OutputCellView.hpp" />
<ClInclude Include="..\Row.hpp" />
<ClInclude Include="..\RowCellIterator.hpp" />
<ClInclude Include="..\search.h" />
<ClInclude Include="..\TextColor.h" />
<ClInclude Include="..\TextAttribute.h" />
<ClInclude Include="..\TextAttributeRun.h" />
Expand Down
58 changes: 32 additions & 26 deletions src/host/search.cpp → src/buffer/out/search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,32 @@

#include "search.h"

#include "dbcs.h"
#include "../buffer/out/CharRow.hpp"
#include "CharRow.hpp"
#include "textBuffer.hpp"
#include "../types/inc/Utf16Parser.hpp"
#include "../types/inc/GlyphWidth.hpp"

using namespace Microsoft::Console::Types;

// Routine Description:
// - Constructs a Search object.
// - Make a Search object then call .FindNext() to locate items.
// - Once you've found something, you can perfom actions like .Select() or .Color()
// Arguments:
// - screenInfo - The screen buffer to search through (the "haystack")
// - textBuffer - The screen text buffer to search through (the "haystack")
// - uiaData - The IUiaData type reference, it is for providing selection methods
// - str - The search term you want to find (the "needle")
// - direction - The direction to search (upward or downward)
// - sensitivity - Whether or not you care about case
Search::Search(const SCREEN_INFORMATION& screenInfo,
Search::Search(IUiaData& uiaData,
const std::wstring& str,
const Direction direction,
const Sensitivity sensitivity) :
_direction(direction),
_sensitivity(sensitivity),
_screenInfo(screenInfo),
_needle(s_CreateNeedleFromString(str)),
_coordAnchor(s_GetInitialAnchor(screenInfo, direction))
_uiaData(uiaData),
_coordAnchor(_GetInitialAnchor(uiaData, direction))
{
_coordNext = _coordAnchor;
}
Expand All @@ -37,21 +40,22 @@ Search::Search(const SCREEN_INFORMATION& screenInfo,
// - Make a Search object then call .FindNext() to locate items.
// - Once you've found something, you can perfom actions like .Select() or .Color()
// Arguments:
// - screenInfo - The screen buffer to search through (the "haystack")
// - textBuffer - The screen text buffer to search through (the "haystack")
// - uiaData - The IUiaData type reference, it is for providing selection methods
// - str - The search term you want to find (the "needle")
// - direction - The direction to search (upward or downward)
// - sensitivity - Whether or not you care about case
// - anchor - starting search location in screenInfo
Search::Search(const SCREEN_INFORMATION& screenInfo,
Search::Search(IUiaData& uiaData,
const std::wstring& str,
const Direction direction,
const Sensitivity sensitivity,
const COORD anchor) :
_direction(direction),
_sensitivity(sensitivity),
_screenInfo(screenInfo),
_needle(s_CreateNeedleFromString(str)),
_coordAnchor(anchor)
_coordAnchor(anchor),
_uiaData(uiaData)
{
_coordNext = _coordAnchor;
}
Expand Down Expand Up @@ -96,20 +100,21 @@ void Search::Select() const
// Only select if we've found something.
if (_coordSelStart != _coordSelEnd)
{
Selection::Instance().SelectNewRegion(_coordSelStart, _coordSelEnd);
_uiaData.SelectNewRegion(_coordSelStart, _coordSelEnd);
}
}

// Routine Description:
// - Takes the found word and applies the given color to it in the screen buffer
// - In console host, we take the found word and apply the given color to it in the screen buffer
// - In Windows Terminal, we just select the found word, but we do not ,modify the buffer
KaiyuWang16 marked this conversation as resolved.
Show resolved Hide resolved
// Arguments:
// - ulAttr - The legacy color attribute to apply to the word
void Search::Color(const TextAttribute attr) const
KaiyuWang16 marked this conversation as resolved.
Show resolved Hide resolved
{
// Only select if we've found something.
if (_coordSelStart != _coordSelEnd)
{
Selection::Instance().ColorSelection(_coordSelStart, _coordSelEnd, attr);
_uiaData.ColorSelection(_coordSelStart, _coordSelEnd, attr);
}
}

Expand All @@ -130,22 +135,23 @@ std::pair<COORD, COORD> Search::GetFoundLocation() const noexcept
// - If the screen buffer given already has a selection in it, it will be used to determine the anchor.
// - Otherwise, we will choose one of the ends of the screen buffer depending on direction.
// Arguments:
// - screenInfo - The screen buffer for determining the anchor
// - uiaData - The reference to the IUiaData interface type object
// - direction - The intended direction of the search
// Return Value:
// - Coordinate to start the search from.
COORD Search::s_GetInitialAnchor(const SCREEN_INFORMATION& screenInfo, const Direction direction)
COORD Search::_GetInitialAnchor(IUiaData& uiaData, const Direction direction)
{
if (Selection::Instance().IsInSelectingState())
const auto& textBuffer = uiaData.GetTextBuffer();
if (uiaData.IsSelectionActive())
{
auto anchor = Selection::Instance().GetSelectionAnchor();
auto anchor = uiaData.GetSelectionAnchor();
if (direction == Direction::Forward)
{
screenInfo.GetBufferSize().IncrementInBoundsCircular(anchor);
textBuffer.GetSize().IncrementInBoundsCircular(anchor);
}
else
{
screenInfo.GetBufferSize().DecrementInBoundsCircular(anchor);
textBuffer.GetSize().DecrementInBoundsCircular(anchor);
}
return anchor;
}
Expand All @@ -157,7 +163,7 @@ COORD Search::s_GetInitialAnchor(const SCREEN_INFORMATION& screenInfo, const Dir
}
else
{
const auto bufferSize = screenInfo.GetBufferSize().Dimensions();
const auto bufferSize = textBuffer.GetSize().Dimensions();
return { bufferSize.X - 1, bufferSize.Y - 1 };
}
}
Expand All @@ -183,7 +189,7 @@ bool Search::_FindNeedleInHaystackAt(const COORD pos, COORD& start, COORD& end)
for (const auto& needleCell : _needle)
{
// Haystack is the buffer. Needle is the string we were given.
const auto hayIter = _screenInfo.GetTextDataAt(bufferPos);
const auto hayIter = _uiaData.GetTextBuffer().GetTextDataAt(bufferPos);
const auto hayChars = *hayIter;
const auto needleChars = std::wstring_view(needleCell.data(), needleCell.size());

Expand Down Expand Up @@ -214,7 +220,7 @@ bool Search::_FindNeedleInHaystackAt(const COORD pos, COORD& start, COORD& end)
// - two - String view representing the second string of text
// Return Value:
// - True if they are the same. False otherwise.
bool Search::_CompareChars(const std::wstring_view one, const std::wstring_view two) const
bool Search::_CompareChars(const std::wstring_view one, const std::wstring_view two) const noexcept
{
if (one.size() != two.size())
{
Expand All @@ -223,7 +229,7 @@ bool Search::_CompareChars(const std::wstring_view one, const std::wstring_view

for (size_t i = 0; i < one.size(); i++)
{
if (_ApplySensitivity(one[i]) != _ApplySensitivity(two[i]))
if (_ApplySensitivity(gsl::at(one, i)) != _ApplySensitivity(gsl::at(two, i)))
KaiyuWang16 marked this conversation as resolved.
Show resolved Hide resolved
{
return false;
}
Expand All @@ -239,7 +245,7 @@ bool Search::_CompareChars(const std::wstring_view one, const std::wstring_view
// - wch - Character to adjust if necessary
// Return Value:
// - Adjusted value (or not).
wchar_t Search::_ApplySensitivity(const wchar_t wch) const
wchar_t Search::_ApplySensitivity(const wchar_t wch) const noexcept
{
if (_sensitivity == Sensitivity::CaseInsensitive)
{
Expand All @@ -257,7 +263,7 @@ wchar_t Search::_ApplySensitivity(const wchar_t wch) const
// - coord - Updated by function to increment one position (will wrap X and Y direction)
void Search::_IncrementCoord(COORD& coord) const
{
_screenInfo.GetBufferSize().IncrementInBoundsCircular(coord);
_uiaData.GetTextBuffer().GetSize().IncrementInBoundsCircular(coord);
}

// Routine Description:
Expand All @@ -266,7 +272,7 @@ void Search::_IncrementCoord(COORD& coord) const
// - coord - Updated by function to decrement one position (will wrap X and Y direction)
void Search::_DecrementCoord(COORD& coord) const
{
_screenInfo.GetBufferSize().DecrementInBoundsCircular(coord);
_uiaData.GetTextBuffer().GetSize().DecrementInBoundsCircular(coord);
}

// Routine Description:
Expand Down
20 changes: 13 additions & 7 deletions src/host/search.h → src/buffer/out/search.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ Revision History:

#pragma once

#include <WinConTypes.h>
#include "TextAttribute.hpp"
#include "textBuffer.hpp"
#include "../types/IUiaData.h"

// This used to be in find.h.
#define SEARCH_STRING_LENGTH (80)

Expand All @@ -35,12 +40,12 @@ class Search final
CaseSensitive
};

Search(const SCREEN_INFORMATION& ScreenInfo,
Search(Microsoft::Console::Types::IUiaData& uiaData,
const std::wstring& str,
const Direction dir,
const Sensitivity sensitivity);

Search(const SCREEN_INFORMATION& ScreenInfo,
Search(Microsoft::Console::Types::IUiaData& uiaData,
const std::wstring& str,
const Direction dir,
const Sensitivity sensitivity,
Expand All @@ -53,27 +58,28 @@ class Search final
std::pair<COORD, COORD> GetFoundLocation() const noexcept;

private:
wchar_t _ApplySensitivity(const wchar_t wch) const;
wchar_t _ApplySensitivity(const wchar_t wch) const noexcept;
bool Search::_FindNeedleInHaystackAt(const COORD pos, COORD& start, COORD& end) const;
bool _CompareChars(const std::wstring_view one, const std::wstring_view two) const;
bool _CompareChars(const std::wstring_view one, const std::wstring_view two) const noexcept;
void _UpdateNextPosition();

void _IncrementCoord(COORD& coord) const;
void _DecrementCoord(COORD& coord) const;

static COORD s_GetInitialAnchor(const SCREEN_INFORMATION& screenInfo, const Direction dir);
COORD _GetInitialAnchor(Microsoft::Console::Types::IUiaData& uiaData, const Direction dir);
KaiyuWang16 marked this conversation as resolved.
Show resolved Hide resolved

static std::vector<std::vector<wchar_t>> s_CreateNeedleFromString(const std::wstring& wstr);

bool _reachedEnd = false;
COORD _coordNext = { 0 };
COORD _coordSelStart = { 0 };
COORD _coordSelEnd = { 0 };

const COORD _coordAnchor;
KaiyuWang16 marked this conversation as resolved.
Show resolved Hide resolved
const COORD _coordAnchor = { 0 };
KaiyuWang16 marked this conversation as resolved.
Show resolved Hide resolved
const std::vector<std::vector<wchar_t>> _needle;
const Direction _direction;
const Sensitivity _sensitivity;
const SCREEN_INFORMATION& _screenInfo;
Microsoft::Console::Types::IUiaData& _uiaData;

#ifdef UNIT_TESTING
friend class SearchTests;
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalCore/Terminal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,9 @@ class Microsoft::Terminal::Core::Terminal final :
const bool IsSelectionActive() const noexcept;
void ClearSelection() override;
void SelectNewRegion(const COORD coordStart, const COORD coordEnd) override;
const COORD GetSelectionAnchor() const override;
const std::wstring GetConsoleTitle() const noexcept override;
void ColorSelection(const COORD coordSelectionStart, const COORD coordSelectionEnd, const TextAttribute) override;
#pragma endregion

void SetWriteInputCallback(std::function<void(std::wstring&)> pfn) noexcept;
Expand Down
22 changes: 22 additions & 0 deletions src/cascadia/TerminalCore/TerminalSelection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,17 @@ SMALL_RECT Terminal::_GetSelectionRow(const SHORT row, const COORD higherCoord,
return selectionRow;
}

// Method Description:
// - Get the current anchor position
// Arguments:
// - None
// Return Value:
// - None
const COORD Terminal::GetSelectionAnchor() const
{
return _selectionAnchor;
}

// Method Description:
// - Expand the selection row according to selection mode and wide glyphs
// - this is particularly useful for box selections (ALT + selection)
Expand Down Expand Up @@ -455,3 +466,14 @@ COORD Terminal::_ConvertToBufferCell(const COORD viewportPos) const
THROW_IF_FAILED(ShortAdd(positionWithOffsets.Y, gsl::narrow<SHORT>(_ViewStartIndex()), &positionWithOffsets.Y));
return positionWithOffsets;
}

// Method Description:
// - Given two points in the buffer space, select the text only because we do not want to modify to the buffer in Terminal
// Arguments:
// - coordSelectionStart - Anchor point (start of selection) for the region to be colored
// - coordSelectionEnd - Other point referencing the rectangle inscribing the selection area
// - attr - Not used.
void Terminal::ColorSelection(const COORD coordSelectionStart, const COORD coordSelectionEnd, const TextAttribute)
{
SelectNewRegion(coordSelectionStart, coordSelectionEnd);
KaiyuWang16 marked this conversation as resolved.
Show resolved Hide resolved
}
2 changes: 0 additions & 2 deletions src/host/host-common.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
<ClCompile Include="..\screenInfo.cpp" />
<ClCompile Include="..\ScreenBufferRenderTarget.cpp" />
<ClCompile Include="..\scrolling.cpp" />
<ClCompile Include="..\search.cpp" />
<ClCompile Include="..\selection.cpp" />
<ClCompile Include="..\selectionInput.cpp" />
<ClCompile Include="..\selectionState.cpp" />
Expand Down Expand Up @@ -105,7 +104,6 @@
<ClInclude Include="..\screenInfo.hpp" />
<ClInclude Include="..\ScreenBufferRenderTarget.hpp" />
<ClInclude Include="..\scrolling.hpp" />
<ClInclude Include="..\search.h" />
<ClInclude Include="..\selection.hpp" />
<ClInclude Include="..\server.h" />
<ClInclude Include="..\settings.hpp" />
Expand Down
8 changes: 1 addition & 7 deletions src/host/lib/hostlib.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,6 @@
<ClCompile Include="..\ntprivapi.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\search.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\init.cpp">
<Filter>Source Files</Filter>
</ClCompile>
Expand Down Expand Up @@ -299,9 +296,6 @@
<ClInclude Include="..\ntprivapi.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\search.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\init.hpp">
<Filter>Header Files</Filter>
</ClInclude>
Expand Down Expand Up @@ -360,4 +354,4 @@
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
</Project>
24 changes: 24 additions & 0 deletions src/host/renderData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,4 +369,28 @@ void RenderData::SelectNewRegion(const COORD coordStart, const COORD coordEnd)
{
Selection::Instance().SelectNewRegion(coordStart, coordEnd);
}

// Routine Description:
// - Gets the current selection anchor position
// Arguments:
// - none
// Return Value:
// - current selection anchor
const COORD RenderData::GetSelectionAnchor() const
{
return Selection::Instance().GetSelectionAnchor();
}

// Routine Description:
// - Given two points in the buffer space, color the selection between the two with the given attribute.
// - This will create an internal selection rectangle covering the two points, assume a line selection,
// and use the first point as the anchor for the selection (as if the mouse click started at that point)
// Arguments:
// - coordSelectionStart - Anchor point (start of selection) for the region to be colored
// - coordSelectionEnd - Other point referencing the rectangle inscribing the selection area
// - attr - Color to apply to region.
void RenderData::ColorSelection(const COORD coordSelectionStart, const COORD coordSelectionEnd, const TextAttribute attr)
{
Selection::Instance().ColorSelection(coordSelectionStart, coordSelectionEnd, attr);
}
#pragma endregion
2 changes: 2 additions & 0 deletions src/host/renderData.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,7 @@ class RenderData final :
const bool IsSelectionActive() const override;
void ClearSelection() override;
void SelectNewRegion(const COORD coordStart, const COORD coordEnd) override;
const COORD GetSelectionAnchor() const;
void ColorSelection(const COORD coordSelectionStart, const COORD coordSelectionEnd, const TextAttribute attr);
#pragma endregion
};
Loading