From 4d8a51eb29aaafc0a0623c0653fc4f459a1941b3 Mon Sep 17 00:00:00 2001 From: Nonunknown Date: Sun, 23 Oct 2022 10:04:23 -0300 Subject: [PATCH] Allow ignore comments on search --- doc/classes/TextEdit.xml | 3 +++ editor/code_editor.cpp | 25 +++++++++++++++++++++++++ editor/code_editor.h | 2 ++ editor/find_in_files.cpp | 25 ++++++++++++++++++++++--- editor/find_in_files.h | 5 +++++ editor/plugins/script_editor_plugin.cpp | 1 + scene/gui/text_edit.cpp | 18 ++++++++++++++---- scene/gui/text_edit.h | 3 ++- 8 files changed, 74 insertions(+), 8 deletions(-) diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml index b1fda25ecd56..32dcf2568d21 100644 --- a/doc/classes/TextEdit.xml +++ b/doc/classes/TextEdit.xml @@ -1301,6 +1301,9 @@ Search from end to beginning. + + Ignore all comments. + Vertical line caret. diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index e328f76545bd..b164300630b5 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -368,6 +368,12 @@ void FindReplaceBar::_update_results_count() { int col_pos = 0; + if (is_ignoring_comments()) { + if (line_text.begins_with("#")) { + continue; + } + } + while (true) { col_pos = is_case_sensitive() ? line_text.find(searched, col_pos) : line_text.findn(searched, col_pos); @@ -427,6 +433,9 @@ bool FindReplaceBar::search_current() { if (is_case_sensitive()) { flags |= TextEdit::SEARCH_MATCH_CASE; } + if (is_ignoring_comments()) { + flags |= TextEdit::SEARCH_IGNORE_COMMENTS; + } int line, col; _get_search_from(line, col); @@ -452,6 +461,9 @@ bool FindReplaceBar::search_prev() { if (is_case_sensitive()) { flags |= TextEdit::SEARCH_MATCH_CASE; } + if (is_ignoring_comments()) { + flags |= TextEdit::SEARCH_IGNORE_COMMENTS; + } flags |= TextEdit::SEARCH_BACKWARDS; @@ -487,6 +499,9 @@ bool FindReplaceBar::search_next() { if (is_case_sensitive()) { flags |= TextEdit::SEARCH_MATCH_CASE; } + if (is_ignoring_comments()) { + flags |= TextEdit::SEARCH_IGNORE_COMMENTS; + } int line, col; _get_search_from(line, col, true); @@ -620,6 +635,10 @@ bool FindReplaceBar::is_case_sensitive() const { return case_sensitive->is_pressed(); } +bool FindReplaceBar::is_ignoring_comments() const { + return ignore_comments->is_pressed(); +} + bool FindReplaceBar::is_whole_words() const { return whole_words->is_pressed(); } @@ -717,6 +736,12 @@ FindReplaceBar::FindReplaceBar() { case_sensitive->set_focus_mode(FOCUS_NONE); case_sensitive->connect("toggled", callable_mp(this, &FindReplaceBar::_search_options_changed)); + ignore_comments = memnew(CheckBox); + hbc_option_search->add_child(ignore_comments); + ignore_comments->set_text(TTR("Ignore Comments")); + ignore_comments->set_focus_mode(FOCUS_NONE); + ignore_comments->connect("toggled", callable_mp(this, &FindReplaceBar::_search_options_changed)); + whole_words = memnew(CheckBox); hbc_option_search->add_child(whole_words); whole_words->set_text(TTR("Whole Words")); diff --git a/editor/code_editor.h b/editor/code_editor.h index ded751828751..9650abe13e6f 100644 --- a/editor/code_editor.h +++ b/editor/code_editor.h @@ -67,6 +67,7 @@ class FindReplaceBar : public HBoxContainer { Button *find_prev = nullptr; Button *find_next = nullptr; CheckBox *case_sensitive = nullptr; + CheckBox *ignore_comments = nullptr; CheckBox *whole_words = nullptr; TextureButton *hide_button = nullptr; @@ -121,6 +122,7 @@ class FindReplaceBar : public HBoxContainer { String get_replace_text() const; bool is_case_sensitive() const; + bool is_ignoring_comments() const; bool is_whole_words() const; bool is_selection_only() const; void set_error(const String &p_label); diff --git a/editor/find_in_files.cpp b/editor/find_in_files.cpp index a0f4ade182e5..e24e7b4fa364 100644 --- a/editor/find_in_files.cpp +++ b/editor/find_in_files.cpp @@ -54,9 +54,15 @@ inline void pop_back(T &container) { container.resize(container.size() - 1); } -static bool find_next(const String &line, String pattern, int from, bool match_case, bool whole_words, int &out_begin, int &out_end) { +static bool find_next(const String &line, String pattern, int from, bool match_case, bool ignore_comments, bool whole_words, int &out_begin, int &out_end) { int end = from; + if (ignore_comments) { + if (line.begins_with("#")) { + return false; + } + } + while (true) { int begin = match_case ? line.find(pattern, end) : line.findn(pattern, end); @@ -95,6 +101,10 @@ void FindInFiles::set_match_case(bool p_match_case) { _match_case = p_match_case; } +void FindInFiles::set_ignore_comments(bool p_ignore_comments) { + _ignore_comments = p_ignore_comments; +} + void FindInFiles::set_folder(String folder) { _root_dir = folder; } @@ -270,7 +280,7 @@ void FindInFiles::_scan_file(String fpath) { String line = f->get_line(); - while (find_next(line, _pattern, end, _match_case, _whole_words, begin, end)) { + while (find_next(line, _pattern, end, _match_case, _ignore_comments, _whole_words, begin, end)) { emit_signal(SNAME(SIGNAL_RESULT_FOUND), fpath, line_number, begin, end, line); } } @@ -340,6 +350,10 @@ FindInFilesDialog::FindInFilesDialog() { _match_case_checkbox->set_text(TTR("Match Case")); hbc->add_child(_match_case_checkbox); + _ignore_comments_checkbox = memnew(CheckBox); + _ignore_comments_checkbox->set_text(TTR("Ignore Comments")); + hbc->add_child(_ignore_comments_checkbox); + gc->add_child(hbc); } @@ -430,6 +444,10 @@ String FindInFilesDialog::get_replace_text() const { return _replace_text_line_edit->get_text(); } +bool FindInFilesDialog::is_ignoring_comments() const { + return _ignore_comments_checkbox->is_pressed(); +} + bool FindInFilesDialog::is_match_case() const { return _match_case_checkbox->is_pressed(); } @@ -728,6 +746,7 @@ void FindInFilesPanel::_on_result_found(String fpath, int line_number, int begin // Trim result item line. int old_text_size = text.size(); text = text.strip_edges(true, false); + int chars_removed = old_text_size - text.size(); String start = vformat("%3s: ", line_number); @@ -933,7 +952,7 @@ void FindInFilesPanel::apply_replaces_in_file(String fpath, const Vector int repl_end = locations[i].end + offset; int _; - if (!find_next(line, search_text, repl_begin, _finder->is_match_case(), _finder->is_whole_words(), _, _)) { + if (!find_next(line, search_text, repl_begin, _finder->is_match_case(), _finder->is_ignoring_comments(), _finder->is_whole_words(), _, _)) { // Make sure the replace is still valid in case the file was tampered with. print_verbose(String("Occurrence no longer matches, replace will be ignored in {0}: line {1}, col {2}").format(varray(fpath, repl_line_number, repl_begin))); continue; diff --git a/editor/find_in_files.h b/editor/find_in_files.h index 46ba3842afae..e3e4d4a1bbd6 100644 --- a/editor/find_in_files.h +++ b/editor/find_in_files.h @@ -45,6 +45,7 @@ class FindInFiles : public Node { void set_search_text(String p_pattern); void set_whole_words(bool p_whole_word); void set_match_case(bool p_match_case); + void set_ignore_comments(bool p_ignore_comments); void set_folder(String folder); void set_filter(const HashSet &exts); @@ -52,6 +53,7 @@ class FindInFiles : public Node { bool is_whole_words() const { return _whole_words; } bool is_match_case() const { return _match_case; } + bool is_ignoring_comments() const { return _ignore_comments; } void start(); void stop(); @@ -76,6 +78,7 @@ class FindInFiles : public Node { String _root_dir; bool _whole_words = true; bool _match_case = true; + bool _ignore_comments = true; // State bool _searching = false; @@ -113,6 +116,7 @@ class FindInFilesDialog : public AcceptDialog { String get_search_text() const; String get_replace_text() const; bool is_match_case() const; + bool is_ignoring_comments() const; bool is_whole_words() const; String get_folder() const; HashSet get_filter() const; @@ -139,6 +143,7 @@ class FindInFilesDialog : public AcceptDialog { LineEdit *_folder_line_edit = nullptr; CheckBox *_match_case_checkbox = nullptr; + CheckBox *_ignore_comments_checkbox = nullptr; CheckBox *_whole_words_checkbox = nullptr; Button *_find_button = nullptr; Button *_replace_button = nullptr; diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 876ef3bae95e..efe4f89864e1 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -3566,6 +3566,7 @@ void ScriptEditor::_start_find_in_files(bool with_replace) { f->set_search_text(find_in_files_dialog->get_search_text()); f->set_match_case(find_in_files_dialog->is_match_case()); f->set_whole_words(find_in_files_dialog->is_whole_words()); + f->set_ignore_comments(find_in_files_dialog->is_ignoring_comments()); f->set_folder(find_in_files_dialog->get_folder()); f->set_filter(find_in_files_dialog->get_filter()); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 90974e31dfdf..a5d3ce677c2d 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -1130,7 +1130,7 @@ void TextEdit::_notification(int p_what) { } if (!clipped && highlight_all_occurrences && !only_whitespaces_highlighted && !highlighted_text.is_empty()) { // Highlight - int highlighted_text_col = _get_column_pos_of_word(highlighted_text, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, 0); + int highlighted_text_col = _get_column_pos_of_word(highlighted_text, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS | SEARCH_IGNORE_COMMENTS, 0); while (highlighted_text_col != -1) { Vector sel = TS->shaped_text_get_selection(rid, highlighted_text_col + start, highlighted_text_col + highlighted_text.length() + start); for (int j = 0; j < sel.size(); j++) { @@ -1147,13 +1147,13 @@ void TextEdit::_notification(int p_what) { draw_rect(rect, word_highlighted_color); } - highlighted_text_col = _get_column_pos_of_word(highlighted_text, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, highlighted_text_col + 1); + highlighted_text_col = _get_column_pos_of_word(highlighted_text, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS | SEARCH_IGNORE_COMMENTS, highlighted_text_col + 1); } } if (!clipped && lookup_symbol_word.length() != 0) { // Highlight word if (is_ascii_char(lookup_symbol_word[0]) || lookup_symbol_word[0] == '_' || lookup_symbol_word[0] == '.') { - int highlighted_word_col = _get_column_pos_of_word(lookup_symbol_word, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, 0); + int highlighted_word_col = _get_column_pos_of_word(lookup_symbol_word, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS | SEARCH_IGNORE_COMMENTS, 0); while (highlighted_word_col != -1) { Vector sel = TS->shaped_text_get_selection(rid, highlighted_word_col + start, highlighted_word_col + lookup_symbol_word.length() + start); for (int j = 0; j < sel.size(); j++) { @@ -1172,7 +1172,7 @@ void TextEdit::_notification(int p_what) { draw_rect(rect, color); } - highlighted_word_col = _get_column_pos_of_word(lookup_symbol_word, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, highlighted_word_col + 1); + highlighted_word_col = _get_column_pos_of_word(lookup_symbol_word, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS | SEARCH_IGNORE_COMMENTS, highlighted_word_col + 1); } } } @@ -4000,6 +4000,11 @@ Point2i TextEdit::search(const String &p_key, uint32_t p_search_flags, int p_fro int last_pos = -1; while (true) { + if (p_search_flags & SEARCH_IGNORE_COMMENTS) { + if (text_line.begins_with("#")) { + break; + } + } if (p_search_flags & SEARCH_BACKWARDS) { while ((last_pos = (p_search_flags & SEARCH_MATCH_CASE) ? text_line.rfind(p_key, pos_from) : text_line.rfindn(p_key, pos_from)) != -1) { if (last_pos <= from_column) { @@ -5906,6 +5911,7 @@ void TextEdit::_bind_methods() { BIND_ENUM_CONSTANT(SEARCH_MATCH_CASE); BIND_ENUM_CONSTANT(SEARCH_WHOLE_WORDS); BIND_ENUM_CONSTANT(SEARCH_BACKWARDS); + BIND_ENUM_CONSTANT(SEARCH_IGNORE_COMMENTS); ClassDB::bind_method(D_METHOD("set_search_text", "search_text"), &TextEdit::set_search_text); ClassDB::bind_method(D_METHOD("set_search_flags", "flags"), &TextEdit::set_search_flags); @@ -6689,6 +6695,10 @@ int TextEdit::_get_column_pos_of_word(const String &p_key, const String &p_searc p_from_column = 0; } + if (p_search_flags & SEARCH_IGNORE_COMMENTS) { + return col; + } + 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); diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index e4af621b738b..313bed75d6b6 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -116,7 +116,8 @@ class TextEdit : public Control { enum SearchFlags { SEARCH_MATCH_CASE = 1, SEARCH_WHOLE_WORDS = 2, - SEARCH_BACKWARDS = 4 + SEARCH_BACKWARDS = 4, + SEARCH_IGNORE_COMMENTS = 8 }; private: