Skip to content

Commit c6dff41

Browse files
committed
Godot addon: fix formatting unsaved tab reverting code changes since last save
Fix #243
1 parent 8359c56 commit c6dff41

2 files changed

Lines changed: 29 additions & 18 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,12 @@ This file documents the changes made to the formatter with each release.
3030
- Fix `lint loop-variable-name` for unused variables (#225)
3131
- Fix `if` statement and comment line getting dedented in nested code blocks (#190)
3232
- Fix formatting with vs without `--reorder-code` not being idempotent in some situations (#207)
33-
- Fix Godot addon: "Uninstall Formatter" command doesn't exist (#189)
34-
- Fix Godot addon: Installing the binary formatter on Mac M1 with ARM installs wrong x86 binary (#248)
3533
- Fix code inside dedented region comments getting dedented too: region comments will now indent into the code (#172)
3634
- Fix dedented comment in a block's body (function body, loop body, if statement body...) causing following lines in the block to be dedented too (#252)
35+
- Godot addon fixes:
36+
- Fix formatter undoes any changes in script if they have not been saved (#243)
37+
- Fix "Uninstall Formatter" command doesn't exist message (#189)
38+
- Fix installing the binary formatter on Mac M1 with ARM installs wrong x86 binary (#248)
3739

3840

3941
## Release 0.20.1 (2026-05-26)

‎addons/GDQuest_GDScript_formatter/plugin.gd‎

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ func format_current_script() -> bool:
146146
return false
147147
var code_edit: CodeEdit = EditorInterface.get_script_editor().get_current_editor().get_base_editor()
148148

149-
var formatted_code := format_code(current_script)
149+
var formatted_code := format_code(current_script, false, code_edit.text)
150150
if formatted_code.is_empty():
151151
return false
152152

@@ -385,7 +385,7 @@ func reorder_code() -> bool:
385385
return false
386386
var code_edit: CodeEdit = EditorInterface.get_script_editor().get_current_editor().get_base_editor()
387387

388-
var formatted_code := format_code(current_script, true)
388+
var formatted_code := format_code(current_script, true, code_edit.text)
389389
if formatted_code.is_empty():
390390
return false
391391

@@ -465,14 +465,22 @@ func has_editor_setting(setting_name: String) -> bool:
465465
return editor_settings.has_setting(full_setting_key)
466466

467467

468-
## Formats a GDScript file using the GDScript Formatter,
469-
## and returns the formatted code as a string. Optionally reorders the code.
470-
func format_code(script: GDScript, force_reorder := false) -> String:
468+
## Formats GDScript code using the GDScript Formatter and returns it as a string.
469+
## When source_content is null, reads the code from the GDScript resource directly.
470+
## Otherwise, formats source_content without reading from the file.
471+
##
472+
## Pass a string through source_content when the user is editing the script in
473+
## the editor and requests formatting without having saved their changes (in
474+
## that case, the code they're editing only exists in the script editor's open
475+
## tab).
476+
func format_code(script: GDScript, force_reorder := false, source_content: Variant = null) -> String:
471477
var script_path := script.resource_path
472-
if script_path.is_empty():
478+
if source_content == null and script_path.is_empty():
473479
push_error("GDScript Formatter Error: Can't format an unsaved script.")
474480
return ""
475481

482+
# Source content is not set, read from the GDScript resource instead.
483+
#
476484
# This is a bit of a hack to avoid two issues:
477485
#
478486
# 1. Running GDScript formatter on stdin/stdout through Godot with
@@ -485,22 +493,23 @@ func format_code(script: GDScript, force_reorder := false) -> String:
485493
#
486494
# To work around that, I save a copy of the script as a temporary file,
487495
# format the file, and read it specifically as a UTF-8 string.
488-
var source_file := FileAccess.open(ProjectSettings.globalize_path(script_path), FileAccess.READ)
489-
if not source_file:
490-
push_error("GDScript Formatter Error: Cannot read source file: " + script_path)
491-
return ""
496+
if source_content == null:
497+
var source_file := FileAccess.open(ProjectSettings.globalize_path(script_path), FileAccess.READ)
498+
if not source_file:
499+
push_error("GDScript Formatter Error: Cannot read source file: " + script_path)
500+
return ""
492501

493-
# FileAccess.get_as_text() reads the file as UTF-8. We use it here and after
494-
# formatting the temporary file.
495-
var source_content := source_file.get_as_text()
496-
source_file.close()
502+
# FileAccess.get_as_text() reads the file as UTF-8. We use it here and after
503+
# formatting the temporary file.
504+
source_content = source_file.get_as_text()
505+
source_file.close()
497506

498507
var path_temporary_file := OS.get_temp_dir().path_join("gdscript_formatter_%d.gd" % Time.get_ticks_msec())
499508
var temporary_file := FileAccess.open(path_temporary_file, FileAccess.WRITE)
500509
if temporary_file == null:
501510
push_error("GDScript Formatter Error: Cannot create temporary file: " + path_temporary_file)
502511
return ""
503-
temporary_file.store_string(source_content)
512+
temporary_file.store_string(source_content as String)
504513
temporary_file.close()
505514

506515
var formatter_arguments := PackedStringArray()
@@ -534,7 +543,7 @@ func format_code(script: GDScript, force_reorder := false) -> String:
534543
else:
535544
push_error("Format GDScript: Cannot read formatted output from temp file")
536545
else:
537-
push_error("Format GDScript failed: " + script_path)
546+
push_error("Format GDScript failed: " + (script_path if not script_path.is_empty() else "unsaved script"))
538547
push_error(
539548
"\tExit code: " + str(exit_code) + " Output: " +
540549
(output[0].strip_edges() if output.size() > 0 else "No output"),

0 commit comments

Comments
 (0)