Skip to content

Commit 77e6d92

Browse files
committed
Fix highlighting warning and error issues related to Godot editor.
Fix Issue #104413 : Add a limit of 20 lines of warning highlight otherwise paint the background of the first line only. Fix Issue #106278 : Extract the logic from clearing and setting background lines from _update_errors() and _update_warnings() to _update_background_text(). Fix Issue #83979 : Added signal for folding/unfolding lines (fold_lines_updated). Feature: Highlight the folded line using signals connected to _update_background_text() to keep the editor visuals up to date. The background is set in the following priority order: Error, Warning, then Highlight background.
1 parent 428a762 commit 77e6d92

File tree

5 files changed

+109
-39
lines changed

5 files changed

+109
-39
lines changed

editor/plugins/script_text_editor.cpp

Lines changed: 49 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,50 @@ void ScriptTextEditor::_update_color_constructor_options() {
605605
}
606606
}
607607

608+
void ScriptTextEditor::_update_background_color() {
609+
// Clear background lines.
610+
CodeEdit *te = code_editor->get_text_editor();
611+
for (int i = 0; i < te->get_line_count(); i++) {
612+
bool is_folded_code_region = te->is_line_code_region_start(i) && te->is_line_folded(i);
613+
te->set_line_background_color(i, is_folded_code_region ? folded_code_region_color : Color(0, 0, 0, 0));
614+
}
615+
616+
// Set the warning background.
617+
if (warning_line_color.a != 0.0) {
618+
for (const ScriptLanguage::Warning &warning : warnings) {
619+
int folder_line_header = te->get_folded_line_header(warning.end_line - 2);
620+
bool is_folded = folder_line_header != (warning.end_line - 2);
621+
622+
if (is_folded) {
623+
te->set_line_background_color(folder_line_header, warning_line_color);
624+
} else if (warning.end_line - warning.start_line > 0 && warning.end_line - warning.start_line < 20) {
625+
// If the warning spans below 20 lines (arbitrary), set the background color for all lines.
626+
// (W.end_line - W.start_line > 0) ensures that we set the background for single line warnings.
627+
for (int i = warning.start_line - 1; i < warning.end_line - 1; i++) {
628+
te->set_line_background_color(i, warning_line_color);
629+
}
630+
} else {
631+
// Otherwise, just set the background color for the start line of the warning.
632+
te->set_line_background_color(warning.start_line - 1, warning_line_color);
633+
}
634+
}
635+
}
636+
637+
// Set the error background.
638+
if (marked_line_color.a != 0.0) {
639+
for (const ScriptLanguage::ScriptError &error : errors) {
640+
int folder_line_header = te->get_folded_line_header(error.line - 1);
641+
bool is_folded_code = folder_line_header != (error.line - 1);
642+
643+
if (is_folded_code) {
644+
te->set_line_background_color(folder_line_header, marked_line_color);
645+
} else {
646+
te->set_line_background_color(error.line - 1, marked_line_color);
647+
}
648+
}
649+
}
650+
}
651+
608652
void ScriptTextEditor::_update_color_text() {
609653
if (inline_color_line < 0) {
610654
return;
@@ -806,6 +850,7 @@ void ScriptTextEditor::_validate_script() {
806850
_update_connected_methods();
807851
_update_warnings();
808852
_update_errors();
853+
_update_background_color();
809854

810855
emit_signal(SNAME("name_changed"));
811856
emit_signal(SNAME("edited_script_changed"));
@@ -874,17 +919,6 @@ void ScriptTextEditor::_update_warnings() {
874919
warnings_panel->pop(); // Cell.
875920
}
876921
warnings_panel->pop(); // Table.
877-
if (warning_line_color.a != 0.0) {
878-
CodeEdit *te = code_editor->get_text_editor();
879-
for (int i = 0; i < te->get_line_count(); i++) {
880-
for (const ScriptLanguage::Warning &W : warnings) {
881-
if (i >= W.start_line - 1 && i < W.end_line) {
882-
te->set_line_background_color(i, warning_line_color);
883-
break;
884-
}
885-
}
886-
}
887-
}
888922
}
889923

890924
void ScriptTextEditor::_update_errors() {
@@ -947,23 +981,11 @@ void ScriptTextEditor::_update_errors() {
947981
errors_panel->pop(); // Indent.
948982
}
949983

950-
CodeEdit *te = code_editor->get_text_editor();
951984
bool highlight_safe = EDITOR_GET("text_editor/appearance/gutters/highlight_type_safe_lines");
952985
bool last_is_safe = false;
953-
for (int i = 0; i < te->get_line_count(); i++) {
954-
if (errors.is_empty()) {
955-
bool is_folded_code_region = te->is_line_code_region_start(i) && te->is_line_folded(i);
956-
te->set_line_background_color(i, is_folded_code_region ? folded_code_region_color : Color(0, 0, 0, 0));
957-
} else if (marked_line_color.a != 0) {
958-
for (const ScriptLanguage::ScriptError &E : errors) {
959-
bool error_line = i == E.line - 1;
960-
te->set_line_background_color(i, error_line ? marked_line_color : Color(0, 0, 0, 0));
961-
if (error_line) {
962-
break;
963-
}
964-
}
965-
}
986+
CodeEdit *te = code_editor->get_text_editor();
966987

988+
for (int i = 0; i < te->get_line_count(); i++) {
967989
if (highlight_safe) {
968990
if (safe_lines.has(i + 1)) {
969991
te->set_line_gutter_item_color(i, line_number_gutter, safe_line_number_color);
@@ -1731,11 +1753,9 @@ void ScriptTextEditor::_edit_option(int p_op) {
17311753
} break;
17321754
case EDIT_FOLD_ALL_LINES: {
17331755
tx->fold_all_lines();
1734-
tx->queue_redraw();
17351756
} break;
17361757
case EDIT_UNFOLD_ALL_LINES: {
17371758
tx->unfold_all_lines();
1738-
tx->queue_redraw();
17391759
} break;
17401760
case EDIT_CREATE_CODE_REGION: {
17411761
tx->create_code_region();
@@ -2037,6 +2057,7 @@ void ScriptTextEditor::_notification(int p_what) {
20372057
if (is_visible_in_tree()) {
20382058
_update_warnings();
20392059
_update_errors();
2060+
_update_background_color();
20402061
}
20412062
[[fallthrough]];
20422063
case NOTIFICATION_ENTER_TREE: {
@@ -2594,6 +2615,7 @@ void ScriptTextEditor::_enable_code_editor() {
25942615
code_editor->get_text_editor()->connect("gutter_added", callable_mp(this, &ScriptTextEditor::_update_gutter_indexes));
25952616
code_editor->get_text_editor()->connect("gutter_removed", callable_mp(this, &ScriptTextEditor::_update_gutter_indexes));
25962617
code_editor->get_text_editor()->connect("gutter_clicked", callable_mp(this, &ScriptTextEditor::_gutter_clicked));
2618+
code_editor->get_text_editor()->connect("_fold_line_updated", callable_mp(this, &ScriptTextEditor::_update_background_color));
25972619
code_editor->get_text_editor()->connect(SceneStringName(gui_input), callable_mp(this, &ScriptTextEditor::_text_edit_gui_input));
25982620
code_editor->show_toggle_files_button();
25992621
_update_gutter_indexes();

editor/plugins/script_text_editor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ class ScriptTextEditor : public ScriptEditorBase {
211211
String _picker_color_stringify(const Color &p_color, COLOR_MODE p_mode);
212212
void _picker_color_changed(const Color &p_color);
213213
void _update_color_constructor_options();
214+
void _update_background_color();
214215
void _update_color_text();
215216

216217
void _notification(int p_what);

editor/plugins/text_editor.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -410,11 +410,9 @@ void TextEditor::_edit_option(int p_op) {
410410
} break;
411411
case EDIT_FOLD_ALL_LINES: {
412412
tx->fold_all_lines();
413-
tx->queue_redraw();
414413
} break;
415414
case EDIT_UNFOLD_ALL_LINES: {
416415
tx->unfold_all_lines();
417-
tx->queue_redraw();
418416
} break;
419417
case EDIT_TRIM_TRAILING_WHITESAPCE: {
420418
trim_trailing_whitespace();

scene/gui/code_edit.cpp

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1672,10 +1672,10 @@ bool CodeEdit::can_fold_line(int p_line) const {
16721672
return false;
16731673
}
16741674

1675-
void CodeEdit::fold_line(int p_line) {
1676-
ERR_FAIL_INDEX(p_line, get_line_count());
1675+
bool CodeEdit::_fold_line(int p_line) {
1676+
ERR_FAIL_INDEX_V(p_line, get_line_count(), false);
16771677
if (!is_line_folding_enabled() || !can_fold_line(p_line)) {
1678-
return;
1678+
return false;
16791679
}
16801680

16811681
/* Find the last line to be hidden. */
@@ -1741,12 +1741,14 @@ void CodeEdit::fold_line(int p_line) {
17411741

17421742
// Collapse any carets in the hidden area.
17431743
collapse_carets(p_line, get_line(p_line).length(), end_line, get_line(end_line).length(), true);
1744+
1745+
return true;
17441746
}
17451747

1746-
void CodeEdit::unfold_line(int p_line) {
1747-
ERR_FAIL_INDEX(p_line, get_line_count());
1748+
bool CodeEdit::_unfold_line(int p_line) {
1749+
ERR_FAIL_INDEX_V(p_line, get_line_count(), false);
17481750
if (!is_line_folded(p_line) && !_is_line_hidden(p_line)) {
1749-
return;
1751+
return false;
17501752
}
17511753

17521754
int fold_start = p_line;
@@ -1766,18 +1768,47 @@ void CodeEdit::unfold_line(int p_line) {
17661768
set_line_background_color(i - 1, Color(0.0, 0.0, 0.0, 0.0));
17671769
}
17681770
}
1769-
queue_redraw();
1771+
return true;
17701772
}
17711773

17721774
void CodeEdit::fold_all_lines() {
1775+
bool any_line_folded = false;
1776+
17731777
for (int i = 0; i < get_line_count(); i++) {
1774-
fold_line(i);
1778+
any_line_folded |= _fold_line(i);
1779+
}
1780+
1781+
if (any_line_folded) {
1782+
emit_signal(SNAME("_fold_line_updated"));
1783+
}
1784+
}
1785+
1786+
void CodeEdit::fold_line(int p_line) {
1787+
bool line_folded = _fold_line(p_line);
1788+
1789+
if (line_folded) {
1790+
emit_signal(SNAME("_fold_line_updated"));
17751791
}
1776-
queue_redraw();
17771792
}
17781793

17791794
void CodeEdit::unfold_all_lines() {
1780-
_unhide_all_lines();
1795+
bool any_line_unfolded = false;
1796+
1797+
for (int i = 0; i < get_line_count(); i++) {
1798+
any_line_unfolded |= _unfold_line(i);
1799+
}
1800+
1801+
if (any_line_unfolded) {
1802+
emit_signal(SNAME("_fold_line_updated"));
1803+
}
1804+
}
1805+
1806+
void CodeEdit::unfold_line(int p_line) {
1807+
bool line_unfolded = _unfold_line(p_line);
1808+
1809+
if (line_unfolded) {
1810+
emit_signal(SNAME("_fold_line_updated"));
1811+
}
17811812
}
17821813

17831814
void CodeEdit::toggle_foldable_line(int p_line) {
@@ -1806,6 +1837,18 @@ void CodeEdit::toggle_foldable_lines_at_carets() {
18061837
end_multicaret_edit();
18071838
}
18081839

1840+
int CodeEdit::get_folded_line_header(int p_line) const {
1841+
ERR_FAIL_INDEX_V(p_line, get_line_count(), 0);
1842+
// Search for the first non hidden line.
1843+
while (p_line > 0) {
1844+
if (!_is_line_hidden(p_line)) {
1845+
break;
1846+
}
1847+
p_line--;
1848+
}
1849+
return p_line;
1850+
}
1851+
18091852
bool CodeEdit::is_line_folded(int p_line) const {
18101853
ERR_FAIL_INDEX_V(p_line, get_line_count(), false);
18111854
return p_line + 1 < get_line_count() && !_is_line_hidden(p_line) && _is_line_hidden(p_line + 1);
@@ -3820,6 +3863,9 @@ CodeEdit::CodeEdit() {
38203863
symbol_tooltip_timer->connect("timeout", callable_mp(this, &CodeEdit::_on_symbol_tooltip_timer_timeout));
38213864
add_child(symbol_tooltip_timer, false, INTERNAL_MODE_FRONT);
38223865

3866+
/* Fold Lines Private signal */
3867+
add_user_signal(MethodInfo("_fold_line_updated"));
3868+
38233869
connect("lines_edited_from", callable_mp(this, &CodeEdit::_lines_edited_from));
38243870
connect("text_set", callable_mp(this, &CodeEdit::_text_set));
38253871
connect(SceneStringName(text_changed), callable_mp(this, &CodeEdit::_text_changed));

scene/gui/code_edit.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ class CodeEdit : public TextEdit {
132132
String code_region_start_tag = "region";
133133
String code_region_end_tag = "endregion";
134134
void _update_code_region_tags();
135+
bool _fold_line(int p_line);
136+
bool _unfold_line(int p_line);
135137

136138
/* Delimiters */
137139
enum DelimiterType {
@@ -426,6 +428,7 @@ class CodeEdit : public TextEdit {
426428
void toggle_foldable_line(int p_line);
427429
void toggle_foldable_lines_at_carets();
428430

431+
int get_folded_line_header(int p_line) const;
429432
bool is_line_folded(int p_line) const;
430433
TypedArray<int> get_folded_lines() const;
431434

0 commit comments

Comments
 (0)