diff options
-rw-r--r-- | core/class_db.cpp | 23 | ||||
-rw-r--r-- | core/script_language.h | 2 | ||||
-rw-r--r-- | editor/code_editor.cpp | 6 | ||||
-rw-r--r-- | editor/code_editor.h | 2 | ||||
-rw-r--r-- | editor/plugins/script_text_editor.cpp | 8 | ||||
-rw-r--r-- | editor/plugins/script_text_editor.h | 4 | ||||
-rw-r--r-- | modules/gdnative/config.py | 2 | ||||
-rw-r--r-- | modules/gdscript/gd_editor.cpp | 141 | ||||
-rw-r--r-- | modules/gdscript/gd_parser.cpp | 18 | ||||
-rw-r--r-- | modules/gdscript/gd_parser.h | 1 | ||||
-rw-r--r-- | modules/gdscript/gd_script.h | 2 | ||||
-rw-r--r-- | modules/nativescript/config.py | 2 | ||||
-rw-r--r-- | scene/gui/text_edit.cpp | 16 | ||||
-rw-r--r-- | scene/gui/text_edit.h | 3 |
14 files changed, 195 insertions, 35 deletions
diff --git a/core/class_db.cpp b/core/class_db.cpp index ff31ea7b06..cd55219b53 100644 --- a/core/class_db.cpp +++ b/core/class_db.cpp @@ -598,14 +598,23 @@ void ClassDB::bind_integer_constant(const StringName &p_class, const StringName type->constant_map[p_name] = p_constant; #ifdef DEBUG_METHODS_ENABLED - List<StringName> *constants_list = type->enum_map.getptr(p_enum); - if (constants_list) { - constants_list->push_back(p_name); - } else { - List<StringName> new_list; - new_list.push_back(p_name); - type->enum_map[p_enum] = new_list; + String enum_name = p_enum; + if (enum_name!=String()) { + if (enum_name.find(".")!=-1) { + enum_name=enum_name.get_slicec('.',1); + } + + List<StringName> *constants_list = type->enum_map.getptr(enum_name); + + if (constants_list) { + constants_list->push_back(p_name); + } else { + List<StringName> new_list; + new_list.push_back(p_name); + type->enum_map[enum_name] = new_list; + } + } type->constant_order.push_back(p_name); diff --git a/core/script_language.h b/core/script_language.h index 7aba3ec0f1..5baf2e6f80 100644 --- a/core/script_language.h +++ b/core/script_language.h @@ -207,7 +207,7 @@ public: virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const = 0; virtual Error open_in_external_editor(const Ref<Script> &p_script, int p_line, int p_col) { return ERR_UNAVAILABLE; } - virtual Error complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, String &r_call_hint) { return ERR_UNAVAILABLE; } + virtual Error complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, bool &r_force, String &r_call_hint) { return ERR_UNAVAILABLE; } struct LookupResult { enum Type { diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index 4575bfcb08..d49b240c80 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -1036,8 +1036,9 @@ void CodeTextEditor::_complete_request() { List<String> entries; String ctext = text_editor->get_text_for_completion(); _code_complete_script(ctext, &entries); + bool forced = false; if (code_complete_func) { - code_complete_func(code_complete_ud, ctext, &entries); + code_complete_func(code_complete_ud, ctext, &entries, forced); } // print_line("COMPLETE: "+p_request); if (entries.size() == 0) @@ -1050,7 +1051,7 @@ void CodeTextEditor::_complete_request() { strs[i++] = E->get(); } - text_editor->code_complete(strs); + text_editor->code_complete(strs, forced); } void CodeTextEditor::_font_resize_timeout() { @@ -1267,6 +1268,7 @@ CodeTextEditor::CodeTextEditor() { cs.push_back("."); cs.push_back(","); cs.push_back("("); + cs.push_back("="); cs.push_back("$"); text_editor->set_completion(true, cs); idle->connect("timeout", this, "_text_changed_idle_timeout"); diff --git a/editor/code_editor.h b/editor/code_editor.h index 8d48c56503..e56d7f7fab 100644 --- a/editor/code_editor.h +++ b/editor/code_editor.h @@ -186,7 +186,7 @@ public: FindReplaceDialog(); }; -typedef void (*CodeTextEditorCodeCompleteFunc)(void *p_ud, const String &p_code, List<String> *r_options); +typedef void (*CodeTextEditorCodeCompleteFunc)(void *p_ud, const String &p_code, List<String> *r_options, bool &r_forced); class CodeTextEditor : public VBoxContainer { diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index e69fa6da88..e86ff8cac2 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -602,13 +602,13 @@ void ScriptEditor::_update_modified_scripts_for_external_editor(Ref<Script> p_fo } } -void ScriptTextEditor::_code_complete_scripts(void *p_ud, const String &p_code, List<String> *r_options) { +void ScriptTextEditor::_code_complete_scripts(void *p_ud, const String &p_code, List<String> *r_options, bool &r_force) { ScriptTextEditor *ste = (ScriptTextEditor *)p_ud; - ste->_code_complete_script(p_code, r_options); + ste->_code_complete_script(p_code, r_options, r_force); } -void ScriptTextEditor::_code_complete_script(const String &p_code, List<String> *r_options) { +void ScriptTextEditor::_code_complete_script(const String &p_code, List<String> *r_options, bool &r_force) { if (color_panel->is_visible_in_tree()) return; Node *base = get_tree()->get_edited_scene_root(); @@ -616,7 +616,7 @@ void ScriptTextEditor::_code_complete_script(const String &p_code, List<String> base = _find_node_for_script(base, base, script); } String hint; - Error err = script->get_language()->complete_code(p_code, script->get_path().get_base_dir(), base, r_options, hint); + Error err = script->get_language()->complete_code(p_code, script->get_path().get_base_dir(), base, r_options, r_force, hint); if (hint != "") { code_editor->get_text_edit()->set_code_hint(hint); } diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h index c505976223..561fa26c76 100644 --- a/editor/plugins/script_text_editor.h +++ b/editor/plugins/script_text_editor.h @@ -94,12 +94,12 @@ class ScriptTextEditor : public ScriptEditorBase { }; protected: - static void _code_complete_scripts(void *p_ud, const String &p_code, List<String> *r_options); + static void _code_complete_scripts(void *p_ud, const String &p_code, List<String> *r_options, bool &r_force); void _breakpoint_toggled(int p_row); //no longer virtual void _validate_script(); - void _code_complete_script(const String &p_code, List<String> *r_options); + void _code_complete_script(const String &p_code, List<String> *r_options, bool &r_force); void _load_theme_settings(); void _notification(int p_what); diff --git a/modules/gdnative/config.py b/modules/gdnative/config.py index 9f57b9bb74..4f89ca0d4c 100644 --- a/modules/gdnative/config.py +++ b/modules/gdnative/config.py @@ -1,7 +1,7 @@ def can_build(platform): - return True + return False def configure(env): diff --git a/modules/gdscript/gd_editor.cpp b/modules/gdscript/gd_editor.cpp index 524d561f0b..d6969c142d 100644 --- a/modules/gdscript/gd_editor.cpp +++ b/modules/gdscript/gd_editor.cpp @@ -30,6 +30,7 @@ #include "editor/editor_settings.h" #include "gd_compiler.h" #include "gd_script.h" +#include "global_constants.h" #include "os/file_access.h" #include "project_settings.h" #ifdef TOOLS_ENABLED @@ -355,6 +356,7 @@ String GDScriptLanguage::make_function(const String &p_class, const String &p_na struct GDCompletionIdentifier { + String enumeration; StringName obj_type; Ref<GDScript> script; Variant::Type type; @@ -608,7 +610,7 @@ static bool _guess_expression_type(GDCompletionContext &context, const GDParser: #ifdef TOOLS_ENABLED MethodBind *mb = ClassDB::get_method(base.obj_type, id); - PropertyInfo pi = mb->get_argument_info(-1); + PropertyInfo pi = mb->get_return_info(); //try calling the function if constant and all args are constant, should not crash.. Object *baseptr = base.value; @@ -809,6 +811,32 @@ static bool _guess_expression_type(GDCompletionContext &context, const GDParser: if (p1.value.get_type() == Variant::OBJECT) { //?? + if (p1.obj_type != StringName() && p2.type == Variant::STRING) { + StringName index = p2.value; + bool valid; + Variant::Type t = ClassDB::get_property_type(p1.obj_type, index, &valid); + if (t != Variant::NIL && valid) { + r_type.type = t; + if (t == Variant::INT) { +//check for enum! +#if defined(DEBUG_METHODS_ENABLED) && defined(TOOLS_ENABLED) + + StringName getter = ClassDB::get_property_getter(p1.obj_type, index); + if (getter != StringName()) { + MethodBind *mb = ClassDB::get_method(p1.obj_type, getter); + if (mb) { + PropertyInfo rt = mb->get_return_info(); + if (rt.usage & PROPERTY_USAGE_CLASS_IS_ENUM) { + r_type.enumeration = rt.class_name; + } + } + } +#endif + } + + return true; + } + } } else if (p1.value.get_type() != Variant::NIL) { bool valid; @@ -908,6 +936,22 @@ static bool _guess_identifier_type_in_block(GDCompletionContext &context, int p_ Variant::Type t = ClassDB::get_property_type(gdi.obj_type, p_identifier, &valid); if (t != Variant::NIL && valid) { r_type.type = t; + if (t == Variant::INT) { +//check for enum! +#if defined(DEBUG_METHODS_ENABLED) && defined(TOOLS_ENABLED) + + StringName getter = ClassDB::get_property_getter(gdi.obj_type, p_identifier); + if (getter != StringName()) { + MethodBind *mb = ClassDB::get_method(gdi.obj_type, getter); + if (mb) { + PropertyInfo rt = mb->get_return_info(); + if (rt.usage & PROPERTY_USAGE_CLASS_IS_ENUM) { + r_type.enumeration = rt.class_name; + } + } + } +#endif + } return true; } } @@ -1436,7 +1480,7 @@ void get_directory_contents(EditorFileSystemDirectory *p_dir, Set<String> &r_lis } } -static void _find_type_arguments(GDCompletionContext &context, const GDParser::Node *p_node, int p_line, const StringName &p_method, const GDCompletionIdentifier &id, int p_argidx, Set<String> &result, String &arghint) { +static void _find_type_arguments(GDCompletionContext &context, const GDParser::Node *p_node, int p_line, const StringName &p_method, const GDCompletionIdentifier &id, int p_argidx, Set<String> &result, bool &r_forced, String &arghint) { //print_line("find type arguments?"); if (id.type == Variant::OBJECT && id.obj_type != StringName()) { @@ -1642,8 +1686,43 @@ static void _find_type_arguments(GDCompletionContext &context, const GDParser::N } } else { - //regular method +//regular method + +#if defined(DEBUG_METHODS_ENABLED) && defined(TOOLS_ENABLED) + if (p_argidx < m->get_argument_count()) { + PropertyInfo pi = m->get_argument_info(p_argidx); + + if (pi.usage & PROPERTY_USAGE_CLASS_IS_ENUM) { + String enumeration = pi.class_name; + if (enumeration.find(".") != -1) { + //class constant + List<StringName> constants; + String cls = enumeration.get_slice(".", 0); + String enm = enumeration.get_slice(".", 1); + + ClassDB::get_enum_constants(cls, enm, &constants); + //constants.sort_custom<StringName::AlphCompare>(); + for (List<StringName>::Element *E = constants.front(); E; E = E->next()) { + String add = cls + "." + E->get(); + result.insert(add); + r_forced = true; + } + } else { + //global constant + StringName current_enum = enumeration; + + for (int i = 0; i < GlobalConstants::get_global_constant_count(); i++) { + if (GlobalConstants::get_global_constant_enum(i) == current_enum) { + result.insert(GlobalConstants::get_global_constant_name(i)); + r_forced = true; + } + } + //global + } + } + } +#endif if (p_method.operator String() == "connect" || (p_method.operator String() == "emit_signal" && p_argidx == 0)) { if (p_argidx == 0) { @@ -1664,6 +1743,7 @@ static void _find_type_arguments(GDCompletionContext &context, const GDParser::N for (List<MethodInfo>::Element *E = sigs.front(); E; E = E->next()) { result.insert("\"" + E->get().name + "\""); + r_forced = true; } } else if (p_argidx == 2) { @@ -1671,6 +1751,7 @@ static void _find_type_arguments(GDCompletionContext &context, const GDParser::N if (context._class) { for (int i = 0; i < context._class->functions.size(); i++) { result.insert("\"" + context._class->functions[i]->name + "\""); + r_forced = true; } } } @@ -1696,6 +1777,7 @@ static void _find_type_arguments(GDCompletionContext &context, const GDParser::N //print_line("found "+s); String name = s.get_slice("/", 1); result.insert("\"/root/" + name + "\""); + r_forced = true; } } @@ -1707,11 +1789,12 @@ static void _find_type_arguments(GDCompletionContext &context, const GDParser::N for (List<String>::Element *E = options.front(); E; E = E->next()) { result.insert(E->get()); + r_forced = true; } } } - arghint = _get_visual_datatype(m->get_argument_info(-1), false) + " " + p_method.operator String() + String("("); + arghint = _get_visual_datatype(m->get_return_info(), false) + " " + p_method.operator String() + String("("); for (int i = 0; i < m->get_argument_count(); i++) { if (i > 0) @@ -1750,7 +1833,7 @@ static void _find_type_arguments(GDCompletionContext &context, const GDParser::N } } -static void _find_call_arguments(GDCompletionContext &context, const GDParser::Node *p_node, int p_line, int p_argidx, Set<String> &result, String &arghint) { +static void _find_call_arguments(GDCompletionContext &context, const GDParser::Node *p_node, int p_line, int p_argidx, Set<String> &result, bool &r_forced, String &arghint) { if (!p_node || p_node->type != GDParser::Node::TYPE_OPERATOR) { @@ -1905,7 +1988,7 @@ static void _find_call_arguments(GDCompletionContext &context, const GDParser::N if (!context._class->owner) ci.value = context.base; - _find_type_arguments(context, p_node, p_line, id->name, ci, p_argidx, result, arghint); + _find_type_arguments(context, p_node, p_line, id->name, ci, p_argidx, result, r_forced, arghint); //guess type.. /* List<MethodInfo> methods; @@ -1927,7 +2010,7 @@ static void _find_call_arguments(GDCompletionContext &context, const GDParser::N GDCompletionIdentifier ci; if (_guess_expression_type(context, op->arguments[0], p_line, ci)) { - _find_type_arguments(context, p_node, p_line, id->name, ci, p_argidx, result, arghint); + _find_type_arguments(context, p_node, p_line, id->name, ci, p_argidx, result, r_forced, arghint); return; } } @@ -2027,14 +2110,14 @@ static void _find_call_arguments(GDCompletionContext &context, const GDParser::N #endif } -Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, String &r_call_hint) { +Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, bool &r_forced, String &r_call_hint) { GDParser p; p.parse(p_code, p_base_path, false, "", true); bool isfunction = false; Set<String> options; - + r_forced = false; GDCompletionContext context; context._class = p.get_completion_class(); context.block = p.get_completion_block(); @@ -2073,6 +2156,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base String opt = E->get().strip_edges(); if (opt.begins_with("\"") && opt.ends_with("\"")) { + r_forced = true; String idopt = opt.substr(1, opt.length() - 2); if (idopt.replace("/", "_").is_valid_identifier()) { options.insert(idopt); @@ -2297,7 +2381,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base } break; case GDParser::COMPLETION_CALL_ARGUMENTS: { - _find_call_arguments(context, p.get_completion_node(), p.get_completion_line(), p.get_completion_argument_index(), options, r_call_hint); + _find_call_arguments(context, p.get_completion_node(), p.get_completion_line(), p.get_completion_argument_index(), options, r_forced, r_call_hint); } break; case GDParser::COMPLETION_VIRTUAL_FUNC: { @@ -2344,6 +2428,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base ClassDB::get_signal_list(t.obj_type, &sigs); for (List<MethodInfo>::Element *E = sigs.front(); E; E = E->next()) { options.insert("\"" + E->get().name + "\""); + r_forced = true; } } @@ -2353,6 +2438,42 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base if (EditorSettings::get_singleton()->get("text_editor/completion/complete_file_paths")) get_directory_contents(EditorFileSystem::get_singleton()->get_filesystem(), options); } break; + case GDParser::COMPLETION_ASSIGN: { +#if defined(DEBUG_METHODS_ENABLED) && defined(TOOLS_ENABLED) + + GDCompletionIdentifier ci; + if (_guess_expression_type(context, p.get_completion_node(), p.get_completion_line(), ci)) { + + String enumeration = ci.enumeration; + if (enumeration.find(".") != -1) { + //class constant + List<StringName> constants; + String cls = enumeration.get_slice(".", 0); + String enm = enumeration.get_slice(".", 1); + + ClassDB::get_enum_constants(cls, enm, &constants); + //constants.sort_custom<StringName::AlphCompare>(); + for (List<StringName>::Element *E = constants.front(); E; E = E->next()) { + String add = cls + "." + E->get(); + r_options->push_back(add); + r_forced = true; + } + } else { + + //global constant + StringName current_enum = enumeration; + + for (int i = 0; i < GlobalConstants::get_global_constant_count(); i++) { + if (GlobalConstants::get_global_constant_enum(i) == current_enum) { + r_options->push_back(GlobalConstants::get_global_constant_name(i)); + r_forced = true; + } + } + //global + } + } +#endif + } break; } for (Set<String>::Element *E = options.front(); E; E = E->next()) { diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp index b349b6b9a8..de8daedb8b 100644 --- a/modules/gdscript/gd_parser.cpp +++ b/modules/gdscript/gd_parser.cpp @@ -1044,6 +1044,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool return NULL; \ } \ p_allow_assign = false; + switch (tokenizer->get_token()) { //see operator case GDTokenizer::TK_OP_IN: op = OperatorNode::OP_IN; break; @@ -1065,7 +1066,22 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool //case GDTokenizer::TK_OP_NEG: op=OperatorNode::OP_NEG ; break; case GDTokenizer::TK_OP_SHIFT_LEFT: op = OperatorNode::OP_SHIFT_LEFT; break; case GDTokenizer::TK_OP_SHIFT_RIGHT: op = OperatorNode::OP_SHIFT_RIGHT; break; - case GDTokenizer::TK_OP_ASSIGN: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN; break; + case GDTokenizer::TK_OP_ASSIGN: { + _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN; + + if (tokenizer->get_token(1) == GDTokenizer::TK_CURSOR) { + //code complete assignment + completion_type = COMPLETION_ASSIGN; + completion_node = expr; + completion_class = current_class; + completion_function = current_function; + completion_line = tokenizer->get_token_line(); + completion_block = current_block; + completion_found = true; + tokenizer->advance(); + } + + } break; case GDTokenizer::TK_OP_ASSIGN_ADD: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_ADD; break; case GDTokenizer::TK_OP_ASSIGN_SUB: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_SUB; break; case GDTokenizer::TK_OP_ASSIGN_MUL: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_MUL; break; diff --git a/modules/gdscript/gd_parser.h b/modules/gdscript/gd_parser.h index 3ad3466624..8ad494cd39 100644 --- a/modules/gdscript/gd_parser.h +++ b/modules/gdscript/gd_parser.h @@ -441,6 +441,7 @@ public: COMPLETION_INDEX, COMPLETION_VIRTUAL_FUNC, COMPLETION_YIELD, + COMPLETION_ASSIGN, }; private: diff --git a/modules/gdscript/gd_script.h b/modules/gdscript/gd_script.h index 17e7b0bc03..441f87474e 100644 --- a/modules/gdscript/gd_script.h +++ b/modules/gdscript/gd_script.h @@ -390,7 +390,7 @@ public: virtual int find_function(const String &p_function, const String &p_code) const; virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const; virtual Error open_in_external_editor(const Ref<Script> &p_script, int p_line, int p_col) { return OK; } - virtual Error complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, String &r_call_hint); + virtual Error complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, bool &r_forced, String &r_call_hint); #ifdef TOOLS_ENABLED virtual Error lookup_code(const String &p_code, const String &p_symbol, const String &p_base_path, Object *p_owner, LookupResult &r_result); #endif diff --git a/modules/nativescript/config.py b/modules/nativescript/config.py index 9f57b9bb74..4f89ca0d4c 100644 --- a/modules/nativescript/config.py +++ b/modules/nativescript/config.py @@ -1,7 +1,7 @@ def can_build(platform): - return True + return False def configure(env): diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 245e7e04be..2c50b4e854 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -4319,6 +4319,7 @@ void TextEdit::_cancel_completion() { return; completion_active = false; + completion_forced = false; update(); } @@ -4386,13 +4387,19 @@ void TextEdit::_update_completion_candidates() { } } - if (cursor.column > 0 && l[cursor.column - 1] == '(' && !pre_keyword && !completion_strings[0].begins_with("\"")) { + if (cursor.column > 0 && l[cursor.column - 1] == '(' && !pre_keyword && !completion_forced) { cancel = true; } update(); - if (cancel || (!pre_keyword && s == "" && (cofs == 0 || !completion_prefixes.has(String::chr(l[cofs - 1]))))) { + bool prev_is_prefix = false; + if (cofs > 0 && completion_prefixes.has(String::chr(l[cofs - 1]))) + prev_is_prefix = true; + if (cofs > 1 && l[cofs - 1] == ' ' && completion_prefixes.has(String::chr(l[cofs - 2]))) //check with one space before prefix, to allow indent + prev_is_prefix = true; + + if (cancel || (!pre_keyword && s == "" && (cofs == 0 || !prev_is_prefix))) { //none to complete, cancel _cancel_completion(); return; @@ -4481,6 +4488,8 @@ void TextEdit::query_code_comple() { if (ofs > 0 && (inquote || _is_completable(l[ofs - 1]) || completion_prefixes.has(String::chr(l[ofs - 1])))) emit_signal("request_completion"); + else if (ofs > 1 && l[ofs - 1] == ' ' && completion_prefixes.has(String::chr(l[ofs - 2]))) //make it work with a space too, it's good enough + emit_signal("request_completion"); } void TextEdit::set_code_hint(const String &p_hint) { @@ -4492,12 +4501,13 @@ void TextEdit::set_code_hint(const String &p_hint) { update(); } -void TextEdit::code_complete(const Vector<String> &p_strings) { +void TextEdit::code_complete(const Vector<String> &p_strings, bool p_forced) { VisualServer::get_singleton()->canvas_item_set_z(get_canvas_item(), 1); raised_from_completion = true; completion_strings = p_strings; completion_active = true; + completion_forced = p_forced; completion_current = ""; completion_index = 0; _update_completion_candidates(); diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index 6321cad2da..7ab26322e7 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -205,6 +205,7 @@ class TextEdit : public Control { Vector<String> completion_strings; Vector<String> completion_options; bool completion_active; + bool completion_forced; String completion_current; String completion_base; int completion_index; @@ -522,7 +523,7 @@ public: void set_tooltip_request_func(Object *p_obj, const StringName &p_function, const Variant &p_udata); void set_completion(bool p_enabled, const Vector<String> &p_prefixes); - void code_complete(const Vector<String> &p_strings); + void code_complete(const Vector<String> &p_strings, bool p_forced = false); void set_code_hint(const String &p_hint); void query_code_comple(); |