Skip to content

Commit 838eb5a

Browse files
committed
Merge pull request godotengine#87099 from bitwise-aiden/ba-add-trim-newlines
Implement `trim_final_newlines` setting and functionality
2 parents ffad49f + b4c1634 commit 838eb5a

13 files changed

+99
-4
lines changed

doc/classes/EditorSettings.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,6 +1028,9 @@
10281028
<member name="text_editor/behavior/files/restore_scripts_on_load" type="bool" setter="" getter="">
10291029
If [code]true[/code], reopens scripts that were opened in the last session when the editor is reopened on a given project.
10301030
</member>
1031+
<member name="text_editor/behavior/files/trim_final_newlines_on_save" type="bool" setter="" getter="">
1032+
If [code]true[/code], trims all empty newlines after the final newline when saving a script. Final newlines refer to the empty newlines found at the end of files. Since these serve no practical purpose, they can and should be removed to make version control diffs less noisy.
1033+
</member>
10311034
<member name="text_editor/behavior/files/trim_trailing_whitespace_on_save" type="bool" setter="" getter="">
10321035
If [code]true[/code], trims trailing whitespace when saving a script. Trailing whitespace refers to tab and space characters placed at the end of lines. Since these serve no practical purpose, they can and should be removed to make version control diffs less noisy.
10331036
</member>

editor/code_editor.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1124,6 +1124,31 @@ void CodeTextEditor::trim_trailing_whitespace() {
11241124
}
11251125
}
11261126

1127+
void CodeTextEditor::trim_final_newlines() {
1128+
int final_line = text_editor->get_line_count() - 1;
1129+
int check_line = final_line;
1130+
1131+
String line = text_editor->get_line(check_line);
1132+
1133+
while (line.is_empty() && check_line > -1) {
1134+
--check_line;
1135+
1136+
line = text_editor->get_line(check_line);
1137+
}
1138+
1139+
++check_line;
1140+
1141+
if (check_line < final_line) {
1142+
text_editor->begin_complex_operation();
1143+
1144+
text_editor->remove_text(check_line, 0, final_line, 0);
1145+
1146+
text_editor->merge_overlapping_carets();
1147+
text_editor->end_complex_operation();
1148+
text_editor->queue_redraw();
1149+
}
1150+
}
1151+
11271152
void CodeTextEditor::insert_final_newline() {
11281153
int final_line = text_editor->get_line_count() - 1;
11291154
String line = text_editor->get_line(final_line);

editor/code_editor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ class CodeTextEditor : public VBoxContainer {
224224

225225
public:
226226
void trim_trailing_whitespace();
227+
void trim_final_newlines();
227228
void insert_final_newline();
228229

229230
enum CaseStyle {

editor/editor_settings.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
651651

652652
// Behavior: Files
653653
_initial_set("text_editor/behavior/files/trim_trailing_whitespace_on_save", false);
654+
_initial_set("text_editor/behavior/files/trim_final_newlines_on_save", true);
654655
_initial_set("text_editor/behavior/files/autosave_interval_secs", 0);
655656
_initial_set("text_editor/behavior/files/restore_scripts_on_load", true);
656657
_initial_set("text_editor/behavior/files/convert_indent_on_save", true);

editor/plugins/script_editor_plugin.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,6 +1008,10 @@ void ScriptEditor::_resave_scripts(const String &p_str) {
10081008
se->trim_trailing_whitespace();
10091009
}
10101010

1011+
if (trim_final_newlines_on_save) {
1012+
se->trim_final_newlines();
1013+
}
1014+
10111015
se->insert_final_newline();
10121016

10131017
if (convert_indent_on_save) {
@@ -1402,6 +1406,10 @@ void ScriptEditor::_menu_option(int p_option) {
14021406
current->trim_trailing_whitespace();
14031407
}
14041408

1409+
if (trim_final_newlines_on_save) {
1410+
current->trim_final_newlines();
1411+
}
1412+
14051413
current->insert_final_newline();
14061414

14071415
if (convert_indent_on_save) {
@@ -2602,6 +2610,10 @@ void ScriptEditor::save_current_script() {
26022610
current->trim_trailing_whitespace();
26032611
}
26042612

2613+
if (trim_final_newlines_on_save) {
2614+
current->trim_final_newlines();
2615+
}
2616+
26052617
current->insert_final_newline();
26062618

26072619
if (convert_indent_on_save) {
@@ -2646,6 +2658,10 @@ void ScriptEditor::save_all_scripts() {
26462658
se->trim_trailing_whitespace();
26472659
}
26482660

2661+
if (trim_final_newlines_on_save) {
2662+
se->trim_final_newlines();
2663+
}
2664+
26492665
se->insert_final_newline();
26502666

26512667
if (!se->is_unsaved()) {
@@ -2883,6 +2899,7 @@ void ScriptEditor::_apply_editor_settings() {
28832899
}
28842900

28852901
trim_trailing_whitespace_on_save = EDITOR_GET("text_editor/behavior/files/trim_trailing_whitespace_on_save");
2902+
trim_final_newlines_on_save = EDITOR_GET("text_editor/behavior/files/trim_final_newlines_on_save");
28862903
convert_indent_on_save = EDITOR_GET("text_editor/behavior/files/convert_indent_on_save");
28872904

28882905
members_overview_enabled = EDITOR_GET("text_editor/script_list/show_members_overview");
@@ -4307,6 +4324,7 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) {
43074324

43084325
edit_pass = 0;
43094326
trim_trailing_whitespace_on_save = EDITOR_GET("text_editor/behavior/files/trim_trailing_whitespace_on_save");
4327+
trim_final_newlines_on_save = EDITOR_GET("text_editor/behavior/files/trim_final_newlines_on_save");
43104328
convert_indent_on_save = EDITOR_GET("text_editor/behavior/files/convert_indent_on_save");
43114329

43124330
ScriptServer::edit_request_func = _open_script_request;

editor/plugins/script_editor_plugin.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ class ScriptEditorBase : public VBoxContainer {
174174
virtual void set_executing_line(int p_line) = 0;
175175
virtual void clear_executing_line() = 0;
176176
virtual void trim_trailing_whitespace() = 0;
177+
virtual void trim_final_newlines() = 0;
177178
virtual void insert_final_newline() = 0;
178179
virtual void convert_indent() = 0;
179180
virtual void ensure_focus() = 0;
@@ -408,6 +409,7 @@ class ScriptEditor : public PanelContainer {
408409

409410
bool open_textfile_after_create = true;
410411
bool trim_trailing_whitespace_on_save;
412+
bool trim_final_newlines_on_save;
411413
bool convert_indent_on_save;
412414
bool external_editor_active;
413415

editor/plugins/script_text_editor.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,10 @@ void ScriptTextEditor::trim_trailing_whitespace() {
431431
code_editor->trim_trailing_whitespace();
432432
}
433433

434+
void ScriptTextEditor::trim_final_newlines() {
435+
code_editor->trim_final_newlines();
436+
}
437+
434438
void ScriptTextEditor::insert_final_newline() {
435439
code_editor->insert_final_newline();
436440
}
@@ -1427,6 +1431,9 @@ void ScriptTextEditor::_edit_option(int p_op) {
14271431
case EDIT_TRIM_TRAILING_WHITESAPCE: {
14281432
trim_trailing_whitespace();
14291433
} break;
1434+
case EDIT_TRIM_FINAL_NEWLINES: {
1435+
trim_final_newlines();
1436+
} break;
14301437
case EDIT_CONVERT_INDENT_TO_SPACES: {
14311438
code_editor->set_indent_using_spaces(true);
14321439
convert_indent();
@@ -2300,6 +2307,7 @@ void ScriptTextEditor::_enable_code_editor() {
23002307
edit_menu->get_popup()->add_separator();
23012308
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("ui_text_completion_query"), EDIT_COMPLETE);
23022309
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/trim_trailing_whitespace"), EDIT_TRIM_TRAILING_WHITESAPCE);
2310+
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/trim_final_newlines"), EDIT_TRIM_FINAL_NEWLINES);
23032311
{
23042312
PopupMenu *sub_menu = memnew(PopupMenu);
23052313
sub_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_indent_to_spaces"), EDIT_CONVERT_INDENT_TO_SPACES);
@@ -2485,6 +2493,7 @@ void ScriptTextEditor::register_editor() {
24852493
ED_SHORTCUT("script_text_editor/evaluate_selection", TTR("Evaluate Selection"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::E);
24862494
ED_SHORTCUT("script_text_editor/toggle_word_wrap", TTR("Toggle Word Wrap"), KeyModifierMask::ALT | Key::Z);
24872495
ED_SHORTCUT("script_text_editor/trim_trailing_whitespace", TTR("Trim Trailing Whitespace"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::ALT | Key::T);
2496+
ED_SHORTCUT("script_text_editor/trim_final_newlines", TTR("Trim Final Newlines"), Key::NONE);
24882497
ED_SHORTCUT("script_text_editor/convert_indent_to_spaces", TTR("Convert Indent to Spaces"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::Y);
24892498
ED_SHORTCUT("script_text_editor/convert_indent_to_tabs", TTR("Convert Indent to Tabs"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::I);
24902499
ED_SHORTCUT("script_text_editor/auto_indent", TTR("Auto Indent"), KeyModifierMask::CMD_OR_CTRL | Key::I);

editor/plugins/script_text_editor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ class ScriptTextEditor : public ScriptEditorBase {
118118
EDIT_COMPLETE,
119119
EDIT_AUTO_INDENT,
120120
EDIT_TRIM_TRAILING_WHITESAPCE,
121+
EDIT_TRIM_FINAL_NEWLINES,
121122
EDIT_CONVERT_INDENT_TO_SPACES,
122123
EDIT_CONVERT_INDENT_TO_TABS,
123124
EDIT_TOGGLE_COMMENT,
@@ -228,6 +229,7 @@ class ScriptTextEditor : public ScriptEditorBase {
228229
virtual Variant get_navigation_state() override;
229230
virtual void ensure_focus() override;
230231
virtual void trim_trailing_whitespace() override;
232+
virtual void trim_final_newlines() override;
231233
virtual void insert_final_newline() override;
232234
virtual void convert_indent() override;
233235
virtual void tag_saved_version() override;

editor/plugins/shader_editor_plugin.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -436,8 +436,14 @@ void ShaderEditorPlugin::_menu_item_pressed(int p_index) {
436436
int index = shader_tabs->get_current_tab();
437437
ERR_FAIL_INDEX(index, shader_tabs->get_tab_count());
438438
TextShaderEditor *editor = edited_shaders[index].shader_editor;
439-
if (editor && editor->get_trim_trailing_whitespace_on_save()) {
440-
editor->trim_trailing_whitespace();
439+
if (editor) {
440+
if (editor->get_trim_trailing_whitespace_on_save()) {
441+
editor->trim_trailing_whitespace();
442+
}
443+
444+
if (editor->get_trim_final_newlines_on_save()) {
445+
editor->trim_final_newlines();
446+
}
441447
}
442448
if (edited_shaders[index].shader.is_valid()) {
443449
EditorNode::get_singleton()->save_resource(edited_shaders[index].shader);
@@ -452,8 +458,14 @@ void ShaderEditorPlugin::_menu_item_pressed(int p_index) {
452458
int index = shader_tabs->get_current_tab();
453459
ERR_FAIL_INDEX(index, shader_tabs->get_tab_count());
454460
TextShaderEditor *editor = edited_shaders[index].shader_editor;
455-
if (editor && editor->get_trim_trailing_whitespace_on_save()) {
456-
editor->trim_trailing_whitespace();
461+
if (editor) {
462+
if (editor->get_trim_trailing_whitespace_on_save()) {
463+
editor->trim_trailing_whitespace();
464+
}
465+
466+
if (editor->get_trim_final_newlines_on_save()) {
467+
editor->trim_final_newlines();
468+
}
457469
}
458470
String path;
459471
if (edited_shaders[index].shader.is_valid()) {

editor/plugins/text_editor.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,10 @@ void TextEditor::trim_trailing_whitespace() {
288288
code_editor->trim_trailing_whitespace();
289289
}
290290

291+
void TextEditor::trim_final_newlines() {
292+
code_editor->trim_final_newlines();
293+
}
294+
291295
void TextEditor::insert_final_newline() {
292296
code_editor->insert_final_newline();
293297
}
@@ -414,6 +418,9 @@ void TextEditor::_edit_option(int p_op) {
414418
case EDIT_TRIM_TRAILING_WHITESAPCE: {
415419
trim_trailing_whitespace();
416420
} break;
421+
case EDIT_TRIM_FINAL_NEWLINES: {
422+
trim_final_newlines();
423+
} break;
417424
case EDIT_CONVERT_INDENT_TO_SPACES: {
418425
code_editor->set_indent_using_spaces(true);
419426
convert_indent();
@@ -641,6 +648,7 @@ TextEditor::TextEditor() {
641648
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/duplicate_lines"), EDIT_DUPLICATE_LINES);
642649
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_word_wrap"), EDIT_TOGGLE_WORD_WRAP);
643650
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/trim_trailing_whitespace"), EDIT_TRIM_TRAILING_WHITESAPCE);
651+
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/trim_final_newlines"), EDIT_TRIM_FINAL_NEWLINES);
644652
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_indent_to_spaces"), EDIT_CONVERT_INDENT_TO_SPACES);
645653
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_indent_to_tabs"), EDIT_CONVERT_INDENT_TO_TABS);
646654

0 commit comments

Comments
 (0)