Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Move behavior into CodeEdit
  • Loading branch information
Cronos87 committed Dec 23, 2024
commit 84545f95a7962e607937de0d9d114617830d3e7c
2 changes: 1 addition & 1 deletion core/object/script_language.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ class ScriptLanguage : public Object {
virtual bool is_control_flow_keyword(const String &p_string) const = 0;
virtual void get_comment_delimiters(List<String> *p_delimiters) const = 0;
virtual void get_doc_comment_delimiters(List<String> *p_delimiters) const = 0;
virtual void get_doc_comment_block_delimiters(List<HashMap<String, String>> *p_delimiters) const = 0;
virtual void get_block_key_delimiters(List<String> *p_delimiters) const = 0;
virtual void get_string_delimiters(List<String> *p_delimiters) const = 0;
virtual Ref<Script> make_template(const String &p_template, const String &p_class_name, const String &p_base_class_name) const { return Ref<Script>(); }
virtual Vector<ScriptTemplate> get_built_in_templates(const StringName &p_object) { return Vector<ScriptTemplate>(); }
Expand Down
2 changes: 1 addition & 1 deletion core/object/script_language_extension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ void ScriptLanguageExtension::_bind_methods() {
GDVIRTUAL_BIND(_is_control_flow_keyword, "keyword");
GDVIRTUAL_BIND(_get_comment_delimiters);
GDVIRTUAL_BIND(_get_doc_comment_delimiters);
GDVIRTUAL_BIND(_get_doc_comment_block_delimiters);
GDVIRTUAL_BIND(_get_block_key_delimiters);
GDVIRTUAL_BIND(_get_string_delimiters);
GDVIRTUAL_BIND(_make_template, "template", "class_name", "base_class_name");
GDVIRTUAL_BIND(_get_built_in_templates, "object");
Expand Down
12 changes: 4 additions & 8 deletions core/object/script_language_extension.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,17 +271,13 @@ class ScriptLanguageExtension : public ScriptLanguage {
}
}

GDVIRTUAL0RC(Vector<String>, _get_doc_comment_block_delimiters)
GDVIRTUAL0RC(Vector<String>, _get_block_key_delimiters)

virtual void get_doc_comment_block_delimiters(List<HashMap<String, String>> *p_words) const override {
virtual void get_block_key_delimiters(List<String> *p_words) const override {
Vector<String> ret;
GDVIRTUAL_CALL(_get_doc_comment_block_delimiters, ret);
GDVIRTUAL_CALL(_get_block_key_delimiters, ret);
for (const String &delimiter : ret) {
HashMap<String, String> word;
word["delimiter_begin"] = delimiter;
word["delimiter_block"] = "";
word["delimiter_end"] = "";
p_words->push_back(word);
p_words->push_back(delimiter);
}
}

Expand Down
10 changes: 5 additions & 5 deletions doc/classes/ScriptLanguageExtension.xml
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,11 @@
<description>
</description>
</method>
<method name="_get_block_key_delimiters" qualifiers="virtual const">
<return type="PackedStringArray" />
<description>
</description>
</method>
<method name="_get_built_in_templates" qualifiers="virtual const">
<return type="Dictionary[]" />
<param index="0" name="object" type="StringName" />
Expand All @@ -153,11 +158,6 @@
<description>
</description>
</method>
<method name="_get_doc_comment_block_delimiters" qualifiers="virtual const">
<return type="PackedStringArray" />
<description>
</description>
</method>
<method name="_get_doc_comment_delimiters" qualifiers="virtual const">
<return type="PackedStringArray" />
<description>
Expand Down
106 changes: 5 additions & 101 deletions editor/plugins/script_text_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,11 @@ void ScriptTextEditor::_set_theme_for_script() {
text_edit->add_auto_brace_completion_pair(beg, end);
}
}

List<String> block_key_delimiters;
script->get_language()->get_block_key_delimiters(&block_key_delimiters);

text_edit->set_block_key_delimiters(&block_key_delimiters);
}

void ScriptTextEditor::_show_errors_panel(bool p_show) {
Expand Down Expand Up @@ -1420,107 +1425,6 @@ void ScriptTextEditor::_gutter_clicked(int p_line, int p_gutter) {
}
}

void ScriptTextEditor::_auto_fill_doc_comments(bool p_above) {
CodeEdit *tx = code_editor->get_text_editor();

if (tx->get_comment_delimiters().is_empty()) {
return;
}

List<HashMap<String, String>> doc_comments_block;
script->get_language()->get_doc_comment_block_delimiters(&doc_comments_block);

// Store the operations to apply, as complex operations need to be used only if comments are added.
List<Vector<Variant>> operations;

for (int i = 0; i < tx->get_caret_count(); i++) {
if (tx->multicaret_edit_ignore_caret(i)) {
continue;
}

const int cl = p_above ? (tx->get_caret_line(i) + 1) : (tx->get_caret_line(i) - 1);
const String line = tx->get_line(cl);

if (tx->is_in_comment(cl) != -1) {
for (const HashMap<String, String> &doc_comment_block : doc_comments_block) {
const String delimiter_begin = doc_comment_block["delimiter_begin"];
const String delimiter_block = doc_comment_block["delimiter_block"];
const String delimiter_end = doc_comment_block["delimiter_end"];
const bool is_inline_delimiter = delimiter_end.is_empty();
String line_strip = line.strip_edges();

// Case for inline comments.
if (is_inline_delimiter) {
if (line_strip.begins_with(delimiter_begin)) {
operations.push_back({ i, delimiter_begin });
break;
}

continue;
}

// Case when the caret is on the same line as a block comment.
if (!p_above && line_strip.begins_with(delimiter_begin)) {
const String next_line = tx->get_line(cl + 1);

if (next_line.ends_with(delimiter_end.strip_edges())) {
const int non_whitespace_column = tx->get_first_non_whitespace_column(cl);
const String indent = line.substr(0, non_whitespace_column);

operations.push_back({ i, vformat("%s \n%s", delimiter_block, indent), cl + 1 });
break;
}

operations.push_back({ i, delimiter_block });
break;
}

// Case when the caret is on the same line as the end delimiter.
if (p_above && line_strip.ends_with(delimiter_end)) {
operations.push_back({ i, delimiter_block });
break;
}

// Case when the caret is in a block comment; needs to go up to
// find the beginning of the current doc comment.
for (int j = cl - 1; j >= 0; --j) {
line_strip = tx->get_line(j).strip_edges();

if (tx->is_in_comment(j) == -1) {
break;
}

if (line_strip.begins_with(delimiter_begin)) {
operations.push_back({ i, delimiter_block });
break;
}
}
}
}
}

if (!operations.is_empty()) {
tx->begin_complex_operation();

for (const Vector<Variant> &op : operations) {
const int caret = op[0];
const String delimiter = op[1].operator String();

tx->insert_text_at_caret(delimiter + " ", caret);

if (op.size() == 3) {
const int line_to_move_on = op[2];
const int line_length = tx->get_line(line_to_move_on).length();
tx->set_caret_line(line_to_move_on, false, true, -1, caret);
tx->set_caret_column(line_length, false, caret);
}
}

tx->merge_overlapping_carets();
tx->end_complex_operation();
}
}

void ScriptTextEditor::_edit_option(int p_op) {
CodeEdit *tx = code_editor->get_text_editor();
tx->apply_ime();
Expand Down
2 changes: 0 additions & 2 deletions editor/plugins/script_text_editor.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,6 @@ class ScriptTextEditor : public ScriptEditorBase {
Color folded_code_region_color = Color(1, 1, 1);
int previous_line = 0;

void _auto_fill_doc_comments(bool p_above);

PopupPanel *color_panel = nullptr;
ColorPicker *color_picker = nullptr;
Vector2 color_position;
Expand Down
2 changes: 1 addition & 1 deletion modules/gdscript/gdscript.h
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,7 @@ class GDScriptLanguage : public ScriptLanguage {
virtual bool is_control_flow_keyword(const String &p_keywords) const override;
virtual void get_comment_delimiters(List<String> *p_delimiters) const override;
virtual void get_doc_comment_delimiters(List<String> *p_delimiters) const override;
virtual void get_doc_comment_block_delimiters(List<HashMap<String, String>> *p_delimiters) const override;
virtual void get_block_key_delimiters(List<String> *p_delimiters) const override;
virtual void get_string_delimiters(List<String> *p_delimiters) const override;
virtual bool is_using_templates() override;
virtual Ref<Script> make_template(const String &p_template, const String &p_class_name, const String &p_base_class_name) const override;
Expand Down
10 changes: 3 additions & 7 deletions modules/gdscript/gdscript_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,9 @@ void GDScriptLanguage::get_doc_comment_delimiters(List<String> *p_delimiters) co
p_delimiters->push_back("##");
}

void GDScriptLanguage::get_doc_comment_block_delimiters(List<HashMap<String, String>> *p_delimiters) const {
HashMap<String, String> first;
first["delimiter_begin"] = "##";
first["delimiter_block"] = "";
first["delimiter_end"] = "";

p_delimiters->push_back(first);
void GDScriptLanguage::get_block_key_delimiters(List<String> *p_delimiters) const {
p_delimiters->push_back("##");
p_delimiters->push_back("#");
}

void GDScriptLanguage::get_string_delimiters(List<String> *p_delimiters) const {
Expand Down
17 changes: 4 additions & 13 deletions modules/mono/csharp_script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,19 +341,10 @@ void CSharpLanguage::get_doc_comment_delimiters(List<String> *p_delimiters) cons
p_delimiters->push_back("/** */"); // delimited doc comment
}

void CSharpLanguage::get_doc_comment_block_delimiters(List<HashMap<String, String>> *p_delimiters) const {
HashMap<String, String> first;
first["delimiter_begin"] = "///";
first["delimiter_block"] = "";
first["delimiter_end"] = "";

HashMap<String, String> second;
second["delimiter_begin"] = "/**";
second["delimiter_block"] = " *";
second["delimiter_end"] = "*/";

p_delimiters->push_back(first);
p_delimiters->push_back(second);
void CSharpLanguage::get_block_key_delimiters(List<String> *p_delimiters) const {
p_delimiters->push_back("///");
p_delimiters->push_back("//");
p_delimiters->push_back("/**| *|*/");
}

void CSharpLanguage::get_string_delimiters(List<String> *p_delimiters) const {
Expand Down
2 changes: 1 addition & 1 deletion modules/mono/csharp_script.h
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ class CSharpLanguage : public ScriptLanguage {
bool is_control_flow_keyword(const String &p_keyword) const override;
void get_comment_delimiters(List<String> *p_delimiters) const override;
void get_doc_comment_delimiters(List<String> *p_delimiters) const override;
void get_doc_comment_block_delimiters(List<HashMap<String, String>> *p_delimiters) const override;
void get_block_key_delimiters(List<String> *p_delimiters) const override;
void get_string_delimiters(List<String> *p_delimiters) const override;
bool is_using_templates() override;
virtual Ref<Script> make_template(const String &p_template, const String &p_class_name, const String &p_base_class_name) const override;
Expand Down
88 changes: 81 additions & 7 deletions scene/gui/code_edit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1192,20 +1192,82 @@ void CodeEdit::_new_line(bool p_split_current_line, bool p_above) {
set_caret_line(get_caret_line(i) - 1, false, true, 0, i);
set_caret_column(get_line(get_caret_line(i)).length(), i == 0, i);
}

_auto_fill_doc_comments(i, p_above);
}

end_multicaret_edit();
end_complex_operation();
}

if (new_lines_actions.size() > 0) {
for (Callable &action : new_lines_actions) {
action.call_deferred(p_above);
}
void CodeEdit::_auto_fill_doc_comments(int caret, bool p_above) {
if (block_key_delimiters.is_empty()) {
return;
}
}

void CodeEdit::add_new_line_actions(const Callable &p_action) {
new_lines_actions.push_back(p_action);
const int cl = p_above ? (get_caret_line(caret) + 1) : (get_caret_line(caret) - 1);
const String line = get_line(cl);

if (is_in_comment(cl) != -1) {
for (const String &block_key : block_key_delimiters) {
const String delimiter_begin = block_key.get_slice("|", 0);
const String delimiter_block = block_key.get_slice("|", 1);
const String delimiter_end = block_key.get_slice("|", 2);
String line_strip = line.strip_edges();

// Case for inline comments.
if (delimiter_begin == delimiter_end) {
if (line_strip.begins_with(delimiter_begin)) {
insert_text_at_caret(delimiter_begin + " ", caret);
break;
}

continue;
}

// Case when the caret is on the same line as a block comment.
if (!p_above && line_strip.begins_with(delimiter_begin)) {
const String next_line = get_line(cl + 1);

if (next_line.ends_with(delimiter_end.strip_edges())) {
const int non_whitespace_column = get_first_non_whitespace_column(cl);
const String indent = line.substr(0, non_whitespace_column);

insert_text_at_caret(delimiter_begin + " ", caret);

const int line_to_move_on = cl + 1;
const int line_length = get_line(line_to_move_on).length();
set_caret_line(line_to_move_on, false, true, -1, caret);
set_caret_column(line_length, false, caret);
break;
}

insert_text_at_caret(delimiter_begin + " ", caret);
break;
}

// Case when the caret is on the same line as the end delimiter.
if (p_above && line_strip.ends_with(delimiter_end)) {
insert_text_at_caret(delimiter_begin + " ", caret);
break;
}

// Case when the caret is in a block comment; needs to go up to
// find the beginning of the current doc comment.
for (int j = cl - 1; j >= 0; --j) {
line_strip = get_line(j).strip_edges();

if (is_in_comment(j) == -1) {
break;
}

if (line_strip.begins_with(delimiter_begin)) {
insert_text_at_caret(delimiter_begin + " ", caret);
break;
}
}
}
}
}

/* Auto brace completion */
Expand Down Expand Up @@ -2064,6 +2126,18 @@ Point2 CodeEdit::get_delimiter_end_position(int p_line, int p_column) const {
return end_position;
}

Vector<String> CodeEdit::get_block_key_delimiters() const {
return block_key_delimiters;
}

void CodeEdit::set_block_key_delimiters(const List<String> *p_delimiters) {
block_key_delimiters.clear();

for (const String &delimiter : *p_delimiters) {
block_key_delimiters.push_back(delimiter);
}
}

/* Code hint */
void CodeEdit::set_code_hint(const String &p_hint) {
if (code_hint == p_hint) {
Expand Down
8 changes: 6 additions & 2 deletions scene/gui/code_edit.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ class CodeEdit : public TextEdit {
int _calculate_spaces_till_next_right_indent(int p_column) const;

void _new_line(bool p_split_current_line = true, bool p_above = false);
void _auto_fill_doc_comments(int caret, bool p_above);
Comment thread
Mickeon marked this conversation as resolved.
Outdated

/* Auto brace completion */
bool auto_brace_completion_enabled = false;
Expand Down Expand Up @@ -185,6 +186,8 @@ class CodeEdit : public TextEdit {
*/
Vector<RBMap<int, int>> delimiter_cache;

Vector<String> block_key_delimiters;

void _update_delimiter_cache(int p_from_line = 0, int p_to_line = -1);
int _is_in_delimiter(int p_line, int p_column, DelimiterType p_type) const;

Expand Down Expand Up @@ -466,6 +469,9 @@ class CodeEdit : public TextEdit {
Point2 get_delimiter_start_position(int p_line, int p_column) const;
Point2 get_delimiter_end_position(int p_line, int p_column) const;

Vector<String> get_block_key_delimiters() const;
void set_block_key_delimiters(const List<String> *p_delimiters);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
void set_block_key_delimiters(const List<String> *p_delimiters);
void set_block_key_delimiters(const List<String> &p_delimiters);

No reason to pass it as a pointer unless it's optional, in that case it needs a null check

But this should really use Vector<String> IMO, it transfers to a Vector anyway so there's going to be a conversion anyway, so I'd say:

Suggested change
void set_block_key_delimiters(const List<String> *p_delimiters);
void set_block_key_delimiters(const Vector<String> &p_delimiters);

Copy link
Copy Markdown
Author

@Cronos87 Cronos87 Nov 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if it is viable to convert it to a Vector, as the API requires a List from the key delimiters. So I need to convert it to a Vector and then pass it to the method. It seems to complicate it a little bit. What do you think?

See the update here: https://github.com/godotengine/godot/pull/95955/files#diff-fa2cafb4b2d8b59e5baeba0b861f7f2f6bf6c213d6387254fee5a7682478e588R264-R273


/* Code hint */
void set_code_hint(const String &p_hint);
void set_code_hint_draw_below(bool p_below);
Expand Down Expand Up @@ -517,8 +523,6 @@ class CodeEdit : public TextEdit {
void duplicate_selection();
void duplicate_lines();

void add_new_line_actions(const Callable &p_action);

CodeEdit();
~CodeEdit();
};
Expand Down