Fix find result current match count

This commit is contained in:
kit 2024-06-27 14:04:40 -04:00
parent cae2f853dc
commit 17c8e8b2b4
2 changed files with 44 additions and 17 deletions

View File

@ -347,18 +347,18 @@ void FindReplaceBar::_replace_all() {
needs_to_count_results = true; needs_to_count_results = true;
} }
void FindReplaceBar::_get_search_from(int &r_line, int &r_col, bool p_is_searching_next) { void FindReplaceBar::_get_search_from(int &r_line, int &r_col, SearchMode p_search_mode) {
if (!text_editor->has_selection(0) || is_selection_only()) { if (!text_editor->has_selection(0) || is_selection_only()) {
r_line = text_editor->get_caret_line(0); r_line = text_editor->get_caret_line(0);
r_col = text_editor->get_caret_column(0); r_col = text_editor->get_caret_column(0);
if (!p_is_searching_next && r_line == result_line && r_col >= result_col && r_col <= result_col + get_search_text().length()) { if (p_search_mode == SEARCH_PREV && r_line == result_line && r_col >= result_col && r_col <= result_col + get_search_text().length()) {
r_col = result_col; r_col = result_col;
} }
return; return;
} }
if (p_is_searching_next) { if (p_search_mode == SEARCH_NEXT) {
r_line = text_editor->get_selection_to_line(); r_line = text_editor->get_selection_to_line();
r_col = text_editor->get_selection_to_column(); r_col = text_editor->get_selection_to_column();
} else { } else {
@ -368,7 +368,11 @@ void FindReplaceBar::_get_search_from(int &r_line, int &r_col, bool p_is_searchi
} }
void FindReplaceBar::_update_results_count() { void FindReplaceBar::_update_results_count() {
if (!needs_to_count_results && (result_line != -1) && results_count_to_current > 0) { int caret_line, caret_column;
_get_search_from(caret_line, caret_column, SEARCH_CURRENT);
bool match_selected = caret_line == result_line && caret_column == result_col && !is_selection_only() && text_editor->has_selection(0);
if (match_selected && !needs_to_count_results && result_line != -1 && results_count_to_current > 0) {
results_count_to_current += (flags & TextEdit::SEARCH_BACKWARDS) ? -1 : 1; results_count_to_current += (flags & TextEdit::SEARCH_BACKWARDS) ? -1 : 1;
if (results_count_to_current > results_count) { if (results_count_to_current > results_count) {
@ -385,9 +389,10 @@ void FindReplaceBar::_update_results_count() {
return; return;
} }
needs_to_count_results = false; needs_to_count_results = !match_selected;
results_count = 0; results_count = 0;
results_count_to_current = 0;
for (int i = 0; i < text_editor->get_line_count(); i++) { for (int i = 0; i < text_editor->get_line_count(); i++) {
String line_text = text_editor->get_line(i); String line_text = text_editor->get_line(i);
@ -417,18 +422,26 @@ void FindReplaceBar::_update_results_count() {
results_count++; results_count++;
if (i == result_line) { if (i <= result_line && col_pos <= result_col) {
if (col_pos == result_col) { results_count_to_current = results_count;
results_count_to_current = results_count; }
} else if (col_pos < result_col && col_pos + searched.length() > result_col) { if (i == result_line && col_pos < result_col && col_pos + searched.length() > result_col) {
col_pos = result_col; // Searching forwards and backwards with repeating text can lead to different matches.
results_count_to_current = results_count; col_pos = result_col;
}
} }
col_pos += searched.length(); col_pos += searched.length();
} }
} }
if (!match_selected) {
// Current result should refer to the match before the caret, if the caret is not on a match.
if (caret_line != result_line || caret_column != result_col) {
results_count_to_current -= 1;
}
if (results_count_to_current == 0 && (caret_line > result_line || (caret_line == result_line && caret_column > result_col))) {
// Caret is after all matches.
results_count_to_current = results_count;
}
}
} }
void FindReplaceBar::_update_matches_display() { void FindReplaceBar::_update_matches_display() {
@ -457,7 +470,7 @@ bool FindReplaceBar::search_current() {
_update_flags(false); _update_flags(false);
int line, col; int line, col;
_get_search_from(line, col); _get_search_from(line, col, SEARCH_CURRENT);
return _search(flags, line, col); return _search(flags, line, col);
} }
@ -473,10 +486,14 @@ bool FindReplaceBar::search_prev() {
String text = get_search_text(); String text = get_search_text();
if ((flags & TextEdit::SEARCH_BACKWARDS) == 0) {
needs_to_count_results = true;
}
_update_flags(true); _update_flags(true);
int line, col; int line, col;
_get_search_from(line, col); _get_search_from(line, col, SEARCH_PREV);
col -= text.length(); col -= text.length();
if (col < 0) { if (col < 0) {
@ -499,10 +516,14 @@ bool FindReplaceBar::search_next() {
popup_search(true); popup_search(true);
} }
if (flags & TextEdit::SEARCH_BACKWARDS) {
needs_to_count_results = true;
}
_update_flags(false); _update_flags(false);
int line, col; int line, col;
_get_search_from(line, col, true); _get_search_from(line, col, SEARCH_NEXT);
return _search(flags, line, col); return _search(flags, line, col);
} }

View File

@ -64,6 +64,12 @@ class CodeTextEditor;
class FindReplaceBar : public HBoxContainer { class FindReplaceBar : public HBoxContainer {
GDCLASS(FindReplaceBar, HBoxContainer); GDCLASS(FindReplaceBar, HBoxContainer);
enum SearchMode {
SEARCH_CURRENT,
SEARCH_NEXT,
SEARCH_PREV,
};
LineEdit *search_text = nullptr; LineEdit *search_text = nullptr;
Label *matches_label = nullptr; Label *matches_label = nullptr;
Button *find_prev = nullptr; Button *find_prev = nullptr;
@ -94,7 +100,7 @@ class FindReplaceBar : public HBoxContainer {
bool replace_all_mode = false; bool replace_all_mode = false;
bool preserve_cursor = false; bool preserve_cursor = false;
void _get_search_from(int &r_line, int &r_col, bool p_is_searching_next = false); void _get_search_from(int &r_line, int &r_col, SearchMode p_search_mode);
void _update_results_count(); void _update_results_count();
void _update_matches_display(); void _update_matches_display();