소스 검색

Fix find result current match count

kit 1 년 전
부모
커밋
17c8e8b2b4
2개의 변경된 파일44개의 추가작업 그리고 17개의 파일을 삭제
  1. 37 16
      editor/code_editor.cpp
  2. 7 1
      editor/code_editor.h

+ 37 - 16
editor/code_editor.cpp

@@ -347,18 +347,18 @@ void FindReplaceBar::_replace_all() {
 	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()) {
 		r_line = text_editor->get_caret_line(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;
 		}
 		return;
 	}
 
-	if (p_is_searching_next) {
+	if (p_search_mode == SEARCH_NEXT) {
 		r_line = text_editor->get_selection_to_line();
 		r_col = text_editor->get_selection_to_column();
 	} 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() {
-	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;
 
 		if (results_count_to_current > results_count) {
@@ -385,9 +389,10 @@ void FindReplaceBar::_update_results_count() {
 		return;
 	}
 
-	needs_to_count_results = false;
+	needs_to_count_results = !match_selected;
 
 	results_count = 0;
+	results_count_to_current = 0;
 
 	for (int i = 0; i < text_editor->get_line_count(); i++) {
 		String line_text = text_editor->get_line(i);
@@ -417,18 +422,26 @@ void FindReplaceBar::_update_results_count() {
 
 			results_count++;
 
-			if (i == result_line) {
-				if (col_pos == result_col) {
-					results_count_to_current = results_count;
-				} else if (col_pos < result_col && col_pos + searched.length() > result_col) {
-					col_pos = result_col;
-					results_count_to_current = results_count;
-				}
+			if (i <= result_line && col_pos <= result_col) {
+				results_count_to_current = results_count;
+			}
+			if (i == result_line && col_pos < result_col && col_pos + searched.length() > result_col) {
+				// Searching forwards and backwards with repeating text can lead to different matches.
+				col_pos = result_col;
 			}
-
 			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() {
@@ -457,7 +470,7 @@ bool FindReplaceBar::search_current() {
 	_update_flags(false);
 
 	int line, col;
-	_get_search_from(line, col);
+	_get_search_from(line, col, SEARCH_CURRENT);
 
 	return _search(flags, line, col);
 }
@@ -473,10 +486,14 @@ bool FindReplaceBar::search_prev() {
 
 	String text = get_search_text();
 
+	if ((flags & TextEdit::SEARCH_BACKWARDS) == 0) {
+		needs_to_count_results = true;
+	}
+
 	_update_flags(true);
 
 	int line, col;
-	_get_search_from(line, col);
+	_get_search_from(line, col, SEARCH_PREV);
 
 	col -= text.length();
 	if (col < 0) {
@@ -499,10 +516,14 @@ bool FindReplaceBar::search_next() {
 		popup_search(true);
 	}
 
+	if (flags & TextEdit::SEARCH_BACKWARDS) {
+		needs_to_count_results = true;
+	}
+
 	_update_flags(false);
 
 	int line, col;
-	_get_search_from(line, col, true);
+	_get_search_from(line, col, SEARCH_NEXT);
 
 	return _search(flags, line, col);
 }

+ 7 - 1
editor/code_editor.h

@@ -64,6 +64,12 @@ class CodeTextEditor;
 class FindReplaceBar : public HBoxContainer {
 	GDCLASS(FindReplaceBar, HBoxContainer);
 
+	enum SearchMode {
+		SEARCH_CURRENT,
+		SEARCH_NEXT,
+		SEARCH_PREV,
+	};
+
 	LineEdit *search_text = nullptr;
 	Label *matches_label = nullptr;
 	Button *find_prev = nullptr;
@@ -94,7 +100,7 @@ class FindReplaceBar : public HBoxContainer {
 	bool replace_all_mode = 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_matches_display();