Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added two options: set 1 line above functions, ignore '/' symbols in $node references #3

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,24 @@ A GDScript beautifier for [Godot Engine](https://github.com/godotengine/godot)
This addon is compatible with Godot 4.

## Features
GDBeautifier performs several cleaning tasks.
GDBeautifier performs several optional cleaning tasks.
* Removes spaces and tabs in empty lines
* Removes spaces at the end of lines
* Removes empty lines at the end of a script
* Adds spaces around operators
* Adds spaces around operators, with the option of ignoring '/' symbols in $node references †
* Adds a space after commas and colons
* Adds 2 empty lines before any function
* Adds 1 or 2 empty lines before any function

† $node references are assumed to start with $ and end with either . = : tab space or EOL

The addon ignores anything inside strings and comments.

## Installation
Add the addons folder to your project, and enable it in the plugins panel of the project settings.

## Usage
The beautifier panel is in the top left dock. It appears when the script editor is visible and a script is selected.
Select the desired options and click on beautify. The current script will be beautified.
The beautifier panel is in the top left dock. It appears when the script editor is visible and a script is selected.
Select the desired options and click on beautify. The current script will be beautified.
You can undo if you change your mind.

## Licence
Expand Down
90 changes: 76 additions & 14 deletions addons/GDBeautifier/beauty.gd
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ var source_lines: PackedStringArray
@onready var endOfScriptCheck = %EndOfScriptCheck
@onready var endOfLinesCheck = %EndOfLinesCheck
@onready var spacesOperatorsCheck = %SpacesOperatorsCheck
@onready var linesBeforeFuncCheck = %LinesBeforeFuncCheck
@onready var oneLineBeforeFuncCheck = %OneLineBeforeFuncCheck
@onready var twoLinesBeforeFuncCheck = %TwoLinesBeforeFuncCheck
@onready var ignoreNodes = %IgnoreNodes

## Array of regular expresessions used to beautify
@onready var cleaners: Array[Cleaner] = [
Expand Down Expand Up @@ -64,7 +66,9 @@ func _ready():
endOfLinesCheck.tooltip_text = endOfLinesCheck.text
endOfScriptCheck.tooltip_text = endOfScriptCheck.text
spacesOperatorsCheck.tooltip_text = spacesOperatorsCheck.text
linesBeforeFuncCheck.tooltip_text = linesBeforeFuncCheck.text
oneLineBeforeFuncCheck.tooltip_text = oneLineBeforeFuncCheck.text
twoLinesBeforeFuncCheck.tooltip_text = twoLinesBeforeFuncCheck.text
ignoreNodes.tooltip_text = ignoreNodes.text


## Sets the current script editor.
Expand All @@ -87,8 +91,10 @@ func _on_beautify_pressed():
source_lines = current_script.source_code.split("\n")
if spacesOperatorsCheck.button_pressed:
_apply_cleaners()
if linesBeforeFuncCheck.button_pressed:
_clean_func()
if oneLineBeforeFuncCheck.button_pressed:
_clean_func(1)
if twoLinesBeforeFuncCheck.button_pressed:
_clean_func(2)
if cleanEmptyLinesCheck.button_pressed:
_clean_empty_lines()
if endOfScriptCheck.button_pressed:
Expand All @@ -97,6 +103,16 @@ func _on_beautify_pressed():
_clean_end_of_lines()


func _on_ignore_nodes_toggled(button_pressed):
if button_pressed:
spacesOperatorsCheck.button_pressed = true


func _on_spaces_operators_check_toggled(button_pressed):
if not button_pressed:
ignoreNodes.button_pressed = false


func _on_end_of_lines_check_toggled(button_pressed):
if button_pressed:
cleanEmptyLinesCheck.button_pressed = true
Expand All @@ -107,6 +123,16 @@ func _on_clean_empty_lines_check_toggled(button_pressed):
endOfLinesCheck.button_pressed = false


func _on_one_line_before_func_check_toggled(button_pressed):
if button_pressed:
twoLinesBeforeFuncCheck.button_pressed = false


func _on_two_lines_before_func_check_toggled(button_pressed):
if button_pressed:
oneLineBeforeFuncCheck.button_pressed = false


func _on_toggle(button_pressed):
_save_preferences()

Expand All @@ -115,7 +141,9 @@ func _on_toggle(button_pressed):
func _save_preferences():
var config_file = ConfigFile.new()
config_file.set_value("prefs", "spacesOperatorsCheck", spacesOperatorsCheck.button_pressed)
config_file.set_value("prefs", "linesBeforeFuncCheck", linesBeforeFuncCheck.button_pressed)
config_file.set_value("prefs", "oneLineBeforeFuncCheck", oneLineBeforeFuncCheck.button_pressed)
config_file.set_value("prefs", "twoLinesBeforeFuncCheck", twoLinesBeforeFuncCheck.button_pressed)
config_file.set_value("prefs", "ignoreNodes", ignoreNodes.button_pressed)
config_file.set_value("prefs", "cleanEmptyLinesCheck", cleanEmptyLinesCheck.button_pressed)
config_file.set_value("prefs", "endOfScriptCheck", endOfScriptCheck.button_pressed)
config_file.set_value("prefs", "endOfLinesCheck", endOfLinesCheck.button_pressed)
Expand All @@ -129,7 +157,9 @@ func _load_preferences():
if err != OK:
return
spacesOperatorsCheck.button_pressed = config_file.get_value("prefs", "spacesOperatorsCheck", true)
linesBeforeFuncCheck.button_pressed = config_file.get_value("prefs", "linesBeforeFuncCheck", true)
oneLineBeforeFuncCheck.button_pressed = config_file.get_value("prefs", "oneLineBeforeFuncCheck", false)
twoLinesBeforeFuncCheck.button_pressed = config_file.get_value("prefs", "twoLinesBeforeFuncCheck", true)
ignoreNodes.button_pressed = config_file.get_value("prefs", "ignoreNodes", false)
cleanEmptyLinesCheck.button_pressed = config_file.get_value("prefs", "cleanEmptyLinesCheck", true)
endOfScriptCheck.button_pressed = config_file.get_value("prefs", "endOfScriptCheck", true)
endOfLinesCheck.button_pressed = config_file.get_value("prefs", "endOfLinesCheck", true)
Expand Down Expand Up @@ -162,13 +192,13 @@ func _clean_end_of_script():
_update_code()


## Checks that there are exactly two empty lines above functions (and above function comments).
func _clean_func():
## Checks that there are exactly num_lines empty lines above functions (and above function comments).
func _clean_func(num_lines):
#A any line
#F func
#C comment
#E empty
#expected result: EEC*F
#expected result: EC*F (1 line) or EEC*F (2 lines)

var func_index = -1
var i = source_lines.size()
Expand All @@ -181,14 +211,14 @@ func _clean_func():
if line.begins_with("#"):
func_index = i
elif not line.is_empty():
source_lines.insert(i + 1, "")
source_lines.insert(i + 1, "")
func_index += 2
elif i == func_index - 2:
for x in num_lines:
source_lines.insert(i + 1, "")
func_index += num_lines
elif i == func_index - num_lines:
if not line.is_empty():
source_lines.insert(i + 1, "")
func_index += 1
elif i == func_index - 3:
elif i == func_index - (num_lines + 1):
if line.is_empty():
source_lines.remove_at(i)
func_index -= 1
Expand Down Expand Up @@ -232,6 +262,12 @@ func _get_quote_ranges(line: String) -> Array:
var in_string = false
var start_pos = -1
var end_pos = -1

#added code to treat node references as quotes (ie $node/node)
var in_node = false
var node_start_pos = -1
var node_end_pos = -1

var i = 0
while i < line.length():
var char = line[i]
Expand All @@ -245,7 +281,33 @@ func _get_quote_ranges(line: String) -> Array:
in_string = false
elif in_string and char == "\\":
i += 1

#added code to treat node references as quotes
if ignoreNodes.button_pressed:
if not in_string:
if char == '$':
in_node = true
node_start_pos = i
if in_node:
#node reference can end with any of .=:\t or space
if char == '.' \
or char == '=' \
or char == ':' \
or char == '\t' \
or char == ' ':
node_end_pos = i
quote_ranges.append({"start": node_start_pos, "end": node_end_pos})
in_node = false
i += 1

#added code to treat node references as quotes
if ignoreNodes.button_pressed:
#if node reference is at EOL
if in_node:
node_end_pos = i - 1
quote_ranges.append({"start": node_start_pos, "end": node_end_pos})
in_node = false

return quote_ranges


Expand Down
33 changes: 29 additions & 4 deletions addons/GDBeautifier/beauty.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,43 @@ tooltip_text = "Add spaces around operators, after commas and colons"
button_pressed = true
text = "Add spaces around operators, after commas and colons"

[node name="LinesBeforeFuncCheck" type="CheckBox" parent="ScrollContainer/VBoxContainer"]
[node name="HBoxSpaces" type="HBoxContainer" parent="ScrollContainer/VBoxContainer"]
layout_mode = 2

[node name="Space" type="Control" parent="ScrollContainer/VBoxContainer/HBoxSpaces"]
custom_minimum_size = Vector2(20, 0)
layout_mode = 2

[node name="IgnoreNodes" type="CheckBox" parent="ScrollContainer/VBoxContainer/HBoxSpaces"]
unique_name_in_owner = true
layout_mode = 2
tooltip_text = "Ignore '/' symbols inside $node references (experimental)"
text = "Ignore '/' symbols inside $node references (experimental)"

[node name="OneLineBeforeFuncCheck" type="CheckBox" parent="ScrollContainer/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
tooltip_text = "Set 1 empty line before functions"
text = "Set 1 empty line before functions"

[node name="TwoLinesBeforeFuncCheck" type="CheckBox" parent="ScrollContainer/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
tooltip_text = "Set 2 empty lines before functions"
button_pressed = true
text = "Set 2 empty lines before functions"

[connection signal="pressed" from="Beautify" to="." method="_on_beautify_pressed"]
[connection signal="toggled" from="ScrollContainer/VBoxContainer/CleanEmptyLinesCheck" to="." method="_on_clean_empty_lines_check_toggled"]
[connection signal="toggled" from="ScrollContainer/VBoxContainer/CleanEmptyLinesCheck" to="." method="_on_toggle"]
[connection signal="toggled" from="ScrollContainer/VBoxContainer/HBoxEndOfLines/EndOfLinesCheck" to="." method="_on_end_of_lines_check_toggled"]
[connection signal="toggled" from="ScrollContainer/VBoxContainer/CleanEmptyLinesCheck" to="." method="_on_clean_empty_lines_check_toggled"]
[connection signal="toggled" from="ScrollContainer/VBoxContainer/HBoxEndOfLines/EndOfLinesCheck" to="." method="_on_toggle"]
[connection signal="toggled" from="ScrollContainer/VBoxContainer/HBoxEndOfLines/EndOfLinesCheck" to="." method="_on_end_of_lines_check_toggled"]
[connection signal="toggled" from="ScrollContainer/VBoxContainer/EndOfScriptCheck" to="." method="_on_toggle"]
[connection signal="toggled" from="ScrollContainer/VBoxContainer/SpacesOperatorsCheck" to="." method="_on_toggle"]
[connection signal="toggled" from="ScrollContainer/VBoxContainer/LinesBeforeFuncCheck" to="." method="_on_toggle"]
[connection signal="toggled" from="ScrollContainer/VBoxContainer/SpacesOperatorsCheck" to="." method="_on_spaces_operators_check_toggled"]
[connection signal="toggled" from="ScrollContainer/VBoxContainer/HBoxSpaces/IgnoreNodes" to="." method="_on_toggle"]
[connection signal="toggled" from="ScrollContainer/VBoxContainer/HBoxSpaces/IgnoreNodes" to="." method="_on_ignore_nodes_toggled"]
[connection signal="toggled" from="ScrollContainer/VBoxContainer/OneLineBeforeFuncCheck" to="." method="_on_toggle"]
[connection signal="toggled" from="ScrollContainer/VBoxContainer/OneLineBeforeFuncCheck" to="." method="_on_one_line_before_func_check_toggled"]
[connection signal="toggled" from="ScrollContainer/VBoxContainer/TwoLinesBeforeFuncCheck" to="." method="_on_toggle"]
[connection signal="toggled" from="ScrollContainer/VBoxContainer/TwoLinesBeforeFuncCheck" to="." method="_on_two_lines_before_func_check_toggled"]
4 changes: 3 additions & 1 deletion addons/GDBeautifier/prefs.cfg
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
[prefs]

spacesOperatorsCheck=true
linesBeforeFuncCheck=true
oneLineBeforeFuncCheck=false
twoLinesBeforeFuncCheck=true
ignoreNodes=false
cleanEmptyLinesCheck=true
endOfScriptCheck=true
endOfLinesCheck=true
Binary file modified assets/gd_beautifier_panel.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion project.godot
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ config_version=5

config/name="Beautify"
run/main_scene="res://main.tscn"
config/features=PackedStringArray("4.0", "GL Compatibility")
config/features=PackedStringArray("4.3", "GL Compatibility")
config/icon="res://icon.png"

[editor_plugins]
Expand Down
8 changes: 8 additions & 0 deletions tests/test.gd
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ func test(a:int, b : int, c, d, e, f, g) -> z :



if $node/test:
var node_test = $node/test
var node_text = $node/test.text
$node/test.text="node/test"
$node/test = "spaces"
$node/test = "tabs"


""".split("\n")


Expand Down
2 changes: 1 addition & 1 deletion tests/test.tscn
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[gd_scene load_steps=3 format=3]
[gd_scene load_steps=3 format=3 uid="uid://cfk7bu8woh2uw"]

[ext_resource type="Script" path="res://tests/test.gd" id="1_2eg6u"]
[ext_resource type="PackedScene" uid="uid://cms8wqnf0f5e0" path="res://addons/GDBeautifier/beauty.tscn" id="2_wdfjr"]
Expand Down