瀏覽代碼

Merge pull request #66867 from Rindbee/implement-willSaveWaitUntil

Implement `GDScriptTextDocument::willSaveWaitUntil` to clean up outdated documents before saving
Rémi Verschelde 2 年之前
父節點
當前提交
f36dda3185

+ 35 - 45
editor/plugins/script_editor_plugin.cpp

@@ -1301,26 +1301,15 @@ void ScriptEditor::_menu_option(int p_option) {
 					break;
 				}
 
-				if (script != nullptr) {
-					Vector<DocData::ClassDoc> documentations = script->get_documentation();
-					for (int j = 0; j < documentations.size(); j++) {
-						const DocData::ClassDoc &doc = documentations.get(j);
-						if (EditorHelp::get_doc_data()->has_doc(doc.name)) {
-							EditorHelp::get_doc_data()->remove_doc(doc.name);
-						}
-					}
+				if (script.is_valid()) {
+					clear_docs_from_script(script);
 				}
 
 				EditorNode::get_singleton()->push_item(resource.ptr());
 				EditorNode::get_singleton()->save_resource_as(resource);
 
-				if (script != nullptr) {
-					Vector<DocData::ClassDoc> documentations = script->get_documentation();
-					for (int j = 0; j < documentations.size(); j++) {
-						const DocData::ClassDoc &doc = documentations.get(j);
-						EditorHelp::get_doc_data()->add_doc(doc);
-						update_doc(doc.name);
-					}
+				if (script.is_valid()) {
+					update_docs_from_script(script);
 				}
 			} break;
 
@@ -2418,14 +2407,8 @@ void ScriptEditor::save_current_script() {
 		return;
 	}
 
-	if (script != nullptr) {
-		Vector<DocData::ClassDoc> documentations = script->get_documentation();
-		for (int j = 0; j < documentations.size(); j++) {
-			const DocData::ClassDoc &doc = documentations.get(j);
-			if (EditorHelp::get_doc_data()->has_doc(doc.name)) {
-				EditorHelp::get_doc_data()->remove_doc(doc.name);
-			}
-		}
+	if (script.is_valid()) {
+		clear_docs_from_script(script);
 	}
 
 	if (resource->is_built_in()) {
@@ -2440,13 +2423,8 @@ void ScriptEditor::save_current_script() {
 		EditorNode::get_singleton()->save_resource(resource);
 	}
 
-	if (script != nullptr) {
-		Vector<DocData::ClassDoc> documentations = script->get_documentation();
-		for (int j = 0; j < documentations.size(); j++) {
-			const DocData::ClassDoc &doc = documentations.get(j);
-			EditorHelp::get_doc_data()->add_doc(doc);
-			update_doc(doc.name);
-		}
+	if (script.is_valid()) {
+		update_docs_from_script(script);
 	}
 }
 
@@ -2491,25 +2469,14 @@ void ScriptEditor::save_all_scripts() {
 				continue;
 			}
 
-			if (script != nullptr) {
-				Vector<DocData::ClassDoc> documentations = script->get_documentation();
-				for (int j = 0; j < documentations.size(); j++) {
-					const DocData::ClassDoc &doc = documentations.get(j);
-					if (EditorHelp::get_doc_data()->has_doc(doc.name)) {
-						EditorHelp::get_doc_data()->remove_doc(doc.name);
-					}
-				}
+			if (script.is_valid()) {
+				clear_docs_from_script(script);
 			}
 
 			EditorNode::get_singleton()->save_resource(edited_res); //external script, save it
 
-			if (script != nullptr) {
-				Vector<DocData::ClassDoc> documentations = script->get_documentation();
-				for (int j = 0; j < documentations.size(); j++) {
-					const DocData::ClassDoc &doc = documentations.get(j);
-					EditorHelp::get_doc_data()->add_doc(doc);
-					update_doc(doc.name);
-				}
+			if (script.is_valid()) {
+				update_docs_from_script(script);
 			}
 		} else {
 			// For built-in scripts, save their scenes instead.
@@ -3331,6 +3298,29 @@ void ScriptEditor::update_doc(const String &p_name) {
 	}
 }
 
+void ScriptEditor::clear_docs_from_script(const Ref<Script> &p_script) {
+	ERR_FAIL_COND(p_script.is_null());
+
+	Vector<DocData::ClassDoc> documentations = p_script->get_documentation();
+	for (int j = 0; j < documentations.size(); j++) {
+		const DocData::ClassDoc &doc = documentations.get(j);
+		if (EditorHelp::get_doc_data()->has_doc(doc.name)) {
+			EditorHelp::get_doc_data()->remove_doc(doc.name);
+		}
+	}
+}
+
+void ScriptEditor::update_docs_from_script(const Ref<Script> &p_script) {
+	ERR_FAIL_COND(p_script.is_null());
+
+	Vector<DocData::ClassDoc> documentations = p_script->get_documentation();
+	for (int j = 0; j < documentations.size(); j++) {
+		const DocData::ClassDoc &doc = documentations.get(j);
+		EditorHelp::get_doc_data()->add_doc(doc);
+		update_doc(doc.name);
+	}
+}
+
 void ScriptEditor::_update_selected_editor_menu() {
 	for (int i = 0; i < tab_container->get_tab_count(); i++) {
 		bool current = tab_container->get_current_tab() == i;

+ 2 - 0
editor/plugins/script_editor_plugin.h

@@ -508,6 +508,8 @@ public:
 
 	void goto_help(const String &p_desc) { _help_class_goto(p_desc); }
 	void update_doc(const String &p_name);
+	void clear_docs_from_script(const Ref<Script> &p_script);
+	void update_docs_from_script(const Ref<Script> &p_script);
 
 	bool can_take_away_focus() const;
 

+ 20 - 12
modules/gdscript/language_server/gdscript_text_document.cpp

@@ -42,6 +42,7 @@ void GDScriptTextDocument::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("didOpen"), &GDScriptTextDocument::didOpen);
 	ClassDB::bind_method(D_METHOD("didClose"), &GDScriptTextDocument::didClose);
 	ClassDB::bind_method(D_METHOD("didChange"), &GDScriptTextDocument::didChange);
+	ClassDB::bind_method(D_METHOD("willSaveWaitUntil"), &GDScriptTextDocument::willSaveWaitUntil);
 	ClassDB::bind_method(D_METHOD("didSave"), &GDScriptTextDocument::didSave);
 	ClassDB::bind_method(D_METHOD("nativeSymbol"), &GDScriptTextDocument::nativeSymbol);
 	ClassDB::bind_method(D_METHOD("documentSymbol"), &GDScriptTextDocument::documentSymbol);
@@ -81,6 +82,16 @@ void GDScriptTextDocument::didChange(const Variant &p_param) {
 	sync_script_content(doc.uri, doc.text);
 }
 
+void GDScriptTextDocument::willSaveWaitUntil(const Variant &p_param) {
+	lsp::TextDocumentItem doc = load_document_item(p_param);
+
+	String path = GDScriptLanguageProtocol::get_singleton()->get_workspace()->get_file_path(doc.uri);
+	Ref<Script> script = ResourceLoader::load(path);
+	if (script.is_valid()) {
+		ScriptEditor::get_singleton()->clear_docs_from_script(script);
+	}
+}
+
 void GDScriptTextDocument::didSave(const Variant &p_param) {
 	lsp::TextDocumentItem doc = load_document_item(p_param);
 	Dictionary dict = p_param;
@@ -88,11 +99,16 @@ void GDScriptTextDocument::didSave(const Variant &p_param) {
 
 	sync_script_content(doc.uri, text);
 
-	/*String path = GDScriptLanguageProtocol::get_singleton()->get_workspace()->get_file_path(doc.uri);
-
+	String path = GDScriptLanguageProtocol::get_singleton()->get_workspace()->get_file_path(doc.uri);
 	Ref<GDScript> script = ResourceLoader::load(path);
-	script->load_source_code(path);
-	script->reload(true);*/
+	if (script.is_valid() && (script->load_source_code(path) == OK)) {
+		if (script->is_tool()) {
+			script->get_language()->reload_tool_script(script, true);
+		} else {
+			script->reload(true);
+		}
+		ScriptEditor::get_singleton()->update_docs_from_script(script);
+	}
 }
 
 lsp::TextDocumentItem GDScriptTextDocument::load_document_item(const Variant &p_param) {
@@ -417,14 +433,6 @@ void GDScriptTextDocument::sync_script_content(const String &p_path, const Strin
 	GDScriptLanguageProtocol::get_singleton()->get_workspace()->parse_script(path, p_content);
 
 	EditorFileSystem::get_singleton()->update_file(path);
-	Error error;
-	Ref<GDScript> script = ResourceLoader::load(path, "", ResourceFormatLoader::CACHE_MODE_REUSE, &error);
-	if (error == OK) {
-		if (script->load_source_code(path) == OK) {
-			script->reload(true);
-			ScriptEditor::get_singleton()->reload_scripts(true); // Refresh scripts opened in the internal editor.
-		}
-	}
 }
 
 void GDScriptTextDocument::show_native_symbol_in_editor(const String &p_symbol_id) {

+ 1 - 0
modules/gdscript/language_server/gdscript_text_document.h

@@ -45,6 +45,7 @@ protected:
 	void didOpen(const Variant &p_param);
 	void didClose(const Variant &p_param);
 	void didChange(const Variant &p_param);
+	void willSaveWaitUntil(const Variant &p_param);
 	void didSave(const Variant &p_param);
 
 	void sync_script_content(const String &p_path, const String &p_content);

+ 1 - 1
modules/gdscript/language_server/godot_lsp.h

@@ -546,7 +546,7 @@ struct TextDocumentSyncOptions {
 	 * If present will save wait until requests are sent to the server. If omitted the request should not be
 	 * sent.
 	 */
-	bool willSaveWaitUntil = false;
+	bool willSaveWaitUntil = true;
 
 	/**
 	 * If present save notifications are sent to the server. If omitted the notification should not be