Skip to content

Commit

Permalink
Add "Replace in Files" functionality to text editors
Browse files Browse the repository at this point in the history
The Soft Reload Script shortcut was changed from Ctrl + Shift + R
to Ctrl + Alt + R to avoid conflicts.
  • Loading branch information
dreamsComeTrue authored and Calinou committed Nov 23, 2021
1 parent c3606a8 commit 7bd0eae
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 5 deletions.
72 changes: 68 additions & 4 deletions editor/find_in_files.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,17 @@ FindInFilesDialog::FindInFilesDialog() {
_search_text_line_edit->connect("text_entered", this, "_on_search_text_entered");
gc->add_child(_search_text_line_edit);

_replace_label = memnew(Label);
_replace_label->set_text(TTR("Replace:"));
_replace_label->hide();
gc->add_child(_replace_label);

_replace_text_line_edit = memnew(LineEdit);
_replace_text_line_edit->set_h_size_flags(SIZE_EXPAND_FILL);
_replace_text_line_edit->connect("text_entered", this, "_on_replace_text_entered");
_replace_text_line_edit->hide();
gc->add_child(_replace_text_line_edit);

gc->add_child(memnew(Control)); // Space to maintain the grid aligned.

{
Expand Down Expand Up @@ -385,18 +396,49 @@ FindInFilesDialog::FindInFilesDialog() {

Button *cancel_button = get_ok();
cancel_button->set_text(TTR("Cancel"));

_mode = SEARCH_MODE;
}

void FindInFilesDialog::set_search_text(String text) {
_search_text_line_edit->set_text(text);
_on_search_text_modified(text);
}

void FindInFilesDialog::set_replace_text(String text) {
_replace_text_line_edit->set_text(text);
}

void FindInFilesDialog::set_find_in_files_mode(FindInFilesMode p_mode) {
if (_mode == p_mode) {
return;
}

_mode = p_mode;

if (p_mode == SEARCH_MODE) {
set_title(TTR("Find in Files"));
_replace_label->hide();
_replace_text_line_edit->hide();
} else if (p_mode == REPLACE_MODE) {
set_title(TTR("Replace in Files"));
_replace_label->show();
_replace_text_line_edit->show();
}

// After hiding some child controls, recalculate proper dialog size.
set_size(Size2(get_size().x, 0));
}

String FindInFilesDialog::get_search_text() const {
String text = _search_text_line_edit->get_text();
return text.strip_edges();
}

String FindInFilesDialog::get_replace_text() const {
return _replace_text_line_edit->get_text();
}

bool FindInFilesDialog::is_match_case() const {
return _match_case_checkbox->is_pressed();
}
Expand Down Expand Up @@ -473,9 +515,26 @@ void FindInFilesDialog::_on_search_text_modified(String text) {
}

void FindInFilesDialog::_on_search_text_entered(String text) {
// This allows to trigger a global search without leaving the keyboard
// This allows to trigger a global search without leaving the keyboard.
if (!_find_button->is_disabled()) {
custom_action("find");
if (_mode == SEARCH_MODE) {
custom_action("find");
}
}

if (!_replace_button->is_disabled()) {
if (_mode == REPLACE_MODE) {
custom_action("replace");
}
}
}

void FindInFilesDialog::_on_replace_text_entered(String text) {
// This allows to trigger a global search without leaving the keyboard.
if (!_replace_button->is_disabled()) {
if (_mode == REPLACE_MODE) {
custom_action("replace");
}
}
}

Expand All @@ -492,6 +551,7 @@ void FindInFilesDialog::_bind_methods() {
ClassDB::bind_method("_on_folder_selected", &FindInFilesDialog::_on_folder_selected);
ClassDB::bind_method("_on_search_text_modified", &FindInFilesDialog::_on_search_text_modified);
ClassDB::bind_method("_on_search_text_entered", &FindInFilesDialog::_on_search_text_entered);
ClassDB::bind_method("_on_replace_text_entered", &FindInFilesDialog::_on_replace_text_entered);

ADD_SIGNAL(MethodInfo(SIGNAL_FIND_REQUESTED));
ADD_SIGNAL(MethodInfo(SIGNAL_REPLACE_REQUESTED));
Expand Down Expand Up @@ -575,7 +635,7 @@ FindInFilesPanel::FindInFilesPanel() {
_replace_container->add_child(_replace_line_edit);

_replace_all_button = memnew(Button);
_replace_all_button->set_text(TTR("Replace all (no undo)"));
_replace_all_button->set_text(TTR("Replace All (NO UNDO)"));
_replace_all_button->connect("pressed", this, "_on_replace_all_clicked");
_replace_container->add_child(_replace_all_button);

Expand All @@ -602,6 +662,10 @@ void FindInFilesPanel::set_with_replace(bool with_replace) {
}
}

void FindInFilesPanel::set_replace_text(String text) {
_replace_line_edit->set_text(text);
}

void FindInFilesPanel::clear() {
_file_items.clear();
_result_items.clear();
Expand Down Expand Up @@ -906,7 +970,7 @@ void FindInFilesPanel::apply_replaces_in_file(String fpath, const Vector<Result>
}

String FindInFilesPanel::get_replace_text() {
return _replace_line_edit->get_text().strip_edges();
return _replace_line_edit->get_text();
}

void FindInFilesPanel::update_replace_buttons() {
Expand Down
16 changes: 16 additions & 0 deletions editor/find_in_files.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,23 @@ class FindInFilesDialog : public AcceptDialog {
GDCLASS(FindInFilesDialog, AcceptDialog);

public:
enum FindInFilesMode {
SEARCH_MODE,
REPLACE_MODE
};

static const char *SIGNAL_FIND_REQUESTED;
static const char *SIGNAL_REPLACE_REQUESTED;

FindInFilesDialog();

void set_search_text(String text);
void set_replace_text(String text);

void set_find_in_files_mode(FindInFilesMode p_mode);

String get_search_text() const;
String get_replace_text() const;
bool is_match_case() const;
bool is_whole_words() const;
String get_folder() const;
Expand All @@ -121,8 +130,14 @@ class FindInFilesDialog : public AcceptDialog {
void _on_folder_selected(String path);
void _on_search_text_modified(String text);
void _on_search_text_entered(String text);
void _on_replace_text_entered(String text);

FindInFilesMode _mode;
LineEdit *_search_text_line_edit;

Label *_replace_label;
LineEdit *_replace_text_line_edit;

LineEdit *_folder_line_edit;
CheckBox *_match_case_checkbox;
CheckBox *_whole_words_checkbox;
Expand Down Expand Up @@ -151,6 +166,7 @@ class FindInFilesPanel : public Control {
FindInFiles *get_finder() const { return _finder; }

void set_with_replace(bool with_replace);
void set_replace_text(String text);

void start_search();
void stop_search();
Expand Down
19 changes: 18 additions & 1 deletion editor/plugins/script_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ void ScriptEditorBase::_bind_methods() {
ADD_SIGNAL(MethodInfo("go_to_help", PropertyInfo(Variant::STRING, "what")));
// TODO: This signal is no use for VisualScript.
ADD_SIGNAL(MethodInfo("search_in_files_requested", PropertyInfo(Variant::STRING, "text")));
ADD_SIGNAL(MethodInfo("replace_in_files_requested", PropertyInfo(Variant::STRING, "text")));
}

static bool _is_built_in_script(Script *p_script) {
Expand Down Expand Up @@ -1037,6 +1038,9 @@ void ScriptEditor::_menu_option(int p_option) {
case SEARCH_IN_FILES: {
_on_find_in_files_requested("");
} break;
case REPLACE_IN_FILES: {
_on_replace_in_files_requested("");
} break;
case SEARCH_HELP: {
help_search_dialog->popup_dialog();
} break;
Expand Down Expand Up @@ -2132,6 +2136,7 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra
se->connect("go_to_help", this, "_help_class_goto");
se->connect("request_save_history", this, "_save_history");
se->connect("search_in_files_requested", this, "_on_find_in_files_requested");
se->connect("replace_in_files_requested", this, "_on_replace_in_files_requested");

//test for modification, maybe the script was not edited but was loaded

Expand Down Expand Up @@ -2842,10 +2847,12 @@ void ScriptEditor::_update_selected_editor_menu() {
script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find_previous", TTR("Find Previous"), KEY_MASK_SHIFT | KEY_F3), HELP_SEARCH_FIND_PREVIOUS);
script_search_menu->get_popup()->add_separator();
script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find_in_files", TTR("Find in Files"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F), SEARCH_IN_FILES);
script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/replace_in_files", TTR("Replace in Files"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_R), REPLACE_IN_FILES);
script_search_menu->show();
} else {
if (tab_container->get_child_count() == 0) {
script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find_in_files", TTR("Find in Files"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F), SEARCH_IN_FILES);
script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/replace_in_files", TTR("Replace in Files"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_R), REPLACE_IN_FILES);
script_search_menu->show();
} else {
script_search_menu->hide();
Expand Down Expand Up @@ -2986,7 +2993,15 @@ void ScriptEditor::_script_changed() {
}

void ScriptEditor::_on_find_in_files_requested(String text) {
find_in_files_dialog->set_find_in_files_mode(FindInFilesDialog::SEARCH_MODE);
find_in_files_dialog->set_search_text(text);
find_in_files_dialog->popup_centered_minsize();
}

void ScriptEditor::_on_replace_in_files_requested(String text) {
find_in_files_dialog->set_find_in_files_mode(FindInFilesDialog::REPLACE_MODE);
find_in_files_dialog->set_search_text(text);
find_in_files_dialog->set_replace_text("");
find_in_files_dialog->popup_centered_minsize();
}

Expand Down Expand Up @@ -3040,6 +3055,7 @@ void ScriptEditor::_start_find_in_files(bool with_replace) {
f->set_filter(find_in_files_dialog->get_filter());

find_in_files->set_with_replace(with_replace);
find_in_files->set_replace_text(find_in_files_dialog->get_replace_text());
find_in_files->start_search();

editor->make_bottom_panel_item_visible(find_in_files);
Expand Down Expand Up @@ -3115,6 +3131,7 @@ void ScriptEditor::_bind_methods() {
ClassDB::bind_method("_filter_methods_text_changed", &ScriptEditor::_filter_methods_text_changed);
ClassDB::bind_method("_update_recent_scripts", &ScriptEditor::_update_recent_scripts);
ClassDB::bind_method("_on_find_in_files_requested", &ScriptEditor::_on_find_in_files_requested);
ClassDB::bind_method("_on_replace_in_files_requested", &ScriptEditor::_on_replace_in_files_requested);
ClassDB::bind_method("_start_find_in_files", &ScriptEditor::_start_find_in_files);
ClassDB::bind_method("_on_find_in_files_result_selected", &ScriptEditor::_on_find_in_files_result_selected);
ClassDB::bind_method("_on_find_in_files_modified_files", &ScriptEditor::_on_find_in_files_modified_files);
Expand Down Expand Up @@ -3263,7 +3280,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/save_as", TTR("Save As...")), FILE_SAVE_AS);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/save_all", TTR("Save All"), KEY_MASK_SHIFT | KEY_MASK_ALT | KEY_S), FILE_SAVE_ALL);
file_menu->get_popup()->add_separator();
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/reload_script_soft", TTR("Soft Reload Script"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_R), FILE_TOOL_RELOAD_SOFT);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/reload_script_soft", TTR("Soft Reload Script"), KEY_MASK_CMD | KEY_MASK_ALT | KEY_R), FILE_TOOL_RELOAD_SOFT);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/copy_path", TTR("Copy Script Path")), FILE_COPY_PATH);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/show_in_file_system", TTR("Show in FileSystem")), SHOW_IN_FILE_SYSTEM);
file_menu->get_popup()->add_separator();
Expand Down
2 changes: 2 additions & 0 deletions editor/plugins/script_editor_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ class ScriptEditor : public PanelContainer {
DEBUG_KEEP_DEBUGGER_OPEN,
DEBUG_WITH_EXTERNAL_EDITOR,
SEARCH_IN_FILES,
REPLACE_IN_FILES,
SEARCH_HELP,
SEARCH_WEBSITE,
HELP_SEARCH_FIND,
Expand Down Expand Up @@ -399,6 +400,7 @@ class ScriptEditor : public PanelContainer {
Error _save_text_file(Ref<TextFile> p_text_file, const String &p_path);

void _on_find_in_files_requested(String text);
void _on_replace_in_files_requested(String text);
void _on_find_in_files_result_selected(String fpath, int line_number, int begin, int end);
void _start_find_in_files(bool with_replace);
void _on_find_in_files_modified_files(PoolStringArray paths);
Expand Down
7 changes: 7 additions & 0 deletions editor/plugins/script_text_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1235,6 +1235,11 @@ void ScriptTextEditor::_edit_option(int p_op) {
// So this will be delegated to the ScriptEditor.
emit_signal("search_in_files_requested", selected_text);
} break;
case REPLACE_IN_FILES: {
String selected_text = code_editor->get_text_edit()->get_selection_text();

emit_signal("replace_in_files_requested", selected_text);
} break;
case SEARCH_LOCATE_FUNCTION: {
quick_open->popup_dialog(get_functions());
quick_open->set_title(TTR("Go to Function"));
Expand Down Expand Up @@ -1805,6 +1810,7 @@ void ScriptTextEditor::_enable_code_editor() {
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/replace"), SEARCH_REPLACE);
search_menu->get_popup()->add_separator();
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_in_files"), SEARCH_IN_FILES);
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/replace_in_files"), REPLACE_IN_FILES);
search_menu->get_popup()->add_separator();
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/contextual_help"), HELP_CONTEXTUAL);
search_menu->get_popup()->connect("id_pressed", this, "_edit_option");
Expand Down Expand Up @@ -2020,6 +2026,7 @@ void ScriptTextEditor::register_editor() {
#endif

ED_SHORTCUT("script_text_editor/find_in_files", TTR("Find in Files..."), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F);
ED_SHORTCUT("script_text_editor/replace_in_files", TTR("Replace in Files..."), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_R);

#ifdef OSX_ENABLED
ED_SHORTCUT("script_text_editor/contextual_help", TTR("Contextual Help"), KEY_MASK_ALT | KEY_MASK_SHIFT | KEY_SPACE);
Expand Down
1 change: 1 addition & 0 deletions editor/plugins/script_text_editor.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ class ScriptTextEditor : public ScriptEditorBase {
SEARCH_LOCATE_FUNCTION,
SEARCH_GOTO_LINE,
SEARCH_IN_FILES,
REPLACE_IN_FILES,
BOOKMARK_TOGGLE,
BOOKMARK_GOTO_NEXT,
BOOKMARK_GOTO_PREV,
Expand Down
6 changes: 6 additions & 0 deletions editor/plugins/text_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,11 @@ void TextEditor::_edit_option(int p_op) {
// So this will be delegated to the ScriptEditor.
emit_signal("search_in_files_requested", selected_text);
} break;
case REPLACE_IN_FILES: {
String selected_text = code_editor->get_text_edit()->get_selection_text();

emit_signal("replace_in_files_requested", selected_text);
} break;
case SEARCH_GOTO_LINE: {
goto_line_dialog->popup_find_line(tx);
} break;
Expand Down Expand Up @@ -616,6 +621,7 @@ TextEditor::TextEditor() {
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/replace"), SEARCH_REPLACE);
search_menu->get_popup()->add_separator();
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find_in_files"), SEARCH_IN_FILES);
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/replace_in_files"), REPLACE_IN_FILES);

edit_menu = memnew(MenuButton);
edit_hb->add_child(edit_menu);
Expand Down
1 change: 1 addition & 0 deletions editor/plugins/text_editor.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ class TextEditor : public ScriptEditorBase {
SEARCH_FIND_PREV,
SEARCH_REPLACE,
SEARCH_IN_FILES,
REPLACE_IN_FILES,
SEARCH_GOTO_LINE,
BOOKMARK_TOGGLE,
BOOKMARK_GOTO_NEXT,
Expand Down

0 comments on commit 7bd0eae

Please sign in to comment.