You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-20 14:45:44 +00:00
Open source code errors in external editor
This commit is contained in:
@@ -200,20 +200,30 @@ void EditorLog::_load_state() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EditorLog::_meta_clicked(const String &p_meta) {
|
void EditorLog::_meta_clicked(const String &p_meta) {
|
||||||
Ref<RegExMatch> uri_match = RegEx(R"(^([a-zA-Z][a-zA-Z0-9+.-]*):(?://)?(.+?)(?::([0-9]+))?$)").search(p_meta);
|
if (!p_meta.contains_char(':')) {
|
||||||
if (uri_match.is_null()) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const PackedStringArray parts = p_meta.rsplit(":", true, 1);
|
||||||
|
String path = parts[0];
|
||||||
|
const int line = parts[1].to_int() - 1;
|
||||||
|
|
||||||
String scheme = uri_match->get_string(1);
|
if (path.begins_with("res://")) {
|
||||||
if (scheme == "res") {
|
if (ResourceLoader::exists(path)) {
|
||||||
String file = uri_match->get_string(2);
|
const Ref<Resource> res = ResourceLoader::load(path);
|
||||||
int line = (int)uri_match->get_string(3).to_int();
|
ScriptEditor::get_singleton()->edit(res, line, 0);
|
||||||
if (ResourceLoader::exists(file)) {
|
|
||||||
Ref<Resource> res = ResourceLoader::load(file);
|
|
||||||
ScriptEditor::get_singleton()->edit(res, line - 1, 0);
|
|
||||||
InspectorDock::get_singleton()->edit_resource(res);
|
InspectorDock::get_singleton()->edit_resource(res);
|
||||||
}
|
}
|
||||||
|
} else if (path.has_extension("cpp") || path.has_extension("h") || path.has_extension("mm") || path.has_extension("hpp")) {
|
||||||
|
// Godot source file. Try to open it in external editor.
|
||||||
|
if (path.begins_with("./") || path.begins_with(".\\")) {
|
||||||
|
// Relative path. Convert to absolute, using executable path as reference.
|
||||||
|
path = path.trim_prefix("./").trim_prefix(".\\");
|
||||||
|
path = OS::get_singleton()->get_executable_path().get_base_dir().get_base_dir().path_join(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ScriptEditorPlugin::open_in_external_editor(path, line, -1, true)) {
|
||||||
|
OS::get_singleton()->shell_open(path);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
OS::get_singleton()->shell_open(p_meta);
|
OS::get_singleton()->shell_open(p_meta);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2554,64 +2554,12 @@ bool ScriptEditor::edit(const Ref<Resource> &p_resource, int p_line, int p_col,
|
|||||||
if (use_external_editor &&
|
if (use_external_editor &&
|
||||||
(EditorDebuggerNode::get_singleton()->get_dump_stack_script() != p_resource || EditorDebuggerNode::get_singleton()->get_debug_with_external_editor()) &&
|
(EditorDebuggerNode::get_singleton()->get_dump_stack_script() != p_resource || EditorDebuggerNode::get_singleton()->get_debug_with_external_editor()) &&
|
||||||
p_resource->get_path().is_resource_file()) {
|
p_resource->get_path().is_resource_file()) {
|
||||||
String path = EDITOR_GET("text_editor/external/exec_path");
|
if (ScriptEditorPlugin::open_in_external_editor(ProjectSettings::get_singleton()->globalize_path(p_resource->get_path()), p_line, p_col)) {
|
||||||
String flags = EDITOR_GET("text_editor/external/exec_flags");
|
|
||||||
|
|
||||||
List<String> args;
|
|
||||||
bool has_file_flag = false;
|
|
||||||
String script_path = ProjectSettings::get_singleton()->globalize_path(p_resource->get_path());
|
|
||||||
|
|
||||||
if (flags.size()) {
|
|
||||||
String project_path = ProjectSettings::get_singleton()->get_resource_path();
|
|
||||||
|
|
||||||
flags = flags.replacen("{line}", itos(MAX(p_line + 1, 1)));
|
|
||||||
flags = flags.replacen("{col}", itos(p_col + 1));
|
|
||||||
flags = flags.strip_edges().replace("\\\\", "\\");
|
|
||||||
|
|
||||||
int from = 0;
|
|
||||||
int num_chars = 0;
|
|
||||||
bool inside_quotes = false;
|
|
||||||
|
|
||||||
for (int i = 0; i < flags.size(); i++) {
|
|
||||||
if (flags[i] == '"' && (!i || flags[i - 1] != '\\')) {
|
|
||||||
if (!inside_quotes) {
|
|
||||||
from++;
|
|
||||||
}
|
|
||||||
inside_quotes = !inside_quotes;
|
|
||||||
|
|
||||||
} else if (flags[i] == '\0' || (!inside_quotes && flags[i] == ' ')) {
|
|
||||||
String arg = flags.substr(from, num_chars);
|
|
||||||
if (arg.contains("{file}")) {
|
|
||||||
has_file_flag = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// do path replacement here, else there will be issues with spaces and quotes
|
|
||||||
arg = arg.replacen("{project}", project_path);
|
|
||||||
arg = arg.replacen("{file}", script_path);
|
|
||||||
args.push_back(arg);
|
|
||||||
|
|
||||||
from = i + 1;
|
|
||||||
num_chars = 0;
|
|
||||||
} else {
|
|
||||||
num_chars++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default to passing script path if no {file} flag is specified.
|
|
||||||
if (!has_file_flag) {
|
|
||||||
args.push_back(script_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!path.is_empty()) {
|
|
||||||
Error err = OS::get_singleton()->create_process(path, args);
|
|
||||||
if (err == OK) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
} else {
|
||||||
}
|
|
||||||
|
|
||||||
ERR_PRINT("Couldn't open external text editor, falling back to the internal editor. Review your `text_editor/external/` editor settings.");
|
ERR_PRINT("Couldn't open external text editor, falling back to the internal editor. Review your `text_editor/external/` editor settings.");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < tab_container->get_tab_count(); i++) {
|
for (int i = 0; i < tab_container->get_tab_count(); i++) {
|
||||||
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i));
|
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i));
|
||||||
@@ -4629,6 +4577,63 @@ void ScriptEditorPlugin::_notification(int p_what) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ScriptEditorPlugin::open_in_external_editor(const String &p_path, int p_line, int p_col, bool p_ignore_project) {
|
||||||
|
const String path = EDITOR_GET("text_editor/external/exec_path");
|
||||||
|
if (path.is_empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
String flags = EDITOR_GET("text_editor/external/exec_flags");
|
||||||
|
|
||||||
|
List<String> args;
|
||||||
|
bool has_file_flag = false;
|
||||||
|
|
||||||
|
if (!flags.is_empty()) {
|
||||||
|
flags = flags.replacen("{line}", itos(MAX(p_line + 1, 1)));
|
||||||
|
flags = flags.replacen("{col}", itos(p_col + 1));
|
||||||
|
flags = flags.strip_edges().replace("\\\\", "\\");
|
||||||
|
|
||||||
|
int from = 0;
|
||||||
|
int num_chars = 0;
|
||||||
|
bool inside_quotes = false;
|
||||||
|
|
||||||
|
for (int i = 0; i < flags.size(); i++) {
|
||||||
|
if (flags[i] == '"' && (!i || flags[i - 1] != '\\')) {
|
||||||
|
if (!inside_quotes) {
|
||||||
|
from++;
|
||||||
|
}
|
||||||
|
inside_quotes = !inside_quotes;
|
||||||
|
|
||||||
|
} else if (flags[i] == '\0' || (!inside_quotes && flags[i] == ' ')) {
|
||||||
|
String arg = flags.substr(from, num_chars);
|
||||||
|
if (arg.contains("{file}")) {
|
||||||
|
has_file_flag = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do path replacement here, else there will be issues with spaces and quotes
|
||||||
|
if (p_ignore_project) {
|
||||||
|
arg = arg.replacen("{project}", String());
|
||||||
|
} else {
|
||||||
|
arg = arg.replacen("{project}", ProjectSettings::get_singleton()->get_resource_path());
|
||||||
|
}
|
||||||
|
arg = arg.replacen("{file}", p_path);
|
||||||
|
args.push_back(arg);
|
||||||
|
|
||||||
|
from = i + 1;
|
||||||
|
num_chars = 0;
|
||||||
|
} else {
|
||||||
|
num_chars++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default to passing script path if no {file} flag is specified.
|
||||||
|
if (!has_file_flag) {
|
||||||
|
args.push_back(p_path);
|
||||||
|
}
|
||||||
|
return OS::get_singleton()->create_process(path, args) == OK;
|
||||||
|
}
|
||||||
|
|
||||||
void ScriptEditorPlugin::edit(Object *p_object) {
|
void ScriptEditorPlugin::edit(Object *p_object) {
|
||||||
if (Object::cast_to<Script>(p_object)) {
|
if (Object::cast_to<Script>(p_object)) {
|
||||||
Script *p_script = Object::cast_to<Script>(p_object);
|
Script *p_script = Object::cast_to<Script>(p_object);
|
||||||
|
|||||||
@@ -644,6 +644,8 @@ protected:
|
|||||||
void _notification(int p_what);
|
void _notification(int p_what);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static bool open_in_external_editor(const String &p_path, int p_line, int p_col, bool p_ignore_project = false);
|
||||||
|
|
||||||
virtual String get_plugin_name() const override { return TTRC("Script"); }
|
virtual String get_plugin_name() const override { return TTRC("Script"); }
|
||||||
bool has_main_screen() const override { return true; }
|
bool has_main_screen() const override { return true; }
|
||||||
virtual void edit(Object *p_object) override;
|
virtual void edit(Object *p_object) override;
|
||||||
|
|||||||
Reference in New Issue
Block a user