Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "Ignore Comments" option to Find & Replace #67796

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/classes/TextEdit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1301,6 +1301,9 @@
<constant name="SEARCH_BACKWARDS" value="4" enum="SearchFlags">
Search from end to beginning.
</constant>
<constant name="SEARCH_IGNORE_COMMENTS" value="8" enum="SearchFlags">
Ignore all comments.
</constant>
<constant name="CARET_TYPE_LINE" value="0" enum="CaretType">
Vertical line caret.
</constant>
Expand Down
25 changes: 25 additions & 0 deletions editor/code_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,12 @@ void FindReplaceBar::_update_results_count() {

int col_pos = 0;

if (is_ignoring_comments()) {
if (line_text.begins_with("#")) {
nonunknown marked this conversation as resolved.
Show resolved Hide resolved
continue;
}
}

while (true) {
col_pos = is_case_sensitive() ? line_text.find(searched, col_pos) : line_text.findn(searched, col_pos);

Expand Down Expand Up @@ -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);
Expand All @@ -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;

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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();
}
Expand Down Expand Up @@ -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"));
Expand Down
2 changes: 2 additions & 0 deletions editor/code_editor.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand Down
25 changes: 22 additions & 3 deletions editor/find_in_files.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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("#")) {
Copy link
Contributor

@alfredbaudisch alfredbaudisch Oct 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still a problem, after you updated the commit, it only matches if the line has no tabbing.
Searching "clicked" correctly ignores the comment here:

func clicked():
	print("Clicked!")
# clicked

But not here:

func clicked():
	print("Clicked!")
	# clicked

line is not being stripped out of tabs before the check.

return false;
}
}

while (true) {
int begin = match_case ? line.find(pattern, end) : line.findn(pattern, end);

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
}
}
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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();
}
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -933,7 +952,7 @@ void FindInFilesPanel::apply_replaces_in_file(String fpath, const Vector<Result>
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;
Expand Down
5 changes: 5 additions & 0 deletions editor/find_in_files.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,15 @@ 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<String> &exts);

String get_search_text() const { return _pattern; }

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();
Expand All @@ -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;
Expand Down Expand Up @@ -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<String> get_filter() const;
Expand All @@ -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;
Expand Down
1 change: 1 addition & 0 deletions editor/plugins/script_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());

Expand Down
18 changes: 14 additions & 4 deletions scene/gui/text_edit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<Vector2> 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++) {
Expand All @@ -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<Vector2> 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++) {
Expand All @@ -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);
}
}
}
Expand Down Expand Up @@ -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("#")) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same as my other comment regarding \t

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debug dump

text_line = {String} U"\t# clicked"
 _cowdata = {CowData<char32_t>} {_ptr=0x0000026460c04320 U"\t# clicked"}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm need to find a way to remove \t's

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also there's a case where the comment can be in front of the code, so I need to modify the text_line var to remove that comment!

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) {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion scene/gui/text_edit.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down