Skip to content
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
1 change: 1 addition & 0 deletions core/object/script_language.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +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_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
1 change: 1 addition & 0 deletions core/object/script_language_extension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +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_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
10 changes: 10 additions & 0 deletions core/object/script_language_extension.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,16 @@ class ScriptLanguageExtension : public ScriptLanguage {
}
}

GDVIRTUAL0RC(Vector<String>, _get_block_key_delimiters)

virtual void get_block_key_delimiters(List<String> *p_words) const override {
Vector<String> ret;
GDVIRTUAL_CALL(_get_block_key_delimiters, ret);
for (const String &delimiter : ret) {
p_words->push_back(delimiter);
}
}

GDVIRTUAL0RC_REQUIRED(Vector<String>, _get_string_delimiters)

virtual void get_string_delimiters(List<String> *p_words) const override {
Expand Down
5 changes: 5 additions & 0 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 Down
11 changes: 11 additions & 0 deletions editor/plugins/script_text_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,17 @@ 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);

Vector<String> block_key_delimiters_vector;

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

text_edit->set_block_key_delimiters(block_key_delimiters_vector);
}

void ScriptTextEditor::_show_errors_panel(bool p_show) {
Expand Down
1 change: 1 addition & 0 deletions modules/gdscript/gdscript.h
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +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_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
4 changes: 4 additions & 0 deletions modules/gdscript/gdscript_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ void GDScriptLanguage::get_doc_comment_delimiters(List<String> *p_delimiters) co
p_delimiters->push_back("##");
}

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

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

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

void CSharpLanguage::get_string_delimiters(List<String> *p_delimiters) const {
p_delimiters->push_back("' '"); // character literal
p_delimiters->push_back("\" \""); // regular string literal
Expand Down
1 change: 1 addition & 0 deletions modules/mono/csharp_script.h
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +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_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
84 changes: 84 additions & 0 deletions scene/gui/code_edit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1192,12 +1192,84 @@ 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();
}

void CodeEdit::_auto_fill_doc_comments(int p_caret, bool p_above) {
if (block_key_delimiters.is_empty()) {
return;
}

const int cl = p_above ? (get_caret_line(p_caret) + 1) : (get_caret_line(p_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 + " ", p_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 + " ", p_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, p_caret);
set_caret_column(line_length, false, p_caret);
break;
}

insert_text_at_caret(delimiter_begin + " ", p_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 + " ", p_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 + " ", p_caret);
break;
}
}
}
}
}

/* Auto brace completion */
void CodeEdit::set_auto_brace_completion_enabled(bool p_enabled) {
auto_brace_completion_enabled = p_enabled;
Expand Down Expand Up @@ -2054,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 Vector<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
7 changes: 7 additions & 0 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 p_caret, bool p_above);

/* 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 @@ -311,6 +314,7 @@ class CodeEdit : public TextEdit {
void _text_changed();

void _apply_project_settings();
Vector<Callable> new_lines_actions;

protected:
void _notification(int p_what);
Expand Down Expand Up @@ -465,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 Vector<String> &p_delimiters);

/* Code hint */
void set_code_hint(const String &p_hint);
void set_code_hint_draw_below(bool p_below);
Expand Down