Skip to content

Commit

Permalink
fix: F3 failed to locate the correct set of matches if file was edite…
Browse files Browse the repository at this point in the history
…d after doing a search (#1867)

### Problem description
The bug can be reproduced as follows:
1) Using Ctrl-F do a search for a term that occurs several times in the
file. and press F3 to visit them.
2) Go back to the fop of the file and insert 3 blank lines. 
3) Pressing F3 once or many times will not find the term entered above.


### Implementation description
The reason for this bug is that the positions of the matches are not
being reset when changes can potentially move them.
The fix consists on resetting the search locations when changing the
contents of the file and redoing the search after the changes are made.
The bug was specially problematic when doing replace because the
replacement position would be identified as a match. This PR fixes
replace as well.

---------

Co-authored-by: Nik <[email protected]>
  • Loading branch information
paxcut and WerWolv authored Sep 15, 2024
1 parent 866b956 commit 96a588b
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 27 deletions.
2 changes: 1 addition & 1 deletion lib/third_party/imgui/ColorTextEditor/include/TextEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ class TextEditor

ImVec2 &GetCharAdvance() { return mCharAdvance; }

bool CanUndo() const;
bool CanUndo();
bool CanRedo() const;
void Undo(int aSteps = 1);
void Redo(int aSteps = 1);
Expand Down
100 changes: 74 additions & 26 deletions lib/third_party/imgui/ColorTextEditor/source/TextEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -794,7 +794,8 @@ void TextEditor::HandleMouseInputs() {
mSelectionMode = SelectionMode::Normal;
}
SetSelection(mInteractiveStart, mInteractiveEnd, mSelectionMode);
resetBlinking=true;
ResetCursorBlinkTime();

EnsureCursorVisible();
mLastClick = (float)ImGui::GetTime();
}
Expand Down Expand Up @@ -1412,6 +1413,13 @@ void TextEditor::EnterCharacter(ImWchar aChar, bool aShift) {
AddUndo(u);

Colorize(coord.mLine - 1, 3);

std::string findWord = mFindReplaceHandler.GetFindWord();
if (!findWord.empty()) {
mFindReplaceHandler.resetMatches();
mFindReplaceHandler.FindAllMatches(this, findWord);
}

EnsureCursorVisible();
}

Expand Down Expand Up @@ -1499,6 +1507,12 @@ void TextEditor::InsertText(const char *aValue) {

SetSelection(pos, pos);
SetCursorPosition(pos);

std::string findWord = mFindReplaceHandler.GetFindWord();
if (!findWord.empty()) {
mFindReplaceHandler.resetMatches();
mFindReplaceHandler.FindAllMatches(this, findWord);
}
Colorize(start.mLine - 1, totalLines + 2);
}

Expand All @@ -1512,6 +1526,11 @@ void TextEditor::DeleteSelection() {

SetSelection(mState.mSelectionStart, mState.mSelectionStart);
SetCursorPosition(mState.mSelectionStart);
std::string findWord = mFindReplaceHandler.GetFindWord();
if (!findWord.empty()) {
mFindReplaceHandler.resetMatches();
mFindReplaceHandler.FindAllMatches(this, findWord);
}
Colorize(mState.mSelectionStart.mLine, 1);
}

Expand Down Expand Up @@ -1798,6 +1817,11 @@ void TextEditor::Delete() {

u.mAfter = mState;
AddUndo(u);
std::string findWord = mFindReplaceHandler.GetFindWord();
if (!findWord.empty()) {
mFindReplaceHandler.resetMatches();
mFindReplaceHandler.FindAllMatches(this, findWord);
}
}

void TextEditor::Backspace() {
Expand Down Expand Up @@ -1866,6 +1890,11 @@ void TextEditor::Backspace() {

u.mAfter = mState;
AddUndo(u);
std::string findWord = mFindReplaceHandler.GetFindWord();
if (!findWord.empty()) {
mFindReplaceHandler.resetMatches();
mFindReplaceHandler.FindAllMatches(this, findWord);
}
}

void TextEditor::SelectWordUnderCursor() {
Expand Down Expand Up @@ -1913,6 +1942,11 @@ void TextEditor::Cut() {
AddUndo(u);
}
}
std::string findWord = mFindReplaceHandler.GetFindWord();
if (!findWord.empty()) {
mFindReplaceHandler.resetMatches();
mFindReplaceHandler.FindAllMatches(this, findWord);
}
}

void TextEditor::Paste() {
Expand Down Expand Up @@ -1940,9 +1974,14 @@ void TextEditor::Paste() {
u.mAfter = mState;
AddUndo(u);
}
std::string findWord = mFindReplaceHandler.GetFindWord();
if (!findWord.empty()) {
mFindReplaceHandler.resetMatches();
mFindReplaceHandler.FindAllMatches(this, findWord);
}
}

bool TextEditor::CanUndo() const {
bool TextEditor::CanUndo() {
return !mReadOnly && mUndoIndex > 0;
}

Expand All @@ -1953,11 +1992,21 @@ bool TextEditor::CanRedo() const {
void TextEditor::Undo(int aSteps) {
while (CanUndo() && aSteps-- > 0)
mUndoBuffer[--mUndoIndex].Undo(this);
std::string findWord = mFindReplaceHandler.GetFindWord();
if (!findWord.empty()) {
mFindReplaceHandler.resetMatches();
mFindReplaceHandler.FindAllMatches(this, findWord);
}
}

void TextEditor::Redo(int aSteps) {
while (CanRedo() && aSteps-- > 0)
mUndoBuffer[mUndoIndex++].Redo(this);
std::string findWord = mFindReplaceHandler.GetFindWord();
if (!findWord.empty()) {
mFindReplaceHandler.resetMatches();
mFindReplaceHandler.FindAllMatches(this, findWord);
}
}

// the index here is array index so zero based
Expand Down Expand Up @@ -2096,7 +2145,7 @@ bool TextEditor::FindReplaceHandler::FindNext(TextEditor *editor, bool wrapAroun
curPos.mLine = mMatches.empty() ? editor->mState.mCursorPosition.mLine : mMatches.back().mCursorPosition.mLine;
curPos.mColumn = mMatches.empty() ? editor->mState.mCursorPosition.mColumn : editor->Utf8CharsToBytes(
mMatches.back().mCursorPosition);

unsigned long selectionLength = editor->GetStringCharacterCount(mFindWord);
size_t byteIndex = 0;

Expand All @@ -2123,13 +2172,13 @@ bool TextEditor::FindReplaceHandler::FindNext(TextEditor *editor, bool wrapAroun
if (GetFindRegEx()) {
try {
regularExpression.assign(wordLower);
} catch (std::regex_error &e) {
} catch (const std::regex_error &e) {
return false;
}
} else {
try {
regularExpression.assign(make_wholeWord(wordLower));
} catch (std::regex_error &e) {
} catch (const std::regex_error &e) {
return false;
}
}
Expand Down Expand Up @@ -2159,10 +2208,8 @@ bool TextEditor::FindReplaceHandler::FindNext(TextEditor *editor, bool wrapAroun

textLoc = pos;
if (wrapAround) {
if (iter == end) {
pos = firstLoc;
if (iter == end)
selectionLength = firstLength;
}
}
} else {
// non regex search
Expand Down Expand Up @@ -2203,16 +2250,18 @@ bool TextEditor::FindReplaceHandler::FindNext(TextEditor *editor, bool wrapAroun
selStart.mColumn = editor->Utf8BytesToChars(curPos);
selEnd = selStart;
selEnd.mColumn += selectionLength;
editor->SetSelection(selStart, selEnd);
editor->SetCursorPosition(selEnd);
editor->mScrollToCursor = true;
TextEditor::EditorState state;
state.mSelectionStart = selStart;
state.mSelectionEnd = selEnd;
state.mCursorPosition = selEnd;
mMatches.push_back(state);
return true;
}

void TextEditor::FindReplaceHandler::FindAllMatches(TextEditor *editor,std::string findWord) {

if (findWord.empty()) {
editor->mScrollToCursor = true;
editor->EnsureCursorVisible();
mFindWord = "";
mMatches.clear();
return;
Expand All @@ -2227,32 +2276,30 @@ void TextEditor::FindReplaceHandler::FindAllMatches(TextEditor *editor,std::stri
mMatches.clear();
mFindWord = findWord;
auto startingPos = editor->mState.mCursorPosition;
auto state = editor->mState;
auto saveState = editor->mState;
Coordinates begin = Coordinates(0,0);
editor->mState.mCursorPosition = begin;

if (!FindNext(editor,false)) {
editor->mState = state;
editor->mScrollToCursor = true;
editor->mState = saveState;
editor->EnsureCursorVisible();
return;
}
auto initialPos = editor->mState.mCursorPosition;
mMatches.push_back(editor->mState);
TextEditor::EditorState state = mMatches.back();

while( editor->mState.mCursorPosition < startingPos) {
while( state.mCursorPosition < startingPos) {
if (!FindNext(editor,false)) {
editor->mState = state;
editor->mScrollToCursor = true;
editor->mState = saveState;
editor->EnsureCursorVisible();
return;
}
mMatches.push_back(editor->mState);
state = mMatches.back();
}

while (FindNext(editor,false))
mMatches.push_back(editor->mState);
while (FindNext(editor,false));

editor->mState = state;
editor->mScrollToCursor = true;
editor->mState = saveState;
editor->EnsureCursorVisible();
return;
}

Expand Down Expand Up @@ -2299,7 +2346,7 @@ bool TextEditor::FindReplaceHandler::Replace(TextEditor *editor, bool next) {

u.mAddedEnd = editor->GetActualCursorCoordinates();

editor->mScrollToCursor = true;
editor->EnsureCursorVisible();
ImGui::SetKeyboardFocusHere(0);

u.mAfter = editor->mState;
Expand Down Expand Up @@ -2885,6 +2932,7 @@ void TextEditor::UndoRecord::Redo(TextEditor *aEditor) {

aEditor->mState = mAfter;
aEditor->EnsureCursorVisible();

}

bool TokenizeCStyleString(const char *in_begin, const char *in_end, const char *&out_begin, const char *&out_end) {
Expand Down

0 comments on commit 96a588b

Please sign in to comment.