@tool class_name FormatOnSave extends EditorPlugin const SUCCESS: int = 0 const AUTO_RELOAD_SETTING: String = "text_editor/behavior/files/auto_reload_scripts_on_external_change" var original_auto_reload_setting: bool # LIFECYCLE EVENTS func _enter_tree(): activate_auto_reload_setting() resource_saved.connect(on_resource_saved) func _exit_tree(): resource_saved.disconnect(on_resource_saved) restore_original_auto_reload_setting() # CALLED WHEN A SCRIPT IS SAVED func on_resource_saved(resource: Resource): if resource is Script: var script: Script = resource var current_script = get_editor_interface().get_script_editor().get_current_script() var text_edit: CodeEdit = ( get_editor_interface().get_script_editor().get_current_editor().get_base_editor() ) # Prevents other unsaved scripts from overwriting the active one if current_script == script: var filepath: String = ProjectSettings.globalize_path(resource.resource_path) # Run gdformat var exit_code = OS.execute("gdformat", [filepath]) # Replace source_code with formatted source_code if exit_code == SUCCESS: var formatted_source = FileAccess.get_file_as_string(resource.resource_path) FormatOnSave.reload_script(text_edit, formatted_source) # Workaround until this PR is merged: # https://github.com/godotengine/godot/pull/83267 # Thanks, @KANAjetzt 💖 static func reload_script(text_edit: TextEdit, source_code: String) -> void: var column := text_edit.get_caret_column() var row := text_edit.get_caret_line() var scroll_position_h := text_edit.get_h_scroll_bar().value var scroll_position_v := text_edit.get_v_scroll_bar().value text_edit.text = source_code text_edit.set_caret_column(column) text_edit.set_caret_line(row) text_edit.scroll_horizontal = scroll_position_h text_edit.scroll_vertical = scroll_position_v text_edit.tag_saved_version() # For this workaround to work, we need to disable the "Reload/Resave" pop-up func activate_auto_reload_setting(): var settings := get_editor_interface().get_editor_settings() original_auto_reload_setting = settings.get(AUTO_RELOAD_SETTING) settings.set(AUTO_RELOAD_SETTING, true) # If the plugin is disabled, let's attempt to restore the original editor setting func restore_original_auto_reload_setting(): var settings := get_editor_interface().get_editor_settings() settings.set(AUTO_RELOAD_SETTING, original_auto_reload_setting)