Add script formatting plugin
Requires gdtoolkit to be installed on the system
This commit is contained in:
		
							parent
							
								
									3295e03343
								
							
						
					
					
						commit
						18a4b02c3e
					
				| 
						 | 
					@ -0,0 +1,21 @@
 | 
				
			||||||
 | 
					MIT License
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Copyright (c) 2023 Ryan Haskell-Glatz
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
 | 
					of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
 | 
					in the Software without restriction, including without limitation the rights
 | 
				
			||||||
 | 
					to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
				
			||||||
 | 
					copies of the Software, and to permit persons to whom the Software is
 | 
				
			||||||
 | 
					furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The above copyright notice and this permission notice shall be included in all
 | 
				
			||||||
 | 
					copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
				
			||||||
 | 
					AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
 | 
					LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
				
			||||||
 | 
					OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
				
			||||||
 | 
					SOFTWARE.
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,70 @@
 | 
				
			||||||
 | 
					@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)
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,6 @@
 | 
				
			||||||
 | 
					[plugin]
 | 
				
			||||||
 | 
					name="Format on Save"
 | 
				
			||||||
 | 
					description="Runs `gdformat` on save to automatically format your GD script as you code."
 | 
				
			||||||
 | 
					author="Ryan Haskell-Glatz"
 | 
				
			||||||
 | 
					version="1.2.0"
 | 
				
			||||||
 | 
					script="format_on_save.gd"
 | 
				
			||||||
| 
						 | 
					@ -29,7 +29,7 @@ project/assembly_name="Character Controller"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[editor_plugins]
 | 
					[editor_plugins]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enabled=PackedStringArray("res://addons/qodot/plugin.cfg")
 | 
					enabled=PackedStringArray("res://addons/format_on_save/plugin.cfg", "res://addons/qodot/plugin.cfg")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[input]
 | 
					[input]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue