namespace Terminal.Gui.Views;
/// Find and Replace functionality
public partial class TextView
{
#region Public Find/Replace Methods
/// Find the next text based on the match case with the option to replace it.
/// The text to find.
/// trueIf all the text was forward searched.falseotherwise.
/// The match case setting.
/// The match whole word setting.
/// The text to replace.
/// trueIf is replacing.falseotherwise.
/// trueIf the text was found.falseotherwise.
public bool FindNextText (
string textToFind,
out bool gaveFullTurn,
bool matchCase = false,
bool matchWholeWord = false,
string? textToReplace = null,
bool replace = false
)
{
if (_model.Count == 0)
{
gaveFullTurn = false;
return false;
}
SetWrapModel ();
ResetContinuousFind ();
(Point current, bool found) foundPos =
_model.FindNextText (textToFind, out gaveFullTurn, matchCase, matchWholeWord);
return SetFoundText (textToFind, foundPos, textToReplace, replace);
}
/// Find the previous text based on the match case with the option to replace it.
/// The text to find.
/// trueIf all the text was backward searched.falseotherwise.
/// The match case setting.
/// The match whole word setting.
/// The text to replace.
/// trueIf the text was found.falseotherwise.
/// trueIf the text was found.falseotherwise.
public bool FindPreviousText (
string textToFind,
out bool gaveFullTurn,
bool matchCase = false,
bool matchWholeWord = false,
string? textToReplace = null,
bool replace = false
)
{
if (_model.Count == 0)
{
gaveFullTurn = false;
return false;
}
SetWrapModel ();
ResetContinuousFind ();
(Point current, bool found) foundPos =
_model.FindPreviousText (textToFind, out gaveFullTurn, matchCase, matchWholeWord);
return SetFoundText (textToFind, foundPos, textToReplace, replace);
}
/// Reset the flag to stop continuous find.
public void FindTextChanged () { _continuousFind = false; }
/// Replaces all the text based on the match case.
/// The text to find.
/// The match case setting.
/// The match whole word setting.
/// The text to replace.
/// trueIf the text was found.falseotherwise.
public bool ReplaceAllText (
string textToFind,
bool matchCase = false,
bool matchWholeWord = false,
string? textToReplace = null
)
{
if (_isReadOnly || _model.Count == 0)
{
return false;
}
SetWrapModel ();
ResetContinuousFind ();
(Point current, bool found) foundPos =
_model.ReplaceAllText (textToFind, matchCase, matchWholeWord, textToReplace);
return SetFoundText (textToFind, foundPos, textToReplace, false, true);
}
#endregion
#region Private Find Helper Methods
private void ResetContinuousFind ()
{
if (!_continuousFind)
{
int col = IsSelecting ? _selectionStartColumn : CurrentColumn;
int row = IsSelecting ? _selectionStartRow : CurrentRow;
_model.ResetContinuousFind (new (col, row));
}
}
private void ResetContinuousFindTrack ()
{
// Handle some state here - whether the last command was a kill
// operation and the column tracking (up/down)
_lastWasKill = false;
_continuousFind = false;
}
private bool SetFoundText (
string text,
(Point current, bool found) foundPos,
string? textToReplace = null,
bool replace = false,
bool replaceAll = false
)
{
if (foundPos.found)
{
StartSelecting ();
_selectionStartColumn = foundPos.current.X;
_selectionStartRow = foundPos.current.Y;
if (!replaceAll)
{
CurrentColumn = _selectionStartColumn + text.GetRuneCount ();
}
else
{
CurrentColumn = _selectionStartColumn + textToReplace!.GetRuneCount ();
}
CurrentRow = foundPos.current.Y;
if (!_isReadOnly && replace)
{
Adjust ();
ClearSelectedRegion ();
InsertAllText (textToReplace!);
StartSelecting ();
_selectionStartColumn = CurrentColumn - textToReplace!.GetRuneCount ();
}
else
{
UpdateWrapModel ();
SetNeedsDraw ();
Adjust ();
}
_continuousFind = true;
return foundPos.found;
}
UpdateWrapModel ();
_continuousFind = false;
return foundPos.found;
}
private IEnumerable<(int col, int row, Cell rune)> ForwardIterator (int col, int row)
{
if (col < 0 || row < 0)
{
yield break;
}
if (row >= _model.Count)
{
yield break;
}
List| line = GetCurrentLine ();
if (col >= line.Count)
{
yield break;
}
while (row < _model.Count)
{
for (int c = col; c < line.Count; c++)
{
yield return (c, row, line [c]);
}
col = 0;
row++;
line = GetCurrentLine ();
}
}
#endregion
}
|