Skip to content

Commit 5cab29f

Browse files
committed
Godot addon: Add support for non-English characters
Fix #176
1 parent fd800d4 commit 5cab29f

File tree

1 file changed

+47
-13
lines changed

1 file changed

+47
-13
lines changed

addons/GDQuest_GDScript_formatter/plugin.gd

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -440,10 +440,37 @@ func format_code(script: GDScript, force_reorder := false) -> String:
440440
push_error("GDScript Formatter Error: Can't format an unsaved script.")
441441
return ""
442442

443-
var output: Array = []
444-
var error_output: Array = []
445-
var formatter_arguments := PackedStringArray(["--stdout"])
443+
# This is a bit of a hack to avoid two issues:
444+
#
445+
# 1. Running GDScript formatter on stdin/stdout through Godot with
446+
# OS.execute() has encoding issues with UTF-8 characters and we don't have
447+
# control over the output encoding (it might be assuming ASCII characters)
448+
#
449+
# 2. If we modify a file in place using the external formatter from Godot,
450+
# it will bring up a pop-up that warns users that the file has been changed
451+
# outside Godot.
452+
#
453+
# To work around that, I save a copy of the script as a temporary file,
454+
# format the file, and read it specifically as a UTF-8 string.
455+
var source_file := FileAccess.open(ProjectSettings.globalize_path(script_path), FileAccess.READ)
456+
if not source_file:
457+
push_error("GDScript Formatter Error: Cannot read source file: " + script_path)
458+
return ""
459+
460+
# FileAccess.get_as_text() reads the file as UTF-8. We use it here and after
461+
# formatting the temporary file.
462+
var source_content := source_file.get_as_text()
463+
source_file.close()
446464

465+
var path_temporary_file := OS.get_temp_dir().path_join("gdscript_formatter_%d.gd" % Time.get_ticks_msec())
466+
var temporary_file := FileAccess.open(path_temporary_file, FileAccess.WRITE)
467+
if temporary_file == null:
468+
push_error("GDScript Formatter Error: Cannot create temporary file: " + path_temporary_file)
469+
return ""
470+
temporary_file.store_string(source_content)
471+
temporary_file.close()
472+
473+
var formatter_arguments := PackedStringArray()
447474
if get_editor_setting(SETTING_USE_SPACES):
448475
formatter_arguments.push_back("--use-spaces")
449476
formatter_arguments.push_back("--indent-size=%d" % get_editor_setting(SETTING_INDENT_SIZE))
@@ -456,28 +483,35 @@ func format_code(script: GDScript, force_reorder := false) -> String:
456483
if get_editor_setting(SETTING_SAFE_MODE):
457484
formatter_arguments.push_back("--safe")
458485

459-
formatter_arguments.push_back(ProjectSettings.globalize_path(script_path))
486+
formatter_arguments.push_back(path_temporary_file)
460487

488+
var output: Array = []
461489
var exit_code := OS.execute(
462490
get_editor_setting(SETTING_FORMATTER_PATH),
463491
formatter_arguments,
464492
output,
465493
)
494+
495+
var formatted_content := ""
466496
if exit_code == OK:
467-
if output.is_empty():
468-
push_error("Format GDScript returned no output for: " + script_path)
469-
return ""
470-
return output.front()
497+
var result_file := FileAccess.open(path_temporary_file, FileAccess.READ)
498+
if result_file:
499+
formatted_content = result_file.get_as_text()
500+
result_file.close()
501+
else:
502+
push_error("Format GDScript: Cannot read formatted output from temp file")
471503
else:
472504
push_error("Format GDScript failed: " + script_path)
473505
push_error(
474-
"\tExit code: " + str(exit_code) + " Stdout: " +
475-
(output.front().strip_edges() if output.size() > 0 else "No output"),
506+
"\tExit code: " + str(exit_code) + " Output: " +
507+
(output[0].strip_edges() if output.size() > 0 else "No output"),
476508
)
477-
if error_output.size() > 0:
478-
push_error("\tStderr: " + error_output.front().strip_edges())
479509
push_error('\tIf your script does not have any syntax errors, this might be a formatter bug.')
480-
return ""
510+
511+
if FileAccess.file_exists(path_temporary_file):
512+
DirAccess.remove_absolute(path_temporary_file)
513+
514+
return formatted_content
481515

482516

483517
## Lints a GDScript file using the GDScript Formatter's linter,

0 commit comments

Comments
 (0)