summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2023-10-05 10:08:58 +0200
committerRémi Verschelde <rverschelde@gmail.com>2023-10-05 10:08:58 +0200
commitaa554e82785ff4c446532f121427c6ea6b4d15e6 (patch)
tree0a1e834a0b19647a6586f5e25db6c87ac5065757
parent829d9bb6ba24ad955ac8fd29a88ed25572adc1dd (diff)
parent676627e1d16367616c7022df8d12c836c201c5f4 (diff)
downloadredot-engine-aa554e82785ff4c446532f121427c6ea6b4d15e6.tar.gz
Merge pull request #82694 from BrianMacIntosh/master
"Whole Words" search can detect word boundaries inside the search term.
-rw-r--r--editor/code_editor.cpp7
-rw-r--r--scene/gui/text_edit.cpp14
-rw-r--r--tests/scene/test_text_edit.h7
3 files changed, 21 insertions, 7 deletions
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index 56e405bfcf..64467bc254 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -368,6 +368,9 @@ void FindReplaceBar::_update_results_count() {
int col_pos = 0;
+ bool searched_start_is_symbol = is_symbol(searched[0]);
+ bool searched_end_is_symbol = is_symbol(searched[searched.length() - 1]);
+
while (true) {
col_pos = is_case_sensitive() ? line_text.find(searched, col_pos) : line_text.findn(searched, col_pos);
@@ -376,11 +379,11 @@ void FindReplaceBar::_update_results_count() {
}
if (is_whole_words()) {
- if (col_pos > 0 && !is_symbol(line_text[col_pos - 1])) {
+ if (!searched_start_is_symbol && col_pos > 0 && !is_symbol(line_text[col_pos - 1])) {
col_pos += searched.length();
continue;
}
- if (col_pos + searched.length() < line_text.length() && !is_symbol(line_text[col_pos + searched.length()])) {
+ if (!searched_end_is_symbol && col_pos + searched.length() < line_text.length() && !is_symbol(line_text[col_pos + searched.length()])) {
col_pos += searched.length();
continue;
}
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 1642d19b67..3d426b8bf3 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -4112,6 +4112,9 @@ Point2i TextEdit::search(const String &p_key, uint32_t p_search_flags, int p_fro
int line = p_from_line;
int pos = -1;
+ bool key_start_is_symbol = is_symbol(p_key[0]);
+ bool key_end_is_symbol = is_symbol(p_key[p_key.length() - 1]);
+
for (int i = 0; i < text.size() + 1; i++) {
if (line < 0) {
line = text.size() - 1;
@@ -4175,9 +4178,9 @@ Point2i TextEdit::search(const String &p_key, uint32_t p_search_flags, int p_fro
if (pos != -1 && (p_search_flags & SEARCH_WHOLE_WORDS)) {
// Validate for whole words.
- if (pos > 0 && !is_symbol(text_line[pos - 1])) {
+ if (!key_start_is_symbol && pos > 0 && !is_symbol(text_line[pos - 1])) {
is_match = false;
- } else if (pos + p_key.length() < text_line.length() && !is_symbol(text_line[pos + p_key.length()])) {
+ } else if (!key_end_is_symbol && pos + p_key.length() < text_line.length() && !is_symbol(text_line[pos + p_key.length()])) {
is_match = false;
}
}
@@ -7022,6 +7025,9 @@ int TextEdit::_get_column_pos_of_word(const String &p_key, const String &p_searc
p_from_column = 0;
}
+ bool key_start_is_symbol = is_symbol(p_key[0]);
+ bool key_end_is_symbol = is_symbol(p_key[p_key.length() - 1]);
+
while (col == -1 && p_from_column <= p_search.length()) {
if (p_search_flags & SEARCH_MATCH_CASE) {
col = p_search.find(p_key, p_from_column);
@@ -7038,9 +7044,9 @@ int TextEdit::_get_column_pos_of_word(const String &p_key, const String &p_searc
if (col != -1 && p_search_flags & SEARCH_WHOLE_WORDS) {
p_from_column = col;
- if (col > 0 && !is_symbol(p_search[col - 1])) {
+ if (!key_start_is_symbol && col > 0 && !is_symbol(p_search[col - 1])) {
col = -1;
- } else if ((col + p_key.length()) < p_search.length() && !is_symbol(p_search[col + p_key.length()])) {
+ } else if (!key_end_is_symbol && (col + p_key.length()) < p_search.length() && !is_symbol(p_search[col + p_key.length()])) {
col = -1;
}
}
diff --git a/tests/scene/test_text_edit.h b/tests/scene/test_text_edit.h
index 7e9b472af1..840a04becf 100644
--- a/tests/scene/test_text_edit.h
+++ b/tests/scene/test_text_edit.h
@@ -3193,7 +3193,7 @@ TEST_CASE("[SceneTree][TextEdit] search") {
TextEdit *text_edit = memnew(TextEdit);
SceneTree::get_singleton()->get_root()->add_child(text_edit);
- text_edit->set_text("hay needle, hay\nHAY NEEDLE, HAY");
+ text_edit->set_text("hay needle, hay\nHAY NEEDLE, HAY\nwordword.word.word");
int length = text_edit->get_line(1).length();
CHECK(text_edit->search("test", 0, 0, 0) == Point2i(-1, -1));
@@ -3225,6 +3225,11 @@ TEST_CASE("[SceneTree][TextEdit] search") {
CHECK(text_edit->search("need", TextEdit::SEARCH_WHOLE_WORDS | TextEdit::SEARCH_MATCH_CASE, 0, 0) == Point2i(-1, -1));
CHECK(text_edit->search("need", TextEdit::SEARCH_WHOLE_WORDS | TextEdit::SEARCH_MATCH_CASE | TextEdit::SEARCH_BACKWARDS, 0, 0) == Point2i(-1, -1));
+ CHECK(text_edit->search("word", TextEdit::SEARCH_WHOLE_WORDS, 2, 0) == Point2i(9, 2));
+ CHECK(text_edit->search("word", TextEdit::SEARCH_WHOLE_WORDS, 2, 10) == Point2i(14, 2));
+ CHECK(text_edit->search(".word", TextEdit::SEARCH_WHOLE_WORDS, 2, 0) == Point2i(8, 2));
+ CHECK(text_edit->search("word.", TextEdit::SEARCH_WHOLE_WORDS, 2, 0) == Point2i(9, 2));
+
ERR_PRINT_OFF;
CHECK(text_edit->search("", 0, 0, 0) == Point2i(-1, -1));
CHECK(text_edit->search("needle", 0, -1, 0) == Point2i(-1, -1));