diff options
Diffstat (limited to 'editor/plugins/script_text_editor.cpp')
| -rw-r--r-- | editor/plugins/script_text_editor.cpp | 615 |
1 files changed, 315 insertions, 300 deletions
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 1b0e9ec781..2b1ca068ee 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -33,6 +33,7 @@ #include "core/math/expression.h" #include "core/os/keyboard.h" #include "editor/debugger/editor_debugger_node.h" +#include "editor/editor_command_palette.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" @@ -50,9 +51,7 @@ void ConnectionInfoDialog::popup_connections(String p_method, Vector<Node *> p_n List<Connection> all_connections; p_nodes[i]->get_signals_connected_to_this(&all_connections); - for (List<Connection>::Element *E = all_connections.front(); E; E = E->next()) { - Connection connection = E->get(); - + for (const Connection &connection : all_connections) { if (connection.callable.get_method() != p_method) { continue; } @@ -66,7 +65,7 @@ void ConnectionInfoDialog::popup_connections(String p_method, Vector<Node *> p_n node_item->set_text(1, connection.signal.get_name()); Control *p = Object::cast_to<Control>(get_parent()); - node_item->set_icon(1, p->get_theme_icon("Slot", "EditorIcons")); + node_item->set_icon(1, p->get_theme_icon(SNAME("Slot"), SNAME("EditorIcons"))); node_item->set_selectable(1, false); node_item->set_editable(1, false); @@ -109,17 +108,15 @@ ConnectionInfoDialog::ConnectionInfoDialog() { //////////////////////////////////////////////////////////////////////////////// Vector<String> ScriptTextEditor::get_functions() { - String errortxt; - int line = -1, col; CodeEdit *te = code_editor->get_text_editor(); String text = te->get_text(); List<String> fnc; - if (script->get_language()->validate(text, line, col, errortxt, script->get_path(), &fnc)) { + if (script->get_language()->validate(text, script->get_path(), &fnc)) { //if valid rewrite functions to latest functions.clear(); - for (List<String>::Element *E = fnc.front(); E; E = E->next()) { - functions.push_back(E->get()); + for (const String &E : fnc) { + functions.push_back(E); } } @@ -149,7 +146,7 @@ void ScriptTextEditor::set_edited_resource(const RES &p_res) { code_editor->get_text_editor()->clear_undo_history(); code_editor->get_text_editor()->tag_saved_version(); - emit_signal("name_changed"); + emit_signal(SNAME("name_changed")); code_editor->update_line_and_column(); } @@ -161,75 +158,32 @@ void ScriptTextEditor::enable_editor() { editor_enabled = true; _enable_code_editor(); - _set_theme_for_script(); _validate_script(); } void ScriptTextEditor::_load_theme_settings() { CodeEdit *text_edit = code_editor->get_text_editor(); - text_edit->clear_keywords(); - Color updated_safe_line_number_color = EDITOR_GET("text_editor/highlighting/safe_line_number_color"); - if (updated_safe_line_number_color != safe_line_number_color) { + Color updated_marked_line_color = EDITOR_GET("text_editor/theme/highlighting/mark_color"); + Color updated_safe_line_number_color = EDITOR_GET("text_editor/theme/highlighting/safe_line_number_color"); + + bool safe_line_number_color_updated = updated_safe_line_number_color != safe_line_number_color; + bool marked_line_color_updated = updated_marked_line_color != marked_line_color; + if (safe_line_number_color_updated || marked_line_color_updated) { safe_line_number_color = updated_safe_line_number_color; for (int i = 0; i < text_edit->get_line_count(); i++) { - if (text_edit->get_line_gutter_item_color(i, line_number_gutter) != default_line_number_color) { + if (marked_line_color_updated && text_edit->get_line_background_color(i) == marked_line_color) { + text_edit->set_line_background_color(i, updated_marked_line_color); + } + + if (safe_line_number_color_updated && text_edit->get_line_gutter_item_color(i, line_number_gutter) != default_line_number_color) { text_edit->set_line_gutter_item_color(i, line_number_gutter, safe_line_number_color); } } + marked_line_color = updated_marked_line_color; } - Color background_color = EDITOR_GET("text_editor/highlighting/background_color"); - Color completion_background_color = EDITOR_GET("text_editor/highlighting/completion_background_color"); - Color completion_selected_color = EDITOR_GET("text_editor/highlighting/completion_selected_color"); - Color completion_existing_color = EDITOR_GET("text_editor/highlighting/completion_existing_color"); - Color completion_scroll_color = EDITOR_GET("text_editor/highlighting/completion_scroll_color"); - Color completion_font_color = EDITOR_GET("text_editor/highlighting/completion_font_color"); - Color text_color = EDITOR_GET("text_editor/highlighting/text_color"); - Color line_number_color = EDITOR_GET("text_editor/highlighting/line_number_color"); - Color caret_color = EDITOR_GET("text_editor/highlighting/caret_color"); - Color caret_background_color = EDITOR_GET("text_editor/highlighting/caret_background_color"); - Color text_selected_color = EDITOR_GET("text_editor/highlighting/text_selected_color"); - Color selection_color = EDITOR_GET("text_editor/highlighting/selection_color"); - Color brace_mismatch_color = EDITOR_GET("text_editor/highlighting/brace_mismatch_color"); - Color current_line_color = EDITOR_GET("text_editor/highlighting/current_line_color"); - Color line_length_guideline_color = EDITOR_GET("text_editor/highlighting/line_length_guideline_color"); - Color word_highlighted_color = EDITOR_GET("text_editor/highlighting/word_highlighted_color"); - Color mark_color = EDITOR_GET("text_editor/highlighting/mark_color"); - Color bookmark_color = EDITOR_GET("text_editor/highlighting/bookmark_color"); - Color breakpoint_color = EDITOR_GET("text_editor/highlighting/breakpoint_color"); - Color executing_line_color = EDITOR_GET("text_editor/highlighting/executing_line_color"); - Color code_folding_color = EDITOR_GET("text_editor/highlighting/code_folding_color"); - Color search_result_color = EDITOR_GET("text_editor/highlighting/search_result_color"); - Color search_result_border_color = EDITOR_GET("text_editor/highlighting/search_result_border_color"); - - text_edit->add_theme_color_override("background_color", background_color); - text_edit->add_theme_color_override("completion_background_color", completion_background_color); - text_edit->add_theme_color_override("completion_selected_color", completion_selected_color); - text_edit->add_theme_color_override("completion_existing_color", completion_existing_color); - text_edit->add_theme_color_override("completion_scroll_color", completion_scroll_color); - text_edit->add_theme_color_override("completion_font_color", completion_font_color); - text_edit->add_theme_color_override("font_color", text_color); - text_edit->add_theme_color_override("line_number_color", line_number_color); - text_edit->add_theme_color_override("caret_color", caret_color); - text_edit->add_theme_color_override("caret_background_color", caret_background_color); - text_edit->add_theme_color_override("font_color_selected", text_selected_color); - text_edit->add_theme_color_override("selection_color", selection_color); - text_edit->add_theme_color_override("brace_mismatch_color", brace_mismatch_color); - text_edit->add_theme_color_override("current_line_color", current_line_color); - text_edit->add_theme_color_override("line_length_guideline_color", line_length_guideline_color); - text_edit->add_theme_color_override("word_highlighted_color", word_highlighted_color); - text_edit->add_theme_color_override("bookmark_color", bookmark_color); - text_edit->add_theme_color_override("breakpoint_color", breakpoint_color); - text_edit->add_theme_color_override("executing_line_color", executing_line_color); - text_edit->add_theme_color_override("mark_color", mark_color); - text_edit->add_theme_color_override("code_folding_color", code_folding_color); - text_edit->add_theme_color_override("search_result_color", search_result_color); - text_edit->add_theme_color_override("search_result_border_color", search_result_border_color); - - text_edit->add_theme_constant_override("line_spacing", EDITOR_DEF("text_editor/theme/line_spacing", 6)); - theme_loaded = true; if (!script.is_null()) { _set_theme_for_script(); @@ -244,46 +198,37 @@ void ScriptTextEditor::_set_theme_for_script() { CodeEdit *text_edit = code_editor->get_text_editor(); text_edit->get_syntax_highlighter()->update_cache(); - /* add keywords for auto completion */ - // singleton autoloads (as types, just as engine singletons are) - Map<StringName, ProjectSettings::AutoloadInfo> autoloads = ProjectSettings::get_singleton()->get_autoload_list(); - for (Map<StringName, ProjectSettings::AutoloadInfo>::Element *E = autoloads.front(); E; E = E->next()) { - const ProjectSettings::AutoloadInfo &info = E->value(); - if (info.is_singleton) { - text_edit->add_keyword(info.name); + List<String> strings; + script->get_language()->get_string_delimiters(&strings); + text_edit->clear_string_delimiters(); + for (const String &string : strings) { + String beg = string.get_slice(" ", 0); + String end = string.get_slice_count(" ") > 1 ? string.get_slice(" ", 1) : String(); + if (!text_edit->has_string_delimiter(beg)) { + text_edit->add_string_delimiter(beg, end, end == ""); } - } - // engine types - List<StringName> types; - ClassDB::get_class_list(&types); - for (List<StringName>::Element *E = types.front(); E; E = E->next()) { - String n = E->get(); - if (n.begins_with("_")) { - n = n.substr(1, n.length()); + if (!end.is_empty() && !text_edit->has_auto_brace_completion_open_key(beg)) { + text_edit->add_auto_brace_completion_pair(beg, end); } - text_edit->add_keyword(n); } - // user types - List<StringName> global_classes; - ScriptServer::get_global_class_list(&global_classes); - for (List<StringName>::Element *E = global_classes.front(); E; E = E->next()) { - text_edit->add_keyword(E->get()); - } + List<String> comments; + script->get_language()->get_comment_delimiters(&comments); + text_edit->clear_comment_delimiters(); + for (const String &comment : comments) { + String beg = comment.get_slice(" ", 0); + String end = comment.get_slice_count(" ") > 1 ? comment.get_slice(" ", 1) : String(); + text_edit->add_comment_delimiter(beg, end, end == ""); - List<String> keywords; - script->get_language()->get_reserved_words(&keywords); - for (List<String>::Element *E = keywords.front(); E; E = E->next()) { - text_edit->add_keyword(E->get()); + if (!end.is_empty() && !text_edit->has_auto_brace_completion_open_key(beg)) { + text_edit->add_auto_brace_completion_pair(beg, end); + } } +} - // core types - List<String> core_types; - script->get_language()->get_core_type_words(&core_types); - for (List<String>::Element *E = core_types.front(); E; E = E->next()) { - text_edit->add_keyword(E->get()); - } +void ScriptTextEditor::_show_errors_panel(bool p_show) { + errors_panel->set_visible(p_show); } void ScriptTextEditor::_show_warnings_panel(bool p_show) { @@ -292,26 +237,32 @@ void ScriptTextEditor::_show_warnings_panel(bool p_show) { void ScriptTextEditor::_warning_clicked(Variant p_line) { if (p_line.get_type() == Variant::INT) { - code_editor->get_text_editor()->cursor_set_line(p_line.operator int64_t()); + goto_line_centered(p_line.operator int64_t()); } else if (p_line.get_type() == Variant::DICTIONARY) { Dictionary meta = p_line.operator Dictionary(); - code_editor->get_text_editor()->insert_at("# warning-ignore:" + meta["code"].operator String(), meta["line"].operator int64_t() - 1); + code_editor->get_text_editor()->insert_line_at(meta["line"].operator int64_t() - 1, "# warning-ignore:" + meta["code"].operator String()); _validate_script(); } } +void ScriptTextEditor::_error_clicked(Variant p_line) { + if (p_line.get_type() == Variant::INT) { + code_editor->get_text_editor()->set_caret_line(p_line.operator int64_t()); + } +} + void ScriptTextEditor::reload_text() { ERR_FAIL_COND(script.is_null()); CodeEdit *te = code_editor->get_text_editor(); - int column = te->cursor_get_column(); - int row = te->cursor_get_line(); + int column = te->get_caret_column(); + int row = te->get_caret_line(); int h = te->get_h_scroll(); int v = te->get_v_scroll(); te->set_text(script->get_source_code()); - te->cursor_set_line(row); - te->cursor_set_column(column); + te->set_caret_line(row); + te->set_caret_column(column); te->set_h_scroll(h); te->set_v_scroll(v); @@ -329,12 +280,12 @@ void ScriptTextEditor::add_callback(const String &p_function, PackedStringArray pos = code_editor->get_text_editor()->get_line_count() + 2; String func = script->get_language()->make_function("", p_function, p_args); //code=code+func; - code_editor->get_text_editor()->cursor_set_line(pos + 1); - code_editor->get_text_editor()->cursor_set_column(1000000); //none shall be that big - code_editor->get_text_editor()->insert_text_at_cursor("\n\n" + func); + code_editor->get_text_editor()->set_caret_line(pos + 1); + code_editor->get_text_editor()->set_caret_column(1000000); //none shall be that big + code_editor->get_text_editor()->insert_text_at_caret("\n\n" + func); } - code_editor->get_text_editor()->cursor_set_line(pos); - code_editor->get_text_editor()->cursor_set_column(1); + code_editor->get_text_editor()->set_caret_line(pos); + code_editor->get_text_editor()->set_caret_column(1); } bool ScriptTextEditor::show_members_overview() { @@ -342,7 +293,7 @@ bool ScriptTextEditor::show_members_overview() { } void ScriptTextEditor::update_settings() { - code_editor->get_text_editor()->set_gutter_draw(connection_gutter, EditorSettings::get_singleton()->get("text_editor/appearance/show_info_gutter")); + code_editor->get_text_editor()->set_gutter_draw(connection_gutter, EditorSettings::get_singleton()->get("text_editor/appearance/gutters/show_info_gutter")); code_editor->update_editor_settings(); } @@ -450,23 +401,21 @@ Ref<Texture2D> ScriptTextEditor::get_theme_icon() { } void ScriptTextEditor::_validate_script() { - String errortxt; - int line = -1, col; CodeEdit *te = code_editor->get_text_editor(); String text = te->get_text(); List<String> fnc; Set<int> safe_lines; List<ScriptLanguage::Warning> warnings; + List<ScriptLanguage::ScriptError> errors; - if (!script->get_language()->validate(text, line, col, errortxt, script->get_path(), &fnc, &warnings, &safe_lines)) { - String error_text = "error(" + itos(line) + "," + itos(col) + "): " + errortxt; + if (!script->get_language()->validate(text, script->get_path(), &fnc, &errors, &warnings, &safe_lines)) { + String error_text = TTR("Error at ") + "(" + itos(errors[0].line) + "," + itos(errors[0].column) + "): " + errors[0].message; code_editor->set_error(error_text); - code_editor->set_error_pos(line - 1, col - 1); + code_editor->set_error_pos(errors[0].line - 1, errors[0].column - 1); script_is_valid = false; } else { code_editor->set_error(""); - line = -1; if (!script->is_tool()) { script->set_source_code(text); script->update_exports(); @@ -474,8 +423,8 @@ void ScriptTextEditor::_validate_script() { } functions.clear(); - for (List<String>::Element *E = fnc.front(); E; E = E->next()) { - functions.push_back(E->get()); + for (const String &E : fnc) { + functions.push_back(E); } script_is_valid = true; } @@ -489,15 +438,13 @@ void ScriptTextEditor::_validate_script() { Node *base = get_tree()->get_edited_scene_root(); if (base && missing_connections.size() > 0) { warnings_panel->push_table(1); - for (List<Connection>::Element *E = missing_connections.front(); E; E = E->next()) { - Connection connection = E->get(); - + for (const Connection &connection : missing_connections) { String base_path = base->get_name(); String source_path = base == connection.signal.get_object() ? base_path : base_path + "/" + base->get_path_to(Object::cast_to<Node>(connection.signal.get_object())); String target_path = base == connection.callable.get_object() ? base_path : base_path + "/" + base->get_path_to(Object::cast_to<Node>(connection.callable.get_object())); warnings_panel->push_cell(); - warnings_panel->push_color(warnings_panel->get_theme_color("warning_color", "Editor")); + warnings_panel->push_color(warnings_panel->get_theme_color(SNAME("warning_color"), SNAME("Editor"))); warnings_panel->add_text(vformat(TTR("Missing connected method '%s' for signal '%s' from node '%s' to node '%s'."), connection.callable.get_method(), connection.signal.get_name(), source_path, target_path)); warnings_panel->pop(); // Color. warnings_panel->pop(); // Cell. @@ -508,20 +455,19 @@ void ScriptTextEditor::_validate_script() { } } - code_editor->set_warning_nb(warning_nb); + code_editor->set_error_count(errors.size()); + code_editor->set_warning_count(warning_nb); // Add script warnings. warnings_panel->push_table(3); - for (List<ScriptLanguage::Warning>::Element *E = warnings.front(); E; E = E->next()) { - ScriptLanguage::Warning w = E->get(); - + for (const ScriptLanguage::Warning &w : warnings) { Dictionary ignore_meta; ignore_meta["line"] = w.start_line; ignore_meta["code"] = w.string_code.to_lower(); warnings_panel->push_cell(); warnings_panel->push_meta(ignore_meta); warnings_panel->push_color( - warnings_panel->get_theme_color("accent_color", "Editor").lerp(warnings_panel->get_theme_color("mono_color", "Editor"), 0.5)); + warnings_panel->get_theme_color(SNAME("accent_color"), SNAME("Editor")).lerp(warnings_panel->get_theme_color(SNAME("mono_color"), SNAME("Editor")), 0.5)); warnings_panel->add_text(TTR("[Ignore]")); warnings_panel->pop(); // Color. warnings_panel->pop(); // Meta ignore. @@ -529,7 +475,7 @@ void ScriptTextEditor::_validate_script() { warnings_panel->push_cell(); warnings_panel->push_meta(w.start_line - 1); - warnings_panel->push_color(warnings_panel->get_theme_color("warning_color", "Editor")); + warnings_panel->push_color(warnings_panel->get_theme_color(SNAME("warning_color"), SNAME("Editor"))); warnings_panel->add_text(TTR("Line") + " " + itos(w.start_line)); warnings_panel->add_text(" (" + w.string_code + "):"); warnings_panel->pop(); // Color. @@ -542,28 +488,55 @@ void ScriptTextEditor::_validate_script() { } warnings_panel->pop(); // Table. - line--; - bool highlight_safe = EDITOR_DEF("text_editor/highlighting/highlight_type_safe_lines", true); + errors_panel->clear(); + errors_panel->push_table(2); + for (const ScriptLanguage::ScriptError &err : errors) { + errors_panel->push_cell(); + errors_panel->push_meta(err.line - 1); + errors_panel->push_color(warnings_panel->get_theme_color(SNAME("error_color"), SNAME("Editor"))); + errors_panel->add_text(TTR("Line") + " " + itos(err.line) + ":"); + errors_panel->pop(); // Color. + errors_panel->pop(); // Meta goto. + errors_panel->pop(); // Cell. + + errors_panel->push_cell(); + errors_panel->add_text(err.message); + errors_panel->pop(); // Cell. + } + errors_panel->pop(); // Table + + bool highlight_safe = EDITOR_DEF("text_editor/appearance/gutters/highlight_type_safe_lines", true); bool last_is_safe = false; for (int i = 0; i < te->get_line_count(); i++) { - te->set_line_as_marked(i, line == i); + if (errors.is_empty()) { + te->set_line_background_color(i, Color(0, 0, 0, 0)); + } else { + for (const ScriptLanguage::ScriptError &E : errors) { + bool error_line = i == E.line - 1; + te->set_line_background_color(i, error_line ? marked_line_color : Color(0, 0, 0, 0)); + if (error_line) { + break; + } + } + } + if (highlight_safe) { if (safe_lines.has(i + 1)) { te->set_line_gutter_item_color(i, line_number_gutter, safe_line_number_color); last_is_safe = true; - } else if (last_is_safe && (te->is_line_comment(i) || te->get_line(i).strip_edges().is_empty())) { + } else if (last_is_safe && (te->is_in_comment(i) != -1 || te->get_line(i).strip_edges().is_empty())) { te->set_line_gutter_item_color(i, line_number_gutter, safe_line_number_color); } else { te->set_line_gutter_item_color(i, line_number_gutter, default_line_number_color); last_is_safe = false; } } else { - te->set_line_gutter_item_color(line, 1, default_line_number_color); + te->set_line_gutter_item_color(i, 1, default_line_number_color); } } - emit_signal("name_changed"); - emit_signal("edited_script_changed"); + emit_signal(SNAME("name_changed")); + emit_signal(SNAME("edited_script_changed")); } void ScriptTextEditor::_update_bookmark_list() { @@ -601,8 +574,7 @@ void ScriptTextEditor::_bookmark_item_pressed(int p_idx) { if (p_idx < 4) { // Any item before the separator. _edit_option(bookmarks_menu->get_item_id(p_idx)); } else { - code_editor->goto_line(bookmarks_menu->get_item_metadata(p_idx)); - code_editor->get_text_editor()->call_deferred("center_viewport_to_cursor"); //Need to be deferred, because goto uses call_deferred(). + code_editor->goto_line_centered(bookmarks_menu->get_item_metadata(p_idx)); } } @@ -688,11 +660,13 @@ void ScriptEditor::_update_modified_scripts_for_external_editor(Ref<Script> p_fo uint64_t date = FileAccess::get_modified_time(script->get_path()); if (last_date != date) { - Ref<Script> rel_script = ResourceLoader::load(script->get_path(), script->get_class(), true); + Ref<Script> rel_script = ResourceLoader::load(script->get_path(), script->get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE); ERR_CONTINUE(!rel_script.is_valid()); script->set_source_code(rel_script->get_source_code()); script->set_last_modified_time(rel_script->get_last_modified_time()); script->update_exports(); + + _trigger_live_script_reload(); } } } @@ -753,7 +727,7 @@ void ScriptTextEditor::_breakpoint_item_pressed(int p_idx) { _edit_option(breakpoints_menu->get_item_id(p_idx)); } else { code_editor->goto_line(breakpoints_menu->get_item_metadata(p_idx)); - code_editor->get_text_editor()->call_deferred("center_viewport_to_cursor"); //Need to be deferred, because goto uses call_deferred(). + code_editor->get_text_editor()->call_deferred(SNAME("center_viewport_to_caret")); //Need to be deferred, because goto uses call_deferred(). } } @@ -780,22 +754,20 @@ void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_c EditorNode::get_singleton()->load_resource(p_symbol); } - } else if (script->get_language()->lookup_code(code_editor->get_text_editor()->get_text_for_lookup_completion(), p_symbol, script->get_path(), base, result) == OK) { + } else if (script->get_language()->lookup_code(code_editor->get_text_editor()->get_text_for_symbol_lookup(), p_symbol, script->get_path(), base, result) == OK) { _goto_line(p_row); - result.class_name = result.class_name.trim_prefix("_"); - switch (result.type) { case ScriptLanguage::LookupResult::RESULT_SCRIPT_LOCATION: { if (result.script.is_valid()) { - emit_signal("request_open_script_at_line", result.script, result.location - 1); + emit_signal(SNAME("request_open_script_at_line"), result.script, result.location - 1); } else { - emit_signal("request_save_history"); - _goto_line(result.location - 1); + emit_signal(SNAME("request_save_history")); + goto_line_centered(result.location - 1); } } break; case ScriptLanguage::LookupResult::RESULT_CLASS: { - emit_signal("go_to_help", "class_name:" + result.class_name); + emit_signal(SNAME("go_to_help"), "class_name:" + result.class_name); } break; case ScriptLanguage::LookupResult::RESULT_CLASS_CONSTANT: { StringName cname = result.class_name; @@ -810,11 +782,11 @@ void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_c } } - emit_signal("go_to_help", "class_constant:" + result.class_name + ":" + result.class_member); + emit_signal(SNAME("go_to_help"), "class_constant:" + result.class_name + ":" + result.class_member); } break; case ScriptLanguage::LookupResult::RESULT_CLASS_PROPERTY: { - emit_signal("go_to_help", "class_property:" + result.class_name + ":" + result.class_member); + emit_signal(SNAME("go_to_help"), "class_property:" + result.class_name + ":" + result.class_member); } break; case ScriptLanguage::LookupResult::RESULT_CLASS_METHOD: { @@ -829,7 +801,7 @@ void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_c } } - emit_signal("go_to_help", "class_method:" + result.class_name + ":" + result.class_member); + emit_signal(SNAME("go_to_help"), "class_method:" + result.class_name + ":" + result.class_member); } break; case ScriptLanguage::LookupResult::RESULT_CLASS_ENUM: { @@ -845,11 +817,11 @@ void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_c } } - emit_signal("go_to_help", "class_enum:" + result.class_name + ":" + result.class_member); + emit_signal(SNAME("go_to_help"), "class_enum:" + result.class_name + ":" + result.class_member); } break; case ScriptLanguage::LookupResult::RESULT_CLASS_TBD_GLOBALSCOPE: { - emit_signal("go_to_help", "class_global:" + result.class_name + ":" + result.class_member); + emit_signal(SNAME("go_to_help"), "class_global:" + result.class_name + ":" + result.class_member); } break; } } else if (ProjectSettings::get_singleton()->has_autoload(p_symbol)) { @@ -858,7 +830,7 @@ void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_c if (info.is_singleton) { EditorNode::get_singleton()->load_scene(info.path); } - } else if (p_symbol.is_rel_path()) { + } else if (p_symbol.is_relative_path()) { // Every symbol other than absolute path is relative path so keep this condition at last. String path = _get_absolute_path(p_symbol); if (FileAccess::exists(path)) { @@ -883,18 +855,17 @@ void ScriptTextEditor::_validate_symbol(const String &p_symbol) { } ScriptLanguage::LookupResult result; - if (ScriptServer::is_global_class(p_symbol) || p_symbol.is_resource_file() || script->get_language()->lookup_code(code_editor->get_text_editor()->get_text_for_lookup_completion(), p_symbol, script->get_path(), base, result) == OK || (ProjectSettings::get_singleton()->has_autoload(p_symbol) && ProjectSettings::get_singleton()->get_autoload(p_symbol).is_singleton)) { - text_edit->set_highlighted_word(p_symbol); - } else if (p_symbol.is_rel_path()) { + if (ScriptServer::is_global_class(p_symbol) || p_symbol.is_resource_file() || script->get_language()->lookup_code(code_editor->get_text_editor()->get_text_for_symbol_lookup(), p_symbol, script->get_path(), base, result) == OK || (ProjectSettings::get_singleton()->has_autoload(p_symbol) && ProjectSettings::get_singleton()->get_autoload(p_symbol).is_singleton)) { + text_edit->set_symbol_lookup_word_as_valid(true); + } else if (p_symbol.is_relative_path()) { String path = _get_absolute_path(p_symbol); if (FileAccess::exists(path)) { - text_edit->set_highlighted_word(p_symbol); + text_edit->set_symbol_lookup_word_as_valid(true); } else { - text_edit->set_highlighted_word(String()); + text_edit->set_symbol_lookup_word_as_valid(false); } - } else { - text_edit->set_highlighted_word(String()); + text_edit->set_symbol_lookup_word_as_valid(false); } } @@ -905,14 +876,12 @@ String ScriptTextEditor::_get_absolute_path(const String &rel_path) { } void ScriptTextEditor::update_toggle_scripts_button() { - if (code_editor != nullptr) { - code_editor->update_toggle_scripts_button(); - } + code_editor->update_toggle_scripts_button(); } void ScriptTextEditor::_update_connected_methods() { CodeEdit *text_edit = code_editor->get_text_editor(); - text_edit->set_gutter_width(connection_gutter, text_edit->get_row_height()); + text_edit->set_gutter_width(connection_gutter, text_edit->get_line_height()); for (int i = 0; i < text_edit->get_line_count(); i++) { if (text_edit->get_line_gutter_metadata(i, connection_gutter) == "") { continue; @@ -938,8 +907,7 @@ void ScriptTextEditor::_update_connected_methods() { List<Connection> connections; nodes[i]->get_signals_connected_to_this(&connections); - for (List<Connection>::Element *E = connections.front(); E; E = E->next()) { - Connection connection = E->get(); + for (const Connection &connection : connections) { if (!(connection.flags & CONNECT_PERSIST)) { continue; } @@ -962,7 +930,7 @@ void ScriptTextEditor::_update_connected_methods() { if (name == connection.callable.get_method()) { line = functions[j].get_slice(":", 1).to_int() - 1; text_edit->set_line_gutter_metadata(line, connection_gutter, connection.callable.get_method()); - text_edit->set_line_gutter_icon(line, connection_gutter, get_parent_control()->get_theme_icon("Slot", "EditorIcons")); + text_edit->set_line_gutter_icon(line, connection_gutter, get_parent_control()->get_theme_icon(SNAME("Slot"), SNAME("EditorIcons"))); text_edit->set_line_gutter_clickable(line, connection_gutter, true); methods_found.insert(connection.callable.get_method()); break; @@ -1032,27 +1000,27 @@ void ScriptTextEditor::_edit_option(int p_op) { switch (p_op) { case EDIT_UNDO: { tx->undo(); - tx->call_deferred("grab_focus"); + tx->call_deferred(SNAME("grab_focus")); } break; case EDIT_REDO: { tx->redo(); - tx->call_deferred("grab_focus"); + tx->call_deferred(SNAME("grab_focus")); } break; case EDIT_CUT: { tx->cut(); - tx->call_deferred("grab_focus"); + tx->call_deferred(SNAME("grab_focus")); } break; case EDIT_COPY: { tx->copy(); - tx->call_deferred("grab_focus"); + tx->call_deferred(SNAME("grab_focus")); } break; case EDIT_PASTE: { tx->paste(); - tx->call_deferred("grab_focus"); + tx->call_deferred(SNAME("grab_focus")); } break; case EDIT_SELECT_ALL: { tx->select_all(); - tx->call_deferred("grab_focus"); + tx->call_deferred(SNAME("grab_focus")); } break; case EDIT_MOVE_LINE_UP: { code_editor->move_lines_up(); @@ -1066,7 +1034,7 @@ void ScriptTextEditor::_edit_option(int p_op) { return; } - tx->indent_left(); + tx->unindent_lines(); } break; case EDIT_INDENT_RIGHT: { Ref<Script> scr = script; @@ -1074,16 +1042,16 @@ void ScriptTextEditor::_edit_option(int p_op) { return; } - tx->indent_right(); + tx->indent_lines(); } break; case EDIT_DELETE_LINE: { code_editor->delete_lines(); } break; - case EDIT_CLONE_DOWN: { - code_editor->clone_lines_down(); + case EDIT_DUPLICATE_SELECTION: { + code_editor->duplicate_selection(); } break; case EDIT_TOGGLE_FOLD_LINE: { - tx->toggle_fold_line(tx->cursor_get_line()); + tx->toggle_foldable_line(tx->get_caret_line()); tx->update(); } break; case EDIT_FOLD_ALL_LINES: { @@ -1091,14 +1059,14 @@ void ScriptTextEditor::_edit_option(int p_op) { tx->update(); } break; case EDIT_UNFOLD_ALL_LINES: { - tx->unhide_all_lines(); + tx->unfold_all_lines(); tx->update(); } break; case EDIT_TOGGLE_COMMENT: { _edit_option_toggle_inline_comment(); } break; case EDIT_COMPLETE: { - tx->query_code_comple(); + tx->request_code_completion(true); } break; case EDIT_AUTO_INDENT: { String text = tx->get_text(); @@ -1109,7 +1077,7 @@ void ScriptTextEditor::_edit_option(int p_op) { tx->begin_complex_operation(); int begin, end; - if (tx->is_selection_active()) { + if (tx->has_selection()) { begin = tx->get_selection_from_line(); end = tx->get_selection_to_line(); // ignore if the cursor is not past the first column @@ -1151,7 +1119,7 @@ void ScriptTextEditor::_edit_option(int p_op) { } break; case EDIT_EVALUATE: { Expression expression; - Vector<String> lines = code_editor->get_text_editor()->get_selection_text().split("\n"); + Vector<String> lines = code_editor->get_text_editor()->get_selected_text().split("\n"); PackedStringArray results; for (int i = 0; i < lines.size(); i++) { @@ -1171,7 +1139,7 @@ void ScriptTextEditor::_edit_option(int p_op) { } code_editor->get_text_editor()->begin_complex_operation(); //prevents creating a two-step undo - code_editor->get_text_editor()->insert_text_at_cursor(String("\n").join(results)); + code_editor->get_text_editor()->insert_text_at_caret(String("\n").join(results)); code_editor->get_text_editor()->end_complex_operation(); } break; case SEARCH_FIND: { @@ -1187,16 +1155,16 @@ void ScriptTextEditor::_edit_option(int p_op) { code_editor->get_find_replace_bar()->popup_replace(); } break; case SEARCH_IN_FILES: { - String selected_text = code_editor->get_text_editor()->get_selection_text(); + String selected_text = code_editor->get_text_editor()->get_selected_text(); // Yep, because it doesn't make sense to instance this dialog for every single script open... // So this will be delegated to the ScriptEditor. - emit_signal("search_in_files_requested", selected_text); + emit_signal(SNAME("search_in_files_requested"), selected_text); } break; case REPLACE_IN_FILES: { - String selected_text = code_editor->get_text_editor()->get_selection_text(); + String selected_text = code_editor->get_text_editor()->get_selected_text(); - emit_signal("replace_in_files_requested", selected_text); + emit_signal(SNAME("replace_in_files_requested"), selected_text); } break; case SEARCH_LOCATE_FUNCTION: { quick_open->popup_dialog(get_functions()); @@ -1218,7 +1186,7 @@ void ScriptTextEditor::_edit_option(int p_op) { code_editor->remove_all_bookmarks(); } break; case DEBUG_TOGGLE_BREAKPOINT: { - int line = tx->cursor_get_line(); + int line = tx->get_caret_line(); bool dobreak = !tx->is_line_breakpointed(line); tx->set_line_as_breakpoint(line, dobreak); EditorDebuggerNode::get_singleton()->set_breakpoint(script->get_path(), line + 1, dobreak); @@ -1239,20 +1207,20 @@ void ScriptTextEditor::_edit_option(int p_op) { return; } - int line = tx->cursor_get_line(); + int line = tx->get_caret_line(); // wrap around if (line >= (int)bpoints[bpoints.size() - 1]) { tx->unfold_line(bpoints[0]); - tx->cursor_set_line(bpoints[0]); - tx->center_viewport_to_cursor(); + tx->set_caret_line(bpoints[0]); + tx->center_viewport_to_caret(); } else { for (int i = 0; i < bpoints.size(); i++) { int bline = bpoints[i]; if (bline > line) { tx->unfold_line(bline); - tx->cursor_set_line(bline); - tx->center_viewport_to_cursor(); + tx->set_caret_line(bline); + tx->center_viewport_to_caret(); return; } } @@ -1265,19 +1233,19 @@ void ScriptTextEditor::_edit_option(int p_op) { return; } - int line = tx->cursor_get_line(); + int line = tx->get_caret_line(); // wrap around if (line <= (int)bpoints[0]) { tx->unfold_line(bpoints[bpoints.size() - 1]); - tx->cursor_set_line(bpoints[bpoints.size() - 1]); - tx->center_viewport_to_cursor(); + tx->set_caret_line(bpoints[bpoints.size() - 1]); + tx->center_viewport_to_caret(); } else { - for (int i = bpoints.size(); i >= 0; i--) { + for (int i = bpoints.size() - 1; i >= 0; i--) { int bline = bpoints[i]; if (bline < line) { tx->unfold_line(bline); - tx->cursor_set_line(bline); - tx->center_viewport_to_cursor(); + tx->set_caret_line(bline); + tx->center_viewport_to_caret(); return; } } @@ -1285,21 +1253,21 @@ void ScriptTextEditor::_edit_option(int p_op) { } break; case HELP_CONTEXTUAL: { - String text = tx->get_selection_text(); + String text = tx->get_selected_text(); if (text == "") { - text = tx->get_word_under_cursor(); + text = tx->get_word_under_caret(); } if (text != "") { - emit_signal("request_help", text); + emit_signal(SNAME("request_help"), text); } } break; case LOOKUP_SYMBOL: { - String text = tx->get_word_under_cursor(); + String text = tx->get_word_under_caret(); if (text == "") { - text = tx->get_selection_text(); + text = tx->get_selected_text(); } if (text != "") { - _lookup_symbol(text, tx->cursor_get_line(), tx->cursor_get_column()); + _lookup_symbol(text, tx->get_caret_line(), tx->get_caret_column()); } } break; } @@ -1314,8 +1282,7 @@ void ScriptTextEditor::_edit_option_toggle_inline_comment() { List<String> comment_delimiters; script->get_language()->get_comment_delimiters(&comment_delimiters); - for (List<String>::Element *E = comment_delimiters.front(); E; E = E->next()) { - String script_delimiter = E->get(); + for (const String &script_delimiter : comment_delimiters) { if (script_delimiter.find(" ") == -1) { delimiter = script_delimiter; break; @@ -1355,7 +1322,7 @@ void ScriptTextEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_THEME_CHANGED: case NOTIFICATION_ENTER_TREE: { - code_editor->get_text_editor()->set_gutter_width(connection_gutter, code_editor->get_text_editor()->get_row_height()); + code_editor->get_text_editor()->set_gutter_width(connection_gutter, code_editor->get_text_editor()->get_line_height()); } break; default: break; @@ -1365,9 +1332,9 @@ void ScriptTextEditor::_notification(int p_what) { void ScriptTextEditor::_bind_methods() { ClassDB::bind_method("_update_connected_methods", &ScriptTextEditor::_update_connected_methods); - ClassDB::bind_method("get_drag_data_fw", &ScriptTextEditor::get_drag_data_fw); - ClassDB::bind_method("can_drop_data_fw", &ScriptTextEditor::can_drop_data_fw); - ClassDB::bind_method("drop_data_fw", &ScriptTextEditor::drop_data_fw); + ClassDB::bind_method("_get_drag_data_fw", &ScriptTextEditor::get_drag_data_fw); + ClassDB::bind_method("_can_drop_data_fw", &ScriptTextEditor::can_drop_data_fw); + ClassDB::bind_method("_drop_data_fw", &ScriptTextEditor::drop_data_fw); ClassDB::bind_method(D_METHOD("add_syntax_highlighter", "highlighter"), &ScriptTextEditor::add_syntax_highlighter); } @@ -1380,6 +1347,10 @@ void ScriptTextEditor::clear_edit_menu() { memdelete(edit_hb); } +void ScriptTextEditor::set_find_replace_bar(FindReplaceBar *p_bar) { + code_editor->set_find_replace_bar(p_bar); +} + void ScriptTextEditor::reload(bool p_soft) { CodeEdit *te = code_editor->get_text_editor(); Ref<Script> scr = script; @@ -1396,6 +1367,14 @@ Array ScriptTextEditor::get_breakpoints() { return code_editor->get_text_editor()->get_breakpointed_lines(); } +void ScriptTextEditor::set_breakpoint(int p_line, bool p_enabled) { + code_editor->get_text_editor()->set_line_as_breakpoint(p_line, p_enabled); +} + +void ScriptTextEditor::clear_breakpoints() { + code_editor->get_text_editor()->clear_breakpointed_lines(); +} + void ScriptTextEditor::set_tooltip_request_func(String p_method, Object *p_obj) { code_editor->get_text_editor()->set_tooltip_request_func(p_obj, p_method, this); } @@ -1403,6 +1382,10 @@ void ScriptTextEditor::set_tooltip_request_func(String p_method, Object *p_obj) void ScriptTextEditor::set_debugger_active(bool p_active) { } +Control *ScriptTextEditor::get_base_editor() const { + return code_editor->get_text_editor(); +} + Variant ScriptTextEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) { return Variant(); } @@ -1412,6 +1395,7 @@ bool ScriptTextEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_ if (d.has("type") && (String(d["type"]) == "resource" || String(d["type"]) == "files" || String(d["type"]) == "nodes" || + String(d["type"]) == "obj_property" || String(d["type"]) == "files_and_dirs")) { return true; } @@ -1441,11 +1425,14 @@ static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const } void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) { + const String quote_style = EDITOR_GET("text_editor/completion/use_single_quotes") ? "'" : "\""; + Dictionary d = p_data; CodeEdit *te = code_editor->get_text_editor(); - int row, col; - te->_get_mouse_pos(p_point, row, col); + Point2i pos = te->get_line_column_at_pos(p_point); + int row = pos.y; + int col = pos.x; if (d.has("type") && String(d["type"]) == "resource") { Ref<Resource> res = d["resource"]; @@ -1458,25 +1445,31 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data return; } - te->cursor_set_line(row); - te->cursor_set_column(col); - te->insert_text_at_cursor(res->get_path()); + te->set_caret_line(row); + te->set_caret_column(col); + te->insert_text_at_caret(res->get_path()); } if (d.has("type") && (String(d["type"]) == "files" || String(d["type"]) == "files_and_dirs")) { Array files = d["files"]; String text_to_drop; + bool preload = Input::get_singleton()->is_key_pressed(KEY_CTRL); for (int i = 0; i < files.size(); i++) { if (i > 0) { - text_to_drop += ","; + text_to_drop += ", "; + } + + if (preload) { + text_to_drop += "preload(" + String(files[i]).c_escape().quote(quote_style) + ")"; + } else { + text_to_drop += String(files[i]).c_escape().quote(quote_style); } - text_to_drop += "\"" + String(files[i]).c_escape() + "\""; } - te->cursor_set_line(row); - te->cursor_set_column(col); - te->insert_text_at_cursor(text_to_drop); + te->set_caret_line(row); + te->set_caret_column(col); + te->insert_text_at_caret(text_to_drop); } if (d.has("type") && String(d["type"]) == "nodes") { @@ -1501,12 +1494,20 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data } String path = sn->get_path_to(node); - text_to_drop += "\"" + path.c_escape() + "\""; + text_to_drop += path.c_escape().quote(quote_style); } - te->cursor_set_line(row); - te->cursor_set_column(col); - te->insert_text_at_cursor(text_to_drop); + te->set_caret_line(row); + te->set_caret_column(col); + te->insert_text_at_caret(text_to_drop); + } + + if (d.has("type") && String(d["type"]) == "obj_property") { + const String text_to_drop = String(d["property"]).c_escape().quote(quote_style); + + te->set_caret_line(row); + te->set_caret_column(col); + te->insert_text_at_caret(text_to_drop); } } @@ -1517,21 +1518,23 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) { bool create_menu = false; CodeEdit *tx = code_editor->get_text_editor(); - if (mb.is_valid() && mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed()) { + if (mb.is_valid() && mb->get_button_index() == MOUSE_BUTTON_RIGHT && mb->is_pressed()) { local_pos = mb->get_global_position() - tx->get_global_position(); create_menu = true; - } else if (k.is_valid() && k->get_keycode() == KEY_MENU) { - local_pos = tx->_get_cursor_pixel_pos(); + } else if (k.is_valid() && k->is_action("ui_menu", true)) { + tx->adjust_viewport_to_caret(); + local_pos = tx->get_caret_draw_pos(); create_menu = true; } if (create_menu) { - int col, row; - tx->_get_mouse_pos(local_pos, row, col); + Point2i pos = tx->get_line_column_at_pos(local_pos); + int row = pos.y; + int col = pos.x; - tx->set_right_click_moves_caret(EditorSettings::get_singleton()->get("text_editor/cursor/right_click_moves_caret")); - if (tx->is_right_click_moving_caret()) { - if (tx->is_selection_active()) { + tx->set_move_caret_on_right_click_enabled(EditorSettings::get_singleton()->get("text_editor/behavior/navigation/move_caret_on_right_click")); + if (tx->is_move_caret_on_right_click_enabled()) { + if (tx->has_selection()) { int from_line = tx->get_selection_from_line(); int to_line = tx->get_selection_to_line(); int from_column = tx->get_selection_from_column(); @@ -1542,22 +1545,22 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) { tx->deselect(); } } - if (!tx->is_selection_active()) { - tx->cursor_set_line(row, true, false); - tx->cursor_set_column(col); + if (!tx->has_selection()) { + tx->set_caret_line(row, false, false); + tx->set_caret_column(col); } } String word_at_pos = tx->get_word_at_pos(local_pos); if (word_at_pos == "") { - word_at_pos = tx->get_word_under_cursor(); + word_at_pos = tx->get_word_under_caret(); } if (word_at_pos == "") { - word_at_pos = tx->get_selection_text(); + word_at_pos = tx->get_selected_text(); } bool has_color = (word_at_pos == "Color"); - bool foldable = tx->can_fold(row) || tx->is_folded(row); + bool foldable = tx->can_fold_line(row) || tx->is_line_folded(row); bool open_docs = false; bool goto_definition = false; @@ -1569,7 +1572,7 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) { base = _find_node_for_script(base, base, script); } ScriptLanguage::LookupResult result; - if (script->get_language()->lookup_code(code_editor->get_text_editor()->get_text_for_lookup_completion(), word_at_pos, script->get_path(), base, result) == OK) { + if (script->get_language()->lookup_code(code_editor->get_text_editor()->get_text_for_symbol_lookup(), word_at_pos, script->get_path(), base, result) == OK) { open_docs = true; } } @@ -1605,7 +1608,7 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) { has_color = false; } } - _make_context_menu(tx->is_selection_active(), has_color, foldable, open_docs, goto_definition, local_pos); + _make_context_menu(tx->has_selection(), has_color, foldable, open_docs, goto_definition, local_pos); } } @@ -1630,18 +1633,25 @@ void ScriptTextEditor::_color_changed(const Color &p_color) { code_editor->get_text_editor()->update(); } +void ScriptTextEditor::_prepare_edit_menu() { + const CodeEdit *tx = code_editor->get_text_editor(); + PopupMenu *popup = edit_menu->get_popup(); + popup->set_item_disabled(popup->get_item_index(EDIT_UNDO), !tx->has_undo()); + popup->set_item_disabled(popup->get_item_index(EDIT_REDO), !tx->has_redo()); +} + void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p_foldable, bool p_open_docs, bool p_goto_definition, Vector2 p_pos) { context_menu->clear(); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_redo"), EDIT_REDO); context_menu->add_separator(); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_cut"), EDIT_CUT); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_copy"), EDIT_COPY); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_paste"), EDIT_PASTE); context_menu->add_separator(); - context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL); + context_menu->add_shortcut(ED_GET_SHORTCUT("ui_text_select_all"), EDIT_SELECT_ALL); context_menu->add_separator(); context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT); @@ -1669,6 +1679,10 @@ void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p } } + const CodeEdit *tx = code_editor->get_text_editor(); + context_menu->set_item_disabled(context_menu->get_item_index(EDIT_UNDO), !tx->has_undo()); + context_menu->set_item_disabled(context_menu->get_item_index(EDIT_REDO), !tx->has_redo()); + context_menu->set_position(get_global_transform().xform(p_pos)); context_menu->set_size(Vector2(1, 1)); context_menu->popup(); @@ -1683,6 +1697,7 @@ void ScriptTextEditor::_enable_code_editor() { editor_box->set_v_size_flags(SIZE_EXPAND_FILL); editor_box->add_child(code_editor); + code_editor->connect("show_errors_panel", callable_mp(this, &ScriptTextEditor::_show_errors_panel)); code_editor->connect("show_warnings_panel", callable_mp(this, &ScriptTextEditor::_show_warnings_panel)); code_editor->connect("validate_script", callable_mp(this, &ScriptTextEditor::_validate_script)); code_editor->connect("load_theme_settings", callable_mp(this, &ScriptTextEditor::_load_theme_settings)); @@ -1698,11 +1713,18 @@ void ScriptTextEditor::_enable_code_editor() { editor_box->add_child(warnings_panel); warnings_panel->add_theme_font_override( - "normal_font", EditorNode::get_singleton()->get_gui_base()->get_theme_font("main", "EditorFonts")); + "normal_font", EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("main"), SNAME("EditorFonts"))); warnings_panel->add_theme_font_size_override( - "normal_font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size("main_size", "EditorFonts")); + "normal_font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("main_size"), SNAME("EditorFonts"))); warnings_panel->connect("meta_clicked", callable_mp(this, &ScriptTextEditor::_warning_clicked)); + editor_box->add_child(errors_panel); + errors_panel->add_theme_font_override( + "normal_font", EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("main"), SNAME("EditorFonts"))); + errors_panel->add_theme_font_size_override( + "normal_font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("main_size"), SNAME("EditorFonts"))); + errors_panel->connect("meta_clicked", callable_mp(this, &ScriptTextEditor::_error_clicked)); + add_child(context_menu); context_menu->connect("id_pressed", callable_mp(this, &ScriptTextEditor::_edit_option)); @@ -1722,6 +1744,9 @@ void ScriptTextEditor::_enable_code_editor() { color_picker->set_raw_mode(true); } + int picker_shape = EDITOR_GET("interface/inspector/default_color_picker_shape"); + color_picker->set_picker_shape((ColorPicker::PickerShapeType)picker_shape); + quick_open = memnew(ScriptEditorQuickOpen); quick_open->connect("goto_line", callable_mp(this, &ScriptTextEditor::_goto_line)); add_child(quick_open); @@ -1743,14 +1768,15 @@ void ScriptTextEditor::_enable_code_editor() { search_menu->get_popup()->connect("id_pressed", callable_mp(this, &ScriptTextEditor::_edit_option)); edit_hb->add_child(edit_menu); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO); + edit_menu->connect("about_to_popup", callable_mp(this, &ScriptTextEditor::_prepare_edit_menu)); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_undo"), EDIT_UNDO); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_redo"), EDIT_REDO); edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/copy"), EDIT_COPY); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/paste"), EDIT_PASTE); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_cut"), EDIT_CUT); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_copy"), EDIT_COPY); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_paste"), EDIT_PASTE); edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/select_all"), EDIT_SELECT_ALL); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_text_select_all"), EDIT_SELECT_ALL); edit_menu->get_popup()->add_separator(); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_up"), EDIT_MOVE_LINE_UP); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/move_down"), EDIT_MOVE_LINE_DOWN); @@ -1762,8 +1788,8 @@ void ScriptTextEditor::_enable_code_editor() { edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/fold_all_lines"), EDIT_FOLD_ALL_LINES); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/unfold_all_lines"), EDIT_UNFOLD_ALL_LINES); edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/clone_down"), EDIT_CLONE_DOWN); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/complete_symbol"), EDIT_COMPLETE); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/duplicate_selection"), EDIT_DUPLICATE_SELECTION); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_text_completion_query"), EDIT_COMPLETE); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/evaluate_selection"), EDIT_EVALUATE); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/trim_trailing_whitespace"), EDIT_TRIM_TRAILING_WHITESAPCE); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_indent_to_spaces"), EDIT_CONVERT_INDENT_TO_SPACES); @@ -1821,7 +1847,7 @@ ScriptTextEditor::ScriptTextEditor() { code_editor->get_text_editor()->set_gutter_name(connection_gutter, "connection_gutter"); code_editor->get_text_editor()->set_gutter_draw(connection_gutter, false); code_editor->get_text_editor()->set_gutter_overwritable(connection_gutter, true); - code_editor->get_text_editor()->set_gutter_type(connection_gutter, TextEdit::GUTTER_TPYE_ICON); + code_editor->get_text_editor()->set_gutter_type(connection_gutter, TextEdit::GUTTER_TYPE_ICON); warnings_panel = memnew(RichTextLabel); warnings_panel->set_custom_minimum_size(Size2(0, 100 * EDSCALE)); @@ -1831,13 +1857,19 @@ ScriptTextEditor::ScriptTextEditor() { warnings_panel->set_focus_mode(FOCUS_CLICK); warnings_panel->hide(); + errors_panel = memnew(RichTextLabel); + errors_panel->set_custom_minimum_size(Size2(0, 100 * EDSCALE)); + errors_panel->set_h_size_flags(SIZE_EXPAND_FILL); + errors_panel->set_meta_underline(true); + errors_panel->set_selection_enabled(true); + errors_panel->set_focus_mode(FOCUS_CLICK); + errors_panel->hide(); + update_settings(); - code_editor->get_text_editor()->set_callhint_settings( - EditorSettings::get_singleton()->get("text_editor/completion/put_callhint_tooltip_below_current_line"), - EditorSettings::get_singleton()->get("text_editor/completion/callhint_tooltip_offset")); + code_editor->get_text_editor()->set_code_hint_draw_below(EditorSettings::get_singleton()->get("text_editor/completion/put_callhint_tooltip_below_current_line")); - code_editor->get_text_editor()->set_select_identifiers_on_hover(true); + code_editor->get_text_editor()->set_symbol_lookup_on_click_enabled(true); code_editor->get_text_editor()->set_context_menu_enabled(false); context_menu = memnew(PopupMenu); @@ -1858,11 +1890,11 @@ ScriptTextEditor::ScriptTextEditor() { highlighter_menu->set_name("highlighter_menu"); Ref<EditorPlainTextSyntaxHighlighter> plain_highlighter; - plain_highlighter.instance(); + plain_highlighter.instantiate(); add_syntax_highlighter(plain_highlighter); Ref<EditorStandardSyntaxHighlighter> highlighter; - highlighter.instance(); + highlighter.instantiate(); add_syntax_highlighter(highlighter); set_syntax_highlighter(highlighter); @@ -1893,6 +1925,7 @@ ScriptTextEditor::~ScriptTextEditor() { if (!editor_enabled) { memdelete(code_editor); memdelete(warnings_panel); + memdelete(errors_panel); memdelete(context_menu); memdelete(color_panel); memdelete(edit_hb); @@ -1915,12 +1948,6 @@ static ScriptEditorBase *create_editor(const RES &p_resource) { } void ScriptTextEditor::register_editor() { - ED_SHORTCUT("script_text_editor/undo", TTR("Undo"), KEY_MASK_CMD | KEY_Z); - ED_SHORTCUT("script_text_editor/redo", TTR("Redo"), KEY_MASK_CMD | KEY_Y); - ED_SHORTCUT("script_text_editor/cut", TTR("Cut"), KEY_MASK_CMD | KEY_X); - ED_SHORTCUT("script_text_editor/copy", TTR("Copy"), KEY_MASK_CMD | KEY_C); - ED_SHORTCUT("script_text_editor/paste", TTR("Paste"), KEY_MASK_CMD | KEY_V); - ED_SHORTCUT("script_text_editor/select_all", TTR("Select All"), KEY_MASK_CMD | KEY_A); ED_SHORTCUT("script_text_editor/move_up", TTR("Move Up"), KEY_MASK_ALT | KEY_UP); ED_SHORTCUT("script_text_editor/move_down", TTR("Move Down"), KEY_MASK_ALT | KEY_DOWN); ED_SHORTCUT("script_text_editor/delete_line", TTR("Delete Line"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_K); @@ -1928,62 +1955,50 @@ void ScriptTextEditor::register_editor() { // Leave these at zero, same can be accomplished with tab/shift-tab, including selection. // The next/previous in history shortcut in this case makes a lot more sense. - ED_SHORTCUT("script_text_editor/indent_left", TTR("Indent Left"), 0); - ED_SHORTCUT("script_text_editor/indent_right", TTR("Indent Right"), 0); + ED_SHORTCUT("script_text_editor/indent_left", TTR("Indent Left"), KEY_NONE); + ED_SHORTCUT("script_text_editor/indent_right", TTR("Indent Right"), KEY_NONE); ED_SHORTCUT("script_text_editor/toggle_comment", TTR("Toggle Comment"), KEY_MASK_CMD | KEY_K); ED_SHORTCUT("script_text_editor/toggle_fold_line", TTR("Fold/Unfold Line"), KEY_MASK_ALT | KEY_F); - ED_SHORTCUT("script_text_editor/fold_all_lines", TTR("Fold All Lines"), 0); - ED_SHORTCUT("script_text_editor/unfold_all_lines", TTR("Unfold All Lines"), 0); -#ifdef OSX_ENABLED - ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_SHIFT | KEY_MASK_CMD | KEY_C); - ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CTRL | KEY_SPACE); -#else - ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_CMD | KEY_D); - ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CMD | KEY_SPACE); -#endif + ED_SHORTCUT("script_text_editor/fold_all_lines", TTR("Fold All Lines"), KEY_NONE); + ED_SHORTCUT("script_text_editor/unfold_all_lines", TTR("Unfold All Lines"), KEY_NONE); + ED_SHORTCUT("script_text_editor/duplicate_selection", TTR("Duplicate Selection"), KEY_MASK_SHIFT | KEY_MASK_CMD | KEY_D); + ED_SHORTCUT_OVERRIDE("script_text_editor/duplicate_selection", "macos", KEY_MASK_SHIFT | KEY_MASK_CMD | KEY_C); ED_SHORTCUT("script_text_editor/evaluate_selection", TTR("Evaluate Selection"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_E); ED_SHORTCUT("script_text_editor/trim_trailing_whitespace", TTR("Trim Trailing Whitespace"), KEY_MASK_CMD | KEY_MASK_ALT | KEY_T); ED_SHORTCUT("script_text_editor/convert_indent_to_spaces", TTR("Convert Indent to Spaces"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Y); ED_SHORTCUT("script_text_editor/convert_indent_to_tabs", TTR("Convert Indent to Tabs"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_I); ED_SHORTCUT("script_text_editor/auto_indent", TTR("Auto Indent"), KEY_MASK_CMD | KEY_I); - ED_SHORTCUT("script_text_editor/find", TTR("Find..."), KEY_MASK_CMD | KEY_F); -#ifdef OSX_ENABLED - ED_SHORTCUT("script_text_editor/find_next", TTR("Find Next"), KEY_MASK_CMD | KEY_G); - ED_SHORTCUT("script_text_editor/find_previous", TTR("Find Previous"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_G); - ED_SHORTCUT("script_text_editor/replace", TTR("Replace..."), KEY_MASK_ALT | KEY_MASK_CMD | KEY_F); -#else + ED_SHORTCUT_AND_COMMAND("script_text_editor/find", TTR("Find..."), KEY_MASK_CMD | KEY_F); + ED_SHORTCUT("script_text_editor/find_next", TTR("Find Next"), KEY_F3); + ED_SHORTCUT_OVERRIDE("script_text_editor/find_next", "macos", KEY_MASK_CMD | KEY_G); + ED_SHORTCUT("script_text_editor/find_previous", TTR("Find Previous"), KEY_MASK_SHIFT | KEY_F3); - ED_SHORTCUT("script_text_editor/replace", TTR("Replace..."), KEY_MASK_CMD | KEY_R); -#endif + ED_SHORTCUT_OVERRIDE("script_text_editor/find_previous", "macos", KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_G); + + ED_SHORTCUT_AND_COMMAND("script_text_editor/replace", TTR("Replace..."), KEY_MASK_CMD | KEY_R); + ED_SHORTCUT_OVERRIDE("script_text_editor/replace", "macos", KEY_MASK_ALT | KEY_MASK_CMD | KEY_F); 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); -#else ED_SHORTCUT("script_text_editor/contextual_help", TTR("Contextual Help"), KEY_MASK_ALT | KEY_F1); -#endif + ED_SHORTCUT_OVERRIDE("script_text_editor/contextual_help", "macos", KEY_MASK_ALT | KEY_MASK_SHIFT | KEY_SPACE); ED_SHORTCUT("script_text_editor/toggle_bookmark", TTR("Toggle Bookmark"), KEY_MASK_CMD | KEY_MASK_ALT | KEY_B); ED_SHORTCUT("script_text_editor/goto_next_bookmark", TTR("Go to Next Bookmark"), KEY_MASK_CMD | KEY_B); ED_SHORTCUT("script_text_editor/goto_previous_bookmark", TTR("Go to Previous Bookmark"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_B); - ED_SHORTCUT("script_text_editor/remove_all_bookmarks", TTR("Remove All Bookmarks"), 0); + ED_SHORTCUT("script_text_editor/remove_all_bookmarks", TTR("Remove All Bookmarks"), KEY_NONE); -#ifdef OSX_ENABLED - ED_SHORTCUT("script_text_editor/goto_function", TTR("Go to Function..."), KEY_MASK_CTRL | KEY_MASK_CMD | KEY_J); -#else ED_SHORTCUT("script_text_editor/goto_function", TTR("Go to Function..."), KEY_MASK_ALT | KEY_MASK_CMD | KEY_F); -#endif + ED_SHORTCUT_OVERRIDE("script_text_editor/goto_function", "macos", KEY_MASK_CTRL | KEY_MASK_CMD | KEY_J); + ED_SHORTCUT("script_text_editor/goto_line", TTR("Go to Line..."), KEY_MASK_CMD | KEY_L); -#ifdef OSX_ENABLED - ED_SHORTCUT("script_text_editor/toggle_breakpoint", TTR("Toggle Breakpoint"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_B); -#else ED_SHORTCUT("script_text_editor/toggle_breakpoint", TTR("Toggle Breakpoint"), KEY_F9); -#endif + ED_SHORTCUT_OVERRIDE("script_text_editor/toggle_breakpoint", "macos", KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_B); + ED_SHORTCUT("script_text_editor/remove_all_breakpoints", TTR("Remove All Breakpoints"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F9); ED_SHORTCUT("script_text_editor/goto_next_breakpoint", TTR("Go to Next Breakpoint"), KEY_MASK_CMD | KEY_PERIOD); ED_SHORTCUT("script_text_editor/goto_previous_breakpoint", TTR("Go to Previous Breakpoint"), KEY_MASK_CMD | KEY_COMMA); |
