summaryrefslogtreecommitdiff
path: root/editor/find_in_files.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'editor/find_in_files.cpp')
-rw-r--r--editor/find_in_files.cpp147
1 files changed, 70 insertions, 77 deletions
diff --git a/editor/find_in_files.cpp b/editor/find_in_files.cpp
index d73180c831..47079a92b7 100644
--- a/editor/find_in_files.cpp
+++ b/editor/find_in_files.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -54,19 +54,19 @@ inline void pop_back(T &container) {
}
// TODO Copied from TextEdit private, would be nice to extract it in a single place
-static bool is_text_char(CharType c) {
+static bool is_text_char(char32_t c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_';
}
static bool find_next(const String &line, String pattern, int from, bool match_case, bool whole_words, int &out_begin, int &out_end) {
-
int end = from;
while (true) {
int begin = match_case ? line.find(pattern, end) : line.findn(pattern, end);
- if (begin == -1)
+ if (begin == -1) {
return false;
+ }
end = begin + pattern.length();
out_begin = begin;
@@ -86,11 +86,6 @@ static bool find_next(const String &line, String pattern, int from, bool match_c
}
//--------------------------------------------------------------------------------
-FindInFiles::FindInFiles() {
- _searching = false;
- _whole_words = true;
- _match_case = true;
-}
void FindInFiles::set_search_text(String p_pattern) {
_pattern = p_pattern;
@@ -157,15 +152,14 @@ void FindInFiles::_process() {
while (is_processing()) {
_iterate();
float elapsed = (os.get_ticks_msec() - time_before);
- if (elapsed > 1000.0 / 120.0)
+ if (elapsed > 1000.0 / 120.0) {
break;
+ }
}
}
void FindInFiles::_iterate() {
-
if (_folders_stack.size() != 0) {
-
// Scan folders first so we can build a list of files and have progress info later
PackedStringArray &folders_to_scan = _folders_stack.write[_folders_stack.size() - 1];
@@ -196,7 +190,6 @@ void FindInFiles::_iterate() {
}
} else if (_files_to_scan.size() != 0) {
-
// Then scan files
String fpath = _files_to_scan[_files_to_scan.size() - 1];
@@ -220,7 +213,6 @@ float FindInFiles::get_progress() const {
}
void FindInFiles::_scan_dir(String path, PackedStringArray &out_folders) {
-
DirAccessRef dir = DirAccess::open(path);
if (!dir) {
print_verbose("Cannot open directory! " + path);
@@ -232,19 +224,22 @@ void FindInFiles::_scan_dir(String path, PackedStringArray &out_folders) {
for (int i = 0; i < 1000; ++i) {
String file = dir->get_next();
- if (file == "")
+ if (file == "") {
break;
+ }
// Ignore special dirs (such as .git and .import)
- if (file == "." || file == ".." || file.begins_with("."))
+ if (file == "." || file == ".." || file.begins_with(".")) {
continue;
- if (dir->current_is_hidden())
+ }
+ if (dir->current_is_hidden()) {
continue;
+ }
- if (dir->current_is_dir())
+ if (dir->current_is_dir()) {
out_folders.push_back(file);
- else {
+ } else {
String file_ext = file.get_extension();
if (_extension_filter.has(file_ext)) {
_files_to_scan.push_back(path.plus_file(file));
@@ -254,7 +249,6 @@ void FindInFiles::_scan_dir(String path, PackedStringArray &out_folders) {
}
void FindInFiles::_scan_file(String fpath) {
-
FileAccessRef f = FileAccess::open(fpath, FileAccess::READ);
if (!f) {
print_verbose(String("Cannot open file ") + fpath);
@@ -264,7 +258,6 @@ void FindInFiles::_scan_file(String fpath) {
int line_number = 0;
while (!f->eof_reached()) {
-
// line number starts at 1
++line_number;
@@ -282,7 +275,6 @@ void FindInFiles::_scan_file(String fpath) {
}
void FindInFiles::_bind_methods() {
-
ADD_SIGNAL(MethodInfo(SIGNAL_RESULT_FOUND,
PropertyInfo(Variant::STRING, "path"),
PropertyInfo(Variant::INT, "line_number"),
@@ -298,15 +290,14 @@ const char *FindInFilesDialog::SIGNAL_FIND_REQUESTED = "find_requested";
const char *FindInFilesDialog::SIGNAL_REPLACE_REQUESTED = "replace_requested";
FindInFilesDialog::FindInFilesDialog() {
-
set_min_size(Size2(500 * EDSCALE, 0));
set_title(TTR("Find in Files"));
VBoxContainer *vbc = memnew(VBoxContainer);
- vbc->set_anchor_and_margin(MARGIN_LEFT, Control::ANCHOR_BEGIN, 8 * EDSCALE);
- vbc->set_anchor_and_margin(MARGIN_TOP, Control::ANCHOR_BEGIN, 8 * EDSCALE);
- vbc->set_anchor_and_margin(MARGIN_RIGHT, Control::ANCHOR_END, -8 * EDSCALE);
- vbc->set_anchor_and_margin(MARGIN_BOTTOM, Control::ANCHOR_END, -8 * EDSCALE);
+ vbc->set_anchor_and_offset(SIDE_LEFT, Control::ANCHOR_BEGIN, 8 * EDSCALE);
+ vbc->set_anchor_and_offset(SIDE_TOP, Control::ANCHOR_BEGIN, 8 * EDSCALE);
+ vbc->set_anchor_and_offset(SIDE_RIGHT, Control::ANCHOR_END, -8 * EDSCALE);
+ vbc->set_anchor_and_offset(SIDE_BOTTOM, Control::ANCHOR_END, -8 * EDSCALE);
add_child(vbc);
GridContainer *gc = memnew(GridContainer);
@@ -392,7 +383,7 @@ FindInFilesDialog::FindInFilesDialog() {
_replace_button = add_button(TTR("Replace..."), false, "replace");
_replace_button->set_disabled(true);
- Button *cancel_button = get_ok();
+ Button *cancel_button = get_ok_button();
cancel_button->set_text(TTR("Cancel"));
_mode = SEARCH_MODE;
@@ -408,9 +399,9 @@ void FindInFilesDialog::set_replace_text(String text) {
}
void FindInFilesDialog::set_find_in_files_mode(FindInFilesMode p_mode) {
-
- if (_mode == p_mode)
+ if (_mode == p_mode) {
return;
+ }
_mode = p_mode;
@@ -464,7 +455,6 @@ Set<String> FindInFilesDialog::get_filter() const {
void FindInFilesDialog::_notification(int p_what) {
if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
-
if (is_visible()) {
// Doesn't work more than once if not deferred...
_search_text_line_edit->call_deferred("grab_focus");
@@ -473,7 +463,7 @@ void FindInFilesDialog::_notification(int p_what) {
for (int i = 0; i < _filters_container->get_child_count(); i++) {
_filters_container->get_child(i)->queue_delete();
}
- Array exts = ProjectSettings::get_singleton()->get("editor/search_in_file_extensions");
+ Array exts = ProjectSettings::get_singleton()->get("editor/script/search_in_file_extensions");
for (int i = 0; i < exts.size(); ++i) {
CheckBox *cb = memnew(CheckBox);
cb->set_text(exts[i]);
@@ -488,7 +478,7 @@ void FindInFilesDialog::_notification(int p_what) {
}
void FindInFilesDialog::_on_folder_button_pressed() {
- _folder_dialog->popup_centered_ratio();
+ _folder_dialog->popup_file_dialog();
}
void FindInFilesDialog::custom_action(const String &p_action) {
@@ -506,12 +496,11 @@ void FindInFilesDialog::custom_action(const String &p_action) {
}
void FindInFilesDialog::_on_search_text_modified(String text) {
-
ERR_FAIL_COND(!_find_button);
ERR_FAIL_COND(!_replace_button);
- _find_button->set_disabled(get_search_text().empty());
- _replace_button->set_disabled(get_search_text().empty());
+ _find_button->set_disabled(get_search_text().is_empty());
+ _replace_button->set_disabled(get_search_text().is_empty());
}
void FindInFilesDialog::_on_search_text_entered(String text) {
@@ -540,13 +529,13 @@ void FindInFilesDialog::_on_replace_text_entered(String text) {
void FindInFilesDialog::_on_folder_selected(String path) {
int i = path.find("://");
- if (i != -1)
+ if (i != -1) {
path = path.right(i + 3);
+ }
_folder_line_edit->set_text(path);
}
void FindInFilesDialog::_bind_methods() {
-
ADD_SIGNAL(MethodInfo(SIGNAL_FIND_REQUESTED));
ADD_SIGNAL(MethodInfo(SIGNAL_REPLACE_REQUESTED));
}
@@ -556,17 +545,16 @@ const char *FindInFilesPanel::SIGNAL_RESULT_SELECTED = "result_selected";
const char *FindInFilesPanel::SIGNAL_FILES_MODIFIED = "files_modified";
FindInFilesPanel::FindInFilesPanel() {
-
_finder = memnew(FindInFiles);
_finder->connect(FindInFiles::SIGNAL_RESULT_FOUND, callable_mp(this, &FindInFilesPanel::_on_result_found));
_finder->connect(FindInFiles::SIGNAL_FINISHED, callable_mp(this, &FindInFilesPanel::_on_finished));
add_child(_finder);
VBoxContainer *vbc = memnew(VBoxContainer);
- vbc->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_BEGIN, 0);
- vbc->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 0);
- vbc->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, 0);
- vbc->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, 0);
+ vbc->set_anchor_and_offset(SIDE_LEFT, ANCHOR_BEGIN, 0);
+ vbc->set_anchor_and_offset(SIDE_TOP, ANCHOR_BEGIN, 0);
+ vbc->set_anchor_and_offset(SIDE_RIGHT, ANCHOR_END, 0);
+ vbc->set_anchor_and_offset(SIDE_BOTTOM, ANCHOR_END, 0);
add_child(vbc);
{
@@ -578,6 +566,7 @@ FindInFilesPanel::FindInFilesPanel() {
_search_text_label = memnew(Label);
_search_text_label->add_theme_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_theme_font("source", "EditorFonts"));
+ _search_text_label->add_theme_font_size_override("font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size("source_size", "EditorFonts"));
hbc->add_child(_search_text_label);
_progress_bar = memnew(ProgressBar);
@@ -606,6 +595,7 @@ FindInFilesPanel::FindInFilesPanel() {
_results_display = memnew(Tree);
_results_display->add_theme_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_theme_font("source", "EditorFonts"));
+ _results_display->add_theme_font_size_override("font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size("source_size", "EditorFonts"));
_results_display->set_v_size_flags(SIZE_EXPAND_FILL);
_results_display->connect("item_selected", callable_mp(this, &FindInFilesPanel::_on_result_selected));
_results_display->connect("item_edited", callable_mp(this, &FindInFilesPanel::_on_item_edited));
@@ -641,7 +631,6 @@ FindInFilesPanel::FindInFilesPanel() {
}
void FindInFilesPanel::set_with_replace(bool with_replace) {
-
_with_replace = with_replace;
_replace_container->set_visible(with_replace);
@@ -670,7 +659,6 @@ void FindInFilesPanel::clear() {
}
void FindInFilesPanel::start_search() {
-
clear();
_status_label->set_text(TTR("Searching..."));
@@ -687,7 +675,6 @@ void FindInFilesPanel::start_search() {
}
void FindInFilesPanel::stop_search() {
-
_finder->stop();
_status_label->set_text("");
@@ -700,11 +687,13 @@ void FindInFilesPanel::stop_search() {
void FindInFilesPanel::_notification(int p_what) {
if (p_what == NOTIFICATION_PROCESS) {
_progress_bar->set_as_ratio(_finder->get_progress());
+ } else if (p_what == NOTIFICATION_THEME_CHANGED) {
+ _search_text_label->add_theme_font_override("font", get_theme_font("source", "EditorFonts"));
+ _results_display->add_theme_font_override("font", get_theme_font("source", "EditorFonts"));
}
}
void FindInFilesPanel::_on_result_found(String fpath, int line_number, int begin, int end, String text) {
-
TreeItem *file_item;
Map<String, TreeItem *>::Element *E = _file_items.find(fpath);
@@ -730,22 +719,20 @@ void FindInFilesPanel::_on_result_found(String fpath, int line_number, int begin
// Do this first because it resets properties of the cell...
item->set_cell_mode(text_index, TreeItem::CELL_MODE_CUSTOM);
- String item_text = vformat("%3s: %s", line_number, text.replace("\t", " "));
+ // 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);
- item->set_text(text_index, item_text);
+ item->set_text(text_index, start + text);
item->set_custom_draw(text_index, this, "_draw_result_text");
- Ref<Font> font = _results_display->get_theme_font("font");
-
- float raw_text_width = font->get_string_size(text).x;
- float item_text_width = font->get_string_size(item_text).x;
-
Result r;
r.line_number = line_number;
r.begin = begin;
r.end = end;
- r.draw_begin = (item_text_width - raw_text_width) + font->get_string_size(text.left(r.begin)).x;
- r.draw_width = font->get_string_size(text.substr(r.begin, r.end - r.begin)).x;
+ r.begin_trimmed = begin - chars_removed + start.size() - 1;
_result_items[item] = r;
if (_with_replace) {
@@ -756,19 +743,23 @@ void FindInFilesPanel::_on_result_found(String fpath, int line_number, int begin
}
void FindInFilesPanel::draw_result_text(Object *item_obj, Rect2 rect) {
-
TreeItem *item = Object::cast_to<TreeItem>(item_obj);
- if (!item)
+ if (!item) {
return;
+ }
Map<TreeItem *, Result>::Element *E = _result_items.find(item);
- if (!E)
+ if (!E) {
return;
+ }
Result r = E->value();
+ String item_text = item->get_text(_with_replace ? 1 : 0);
+ Ref<Font> font = _results_display->get_theme_font("font");
+ int font_size = _results_display->get_theme_font_size("font_size");
Rect2 match_rect = rect;
- match_rect.position.x += r.draw_begin;
- match_rect.size.x = r.draw_width;
+ match_rect.position.x += font->get_string_size(item_text.left(r.begin_trimmed), font_size).x;
+ match_rect.size.x = font->get_string_size(_search_text_label->get_text(), font_size).x;
match_rect.position.y += 1 * EDSCALE;
match_rect.size.y -= 2 * EDSCALE;
@@ -777,7 +768,6 @@ void FindInFilesPanel::draw_result_text(Object *item_obj, Rect2 rect) {
}
void FindInFilesPanel::_on_item_edited() {
-
TreeItem *item = _results_display->get_selected();
if (item->is_checked(0)) {
@@ -792,8 +782,19 @@ void FindInFilesPanel::_on_item_edited() {
}
void FindInFilesPanel::_on_finished() {
+ String results_text;
+ int result_count = _result_items.size();
+ int file_count = _file_items.size();
+
+ if (result_count == 1 && file_count == 1) {
+ results_text = vformat(TTR("%d match in %d file."), result_count, file_count);
+ } else if (result_count != 1 && file_count == 1) {
+ results_text = vformat(TTR("%d matches in %d file."), result_count, file_count);
+ } else {
+ results_text = vformat(TTR("%d matches in %d files."), result_count, file_count);
+ }
- _status_label->set_text(TTR("Search complete"));
+ _status_label->set_text(results_text);
update_replace_buttons();
set_progress_visible(false);
_refresh_button->show();
@@ -809,12 +810,12 @@ void FindInFilesPanel::_on_cancel_button_clicked() {
}
void FindInFilesPanel::_on_result_selected() {
-
TreeItem *item = _results_display->get_selected();
Map<TreeItem *, Result>::Element *E = _result_items.find(item);
- if (E == nullptr)
+ if (E == nullptr) {
return;
+ }
Result r = E->value();
TreeItem *file_item = item->get_parent();
@@ -828,21 +829,19 @@ void FindInFilesPanel::_on_replace_text_changed(String text) {
}
void FindInFilesPanel::_on_replace_all_clicked() {
-
String replace_text = get_replace_text();
PackedStringArray modified_files;
for (Map<String, TreeItem *>::Element *E = _file_items.front(); E; E = E->next()) {
-
TreeItem *file_item = E->value();
String fpath = file_item->get_metadata(0);
Vector<Result> locations;
for (TreeItem *item = file_item->get_children(); item; item = item->get_next()) {
-
- if (!item->is_checked(0))
+ if (!item->is_checked(0)) {
continue;
+ }
Map<TreeItem *, Result>::Element *F = _result_items.find(item);
ERR_FAIL_COND(F == nullptr);
@@ -866,13 +865,11 @@ void FindInFilesPanel::_on_replace_all_clicked() {
class ConservativeGetLine {
public:
String get_line(FileAccess *f) {
-
_line_buffer.clear();
- CharType c = f->get_8();
+ char32_t c = f->get_8();
while (!f->eof_reached()) {
-
if (c == '\n') {
_line_buffer.push_back(c);
_line_buffer.push_back(0);
@@ -898,7 +895,6 @@ private:
};
void FindInFilesPanel::apply_replaces_in_file(String fpath, const Vector<Result> &locations, String new_text) {
-
// If the file is already open, I assume the editor will reload it.
// If there are unsaved changes, the user will be asked on focus,
// however that means either losing changes or losing replaces.
@@ -917,7 +913,6 @@ void FindInFilesPanel::apply_replaces_in_file(String fpath, const Vector<Result>
int offset = 0;
for (int i = 0; i < locations.size(); ++i) {
-
int repl_line_number = locations[i].line_number;
while (current_line < repl_line_number) {
@@ -963,7 +958,6 @@ String FindInFilesPanel::get_replace_text() {
}
void FindInFilesPanel::update_replace_buttons() {
-
bool disabled = _finder->is_searching();
_replace_all_button->set_disabled(disabled);
@@ -974,7 +968,6 @@ void FindInFilesPanel::set_progress_visible(bool visible) {
}
void FindInFilesPanel::_bind_methods() {
-
ClassDB::bind_method("_on_result_found", &FindInFilesPanel::_on_result_found);
ClassDB::bind_method("_on_finished", &FindInFilesPanel::_on_finished);
ClassDB::bind_method("_draw_result_text", &FindInFilesPanel::draw_result_text);