diff options
| -rw-r--r-- | core/script_language.h | 30 | ||||
| -rw-r--r-- | editor/code_editor.cpp | 15 | ||||
| -rw-r--r-- | editor/code_editor.h | 4 | ||||
| -rw-r--r-- | editor/plugins/script_text_editor.cpp | 4 | ||||
| -rw-r--r-- | editor/plugins/script_text_editor.h | 6 | ||||
| -rw-r--r-- | modules/gdnative/pluginscript/pluginscript_language.cpp | 5 | ||||
| -rw-r--r-- | modules/gdnative/pluginscript/pluginscript_language.h | 2 | ||||
| -rw-r--r-- | modules/gdscript/gdscript.h | 2 | ||||
| -rw-r--r-- | modules/gdscript/gdscript_editor.cpp | 219 | 
9 files changed, 194 insertions, 93 deletions
| diff --git a/core/script_language.h b/core/script_language.h index b0c60b4e90..cb103646ed 100644 --- a/core/script_language.h +++ b/core/script_language.h @@ -200,6 +200,34 @@ public:  	virtual ~ScriptInstance();  }; +struct ScriptCodeCompletionOption { +	enum Kind { +		KIND_CLASS, +		KIND_FUNCTION, +		KIND_SIGNAL, +		KIND_VARIABLE, +		KIND_MEMBER, +		KIND_ENUM, +		KIND_CONSTANT, +		KIND_NODE_PATH, +		KIND_FILE_PATH, +		KIND_PLAIN_TEXT, +	}; +	Kind kind; +	String display; +	String insert_text; + +	ScriptCodeCompletionOption() { +		kind = KIND_PLAIN_TEXT; +	} + +	ScriptCodeCompletionOption(const String &p_text, Kind p_kind) { +		display = p_text; +		insert_text = p_text; +		kind = p_kind; +	} +}; +  class ScriptCodeCompletionCache {  	static ScriptCodeCompletionCache *singleton; @@ -250,7 +278,7 @@ public:  	virtual Error open_in_external_editor(const Ref<Script> &p_script, int p_line, int p_col) { return ERR_UNAVAILABLE; }  	virtual bool overrides_external_editor() { return false; } -	virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<String> *r_options, bool &r_force, String &r_call_hint) { return ERR_UNAVAILABLE; } +	virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<ScriptCodeCompletionOption> *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 ed50c7914e..d5aae7b562 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -724,7 +724,7 @@ void CodeTextEditor::_code_complete_timer_timeout() {  void CodeTextEditor::_complete_request() { -	List<String> entries; +	List<ScriptCodeCompletionOption> entries;  	String ctext = text_editor->get_text_for_completion();  	_code_complete_script(ctext, &entries);  	bool forced = false; @@ -733,15 +733,16 @@ void CodeTextEditor::_complete_request() {  	}  	if (entries.size() == 0)  		return; -	Vector<String> strs; -	strs.resize(entries.size()); -	int i = 0; -	for (List<String>::Element *E = entries.front(); E; E = E->next()) { -		strs.write[i++] = E->get(); +	Vector<String> options; +	options.resize(entries.size()); +	size_t i = 0; +	for (List<ScriptCodeCompletionOption>::Element *E = entries.front(); E; E = E->next()) { +		options.write[i] = E->get().insert_text; +		i++;  	} -	text_editor->code_complete(strs, forced); +	text_editor->code_complete(options, forced);  }  void CodeTextEditor::_font_resize_timeout() { diff --git a/editor/code_editor.h b/editor/code_editor.h index c0989f9704..2653a8cecc 100644 --- a/editor/code_editor.h +++ b/editor/code_editor.h @@ -131,7 +131,7 @@ public:  	FindReplaceBar();  }; -typedef void (*CodeTextEditorCodeCompleteFunc)(void *p_ud, const String &p_code, List<String> *r_options, bool &r_forced); +typedef void (*CodeTextEditorCodeCompleteFunc)(void *p_ud, const String &p_code, List<ScriptCodeCompletionOption> *r_options, bool &r_forced);  class CodeTextEditor : public VBoxContainer { @@ -183,7 +183,7 @@ class CodeTextEditor : public VBoxContainer {  protected:  	virtual void _load_theme_settings() {}  	virtual void _validate_script() {} -	virtual void _code_complete_script(const String &p_code, List<String> *r_options) {} +	virtual void _code_complete_script(const String &p_code, List<ScriptCodeCompletionOption> *r_options) {}  	void _text_changed_idle_timeout();  	void _code_complete_timer_timeout(); diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 2cfa759e3b..438621115b 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -773,13 +773,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, bool &r_force) { +void ScriptTextEditor::_code_complete_scripts(void *p_ud, const String &p_code, List<ScriptCodeCompletionOption> *r_options, bool &r_force) {  	ScriptTextEditor *ste = (ScriptTextEditor *)p_ud;  	ste->_code_complete_script(p_code, r_options, r_force);  } -void ScriptTextEditor::_code_complete_script(const String &p_code, List<String> *r_options, bool &r_force) { +void ScriptTextEditor::_code_complete_script(const String &p_code, List<ScriptCodeCompletionOption> *r_options, bool &r_force) {  	if (color_panel->is_visible_in_tree()) return;  	Node *base = get_tree()->get_edited_scene_root(); diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h index b53383b117..9a2a514a6e 100644 --- a/editor/plugins/script_text_editor.h +++ b/editor/plugins/script_text_editor.h @@ -143,7 +143,6 @@ class ScriptTextEditor : public ScriptEditorBase {  	};  protected: -	static void _code_complete_scripts(void *p_ud, const String &p_code, List<String> *r_options, bool &r_force);  	void _update_breakpoint_list();  	void _breakpoint_item_pressed(int p_idx);  	void _breakpoint_toggled(int p_row); @@ -151,7 +150,10 @@ protected:  	void _validate_script(); // No longer virtual.  	void _update_bookmark_list();  	void _bookmark_item_pressed(int p_idx); -	void _code_complete_script(const String &p_code, List<String> *r_options, bool &r_force); + +	static void _code_complete_scripts(void *p_ud, const String &p_code, List<ScriptCodeCompletionOption> *r_options, bool &r_force); +	void _code_complete_script(const String &p_code, List<ScriptCodeCompletionOption> *r_options, bool &r_force); +  	void _load_theme_settings();  	void _set_theme_for_script();  	void _show_warnings_panel(bool p_show); diff --git a/modules/gdnative/pluginscript/pluginscript_language.cpp b/modules/gdnative/pluginscript/pluginscript_language.cpp index 4bbadc62e7..9de073fc8e 100644 --- a/modules/gdnative/pluginscript/pluginscript_language.cpp +++ b/modules/gdnative/pluginscript/pluginscript_language.cpp @@ -159,7 +159,7 @@ String PluginScriptLanguage::make_function(const String &p_class, const String &  	return String();  } -Error PluginScriptLanguage::complete_code(const String &p_code, const String &p_path, Object *p_owner, List<String> *r_options, bool &r_force, String &r_call_hint) { +Error PluginScriptLanguage::complete_code(const String &p_code, const String &p_path, Object *p_owner, List<ScriptCodeCompletionOption> *r_options, bool &r_force, String &r_call_hint) {  	if (_desc.complete_code) {  		Array options;  		godot_error tmp = _desc.complete_code( @@ -171,7 +171,8 @@ Error PluginScriptLanguage::complete_code(const String &p_code, const String &p_  				&r_force,  				(godot_string *)&r_call_hint);  		for (int i = 0; i < options.size(); i++) { -			r_options->push_back(String(options[i])); +			ScriptCodeCompletionOption option(options[i], ScriptCodeCompletionOption::KIND_PLAIN_TEXT); +			r_options->push_back(option);  		}  		return (Error)tmp;  	} diff --git a/modules/gdnative/pluginscript/pluginscript_language.h b/modules/gdnative/pluginscript/pluginscript_language.h index a11e916975..7b3844d0b0 100644 --- a/modules/gdnative/pluginscript/pluginscript_language.h +++ b/modules/gdnative/pluginscript/pluginscript_language.h @@ -81,7 +81,7 @@ public:  	virtual bool can_inherit_from_file() { return true; }  	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 complete_code(const String &p_code, const String &p_path, Object *p_owner, List<String> *r_options, bool &r_force, String &r_call_hint); +	virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<ScriptCodeCompletionOption> *r_options, bool &r_force, String &r_call_hint);  	virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const;  	virtual void add_global_constant(const StringName &p_variable, const Variant &p_value); diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 1756f6eabc..a5ad23c75d 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -458,7 +458,7 @@ public:  	virtual bool can_inherit_from_file() { return true; }  	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 complete_code(const String &p_code, const String &p_path, Object *p_owner, List<String> *r_options, bool &r_forced, String &r_call_hint); +	virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<ScriptCodeCompletionOption> *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_path, Object *p_owner, LookupResult &r_result);  #endif diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 26b14a6148..78a1bfc99b 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -509,12 +509,14 @@ struct GDScriptCompletionIdentifier {  			assigned_expression(NULL) {}  }; -static void _get_directory_contents(EditorFileSystemDirectory *p_dir, Set<String> &r_list) { +static void _get_directory_contents(EditorFileSystemDirectory *p_dir, Map<String, ScriptCodeCompletionOption> &r_list) {  	const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\"";  	for (int i = 0; i < p_dir->get_file_count(); i++) { -		r_list.insert(quote_style + p_dir->get_file_path(i) + quote_style); +		ScriptCodeCompletionOption option(p_dir->get_file_path(i), ScriptCodeCompletionOption::KIND_FILE_PATH); +		option.insert_text = quote_style + option.display + quote_style; +		r_list.insert(option.display, option);  	}  	for (int i = 0; i < p_dir->get_subdir_count(); i++) { @@ -1807,14 +1809,15 @@ static String _make_arguments_hint(const GDScriptParser::FunctionNode *p_functio  	return arghint;  } -static void _find_enumeration_candidates(const String p_enum_hint, Set<String> &r_result) { +static void _find_enumeration_candidates(const String p_enum_hint, Map<String, ScriptCodeCompletionOption> &r_result) {  	if (p_enum_hint.find(".") == -1) {  		// Global constant  		StringName current_enum = p_enum_hint;  		for (int i = 0; i < GlobalConstants::get_global_constant_count(); i++) {  			if (GlobalConstants::get_global_constant_enum(i) == current_enum) { -				r_result.insert(GlobalConstants::get_global_constant_name(i)); +				ScriptCodeCompletionOption option(GlobalConstants::get_global_constant_name(i), ScriptCodeCompletionOption::KIND_ENUM); +				r_result.insert(option.display, option);  			}  		}  	} else { @@ -1829,15 +1832,17 @@ static void _find_enumeration_candidates(const String p_enum_hint, Set<String> &  		ClassDB::get_enum_constants(class_name, enum_name, &enum_constants);  		for (List<StringName>::Element *E = enum_constants.front(); E; E = E->next()) {  			String candidate = class_name + "." + E->get(); -			r_result.insert(candidate); +			ScriptCodeCompletionOption option(candidate, ScriptCodeCompletionOption::KIND_ENUM); +			r_result.insert(option.display, option);  		}  	}  } -static void _find_identifiers_in_block(const GDScriptCompletionContext &p_context, Set<String> &r_result) { +static void _find_identifiers_in_block(const GDScriptCompletionContext &p_context, Map<String, ScriptCodeCompletionOption> &r_result) {  	for (Map<StringName, GDScriptParser::LocalVarNode *>::Element *E = p_context.block->variables.front(); E; E = E->next()) {  		if (E->get()->line < p_context.line) { -			r_result.insert(E->key().operator String()); +			ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_VARIABLE); +			r_result.insert(option.display, option);  		}  	}  	if (p_context.block->parent_block) { @@ -1847,40 +1852,47 @@ static void _find_identifiers_in_block(const GDScriptCompletionContext &p_contex  	}  } -static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, bool p_only_functions, Set<String> &r_result); +static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, bool p_only_functions, Map<String, ScriptCodeCompletionOption> &r_result); -static void _find_identifiers_in_class(const GDScriptCompletionContext &p_context, bool p_static, bool p_only_functions, bool p_parent_only, Set<String> &r_result) { +static void _find_identifiers_in_class(const GDScriptCompletionContext &p_context, bool p_static, bool p_only_functions, bool p_parent_only, Map<String, ScriptCodeCompletionOption> &r_result) {  	if (!p_parent_only) {  		if (!p_static && !p_only_functions) {  			for (int i = 0; i < p_context._class->variables.size(); i++) { -				r_result.insert(p_context._class->variables[i].identifier); +				ScriptCodeCompletionOption option(p_context._class->variables[i].identifier, ScriptCodeCompletionOption::KIND_MEMBER); +				r_result.insert(option.display, option);  			}  		}  		if (!p_only_functions) {  			for (Map<StringName, GDScriptParser::ClassNode::Constant>::Element *E = p_context._class->constant_expressions.front(); E; E = E->next()) { -				r_result.insert(E->key()); +				ScriptCodeCompletionOption option(E->key(), ScriptCodeCompletionOption::KIND_CONSTANT); +				r_result.insert(option.display, option);  			}  			for (int i = 0; i < p_context._class->subclasses.size(); i++) { -				r_result.insert(p_context._class->subclasses[i]->name); +				ScriptCodeCompletionOption option(p_context._class->subclasses[i]->name, ScriptCodeCompletionOption::KIND_CLASS); +				r_result.insert(option.display, option);  			}  		}  		for (int i = 0; i < p_context._class->static_functions.size(); i++) { +			ScriptCodeCompletionOption option(p_context._class->static_functions[i]->name.operator String(), ScriptCodeCompletionOption::KIND_FUNCTION);  			if (p_context._class->static_functions[i]->arguments.size()) { -				r_result.insert(p_context._class->static_functions[i]->name.operator String() + "("); +				option.insert_text += "(";  			} else { -				r_result.insert(p_context._class->static_functions[i]->name.operator String() + "()"); +				option.insert_text += "()";  			} +			r_result.insert(option.display, option);  		}  		if (!p_static) {  			for (int i = 0; i < p_context._class->functions.size(); i++) { +				ScriptCodeCompletionOption option(p_context._class->functions[i]->name.operator String(), ScriptCodeCompletionOption::KIND_FUNCTION);  				if (p_context._class->functions[i]->arguments.size()) { -					r_result.insert(p_context._class->functions[i]->name.operator String() + "("); +					option.insert_text += "(";  				} else { -					r_result.insert(p_context._class->functions[i]->name.operator String() + "()"); +					option.insert_text += "()";  				} +				r_result.insert(option.display, option);  			}  		}  	} @@ -1898,12 +1910,14 @@ static void _find_identifiers_in_class(const GDScriptCompletionContext &p_contex  	_find_identifiers_in_base(c, base_type, p_only_functions, r_result);  } -static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, bool p_only_functions, Set<String> &r_result) { +static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, bool p_only_functions, Map<String, ScriptCodeCompletionOption> &r_result) {  	GDScriptParser::DataType base_type = p_base.type;  	bool _static = base_type.is_meta_type;  	if (_static && base_type.kind != GDScriptParser::DataType::BUILTIN) { -		r_result.insert("new("); +		ScriptCodeCompletionOption option("new", ScriptCodeCompletionOption::KIND_FUNCTION); +		option.insert_text += "("; +		r_result.insert(option.display, option);  	}  	while (base_type.has_type) { @@ -1921,26 +1935,31 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context  				if (script.is_valid()) {  					if (!_static && !p_only_functions) {  						for (const Set<StringName>::Element *E = script->get_members().front(); E; E = E->next()) { -							r_result.insert(E->get().operator String()); +							ScriptCodeCompletionOption option(E->get().operator String(), ScriptCodeCompletionOption::KIND_MEMBER); +							r_result.insert(option.display, option);  						}  					}  					if (!p_only_functions) {  						for (const Map<StringName, Variant>::Element *E = script->get_constants().front(); E; E = E->next()) { -							r_result.insert(E->key().operator String()); +							ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CONSTANT); +							r_result.insert(option.display, option);  						}  					}  					for (const Map<StringName, GDScriptFunction *>::Element *E = script->get_member_functions().front(); E; E = E->next()) {  						if (!_static || E->get()->is_static()) { +							ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_FUNCTION);  							if (E->get()->get_argument_count()) { -								r_result.insert(E->key().operator String() + "("); +								option.insert_text += "(";  							} else { -								r_result.insert(E->key().operator String() + "()"); +								option.insert_text += "()";  							} +							r_result.insert(option.display, option);  						}  					}  					if (!p_only_functions) {  						for (const Map<StringName, Ref<GDScript> >::Element *E = script->get_subclasses().front(); E; E = E->next()) { -							r_result.insert(E->key().operator String()); +							ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CLASS); +							r_result.insert(option.display, option);  						}  					}  					base_type = GDScriptParser::DataType(); @@ -1964,25 +1983,29 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context  						List<PropertyInfo> members;  						scr->get_script_property_list(&members);  						for (List<PropertyInfo>::Element *E = members.front(); E; E = E->next()) { -							r_result.insert(E->get().name); +							ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_MEMBER); +							r_result.insert(option.display, option);  						}  					}  					if (!p_only_functions) {  						Map<StringName, Variant> constants;  						scr->get_constants(&constants);  						for (Map<StringName, Variant>::Element *E = constants.front(); E; E = E->next()) { -							r_result.insert(E->key().operator String()); +							ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CONSTANT); +							r_result.insert(option.display, option);  						}  					}  					List<MethodInfo> methods;  					scr->get_script_method_list(&methods);  					for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) { +						ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_FUNCTION);  						if (E->get().arguments.size()) { -							r_result.insert(E->get().name + "("); +							option.insert_text += "(";  						} else { -							r_result.insert(E->get().name + "()"); +							option.insert_text += "()";  						} +						r_result.insert(option.display, option);  					}  					Ref<Script> base_script = scr->get_base_script(); @@ -2009,7 +2032,8 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context  					List<String> constants;  					ClassDB::get_integer_constant_list(type, &constants);  					for (List<String>::Element *E = constants.front(); E; E = E->next()) { -						r_result.insert(E->get()); +						ScriptCodeCompletionOption option(E->get(), ScriptCodeCompletionOption::KIND_CONSTANT); +						r_result.insert(option.display, option);  					}  					if (!_static) { @@ -2022,7 +2046,8 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context  							if (E->get().name.find("/") != -1) {  								continue;  							} -							r_result.insert(E->get().name); +							ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_MEMBER); +							r_result.insert(option.display, option);  						}  					}  				} @@ -2035,11 +2060,13 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context  						if (E->get().name.begins_with("_")) {  							continue;  						} +						ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_FUNCTION);  						if (E->get().arguments.size()) { -							r_result.insert(E->get().name + "("); +							option.insert_text += "(";  						} else { -							r_result.insert(E->get().name + "()"); +							option.insert_text += "()";  						} +						r_result.insert(option.display, option);  					}  				} @@ -2058,7 +2085,8 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context  					for (List<PropertyInfo>::Element *E = members.front(); E; E = E->next()) {  						if (String(E->get().name).find("/") == -1) { -							r_result.insert(E->get().name); +							ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_MEMBER); +							r_result.insert(option.display, option);  						}  					}  				} @@ -2066,11 +2094,13 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context  				List<MethodInfo> methods;  				tmp.get_method_list(&methods);  				for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) { +					ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_FUNCTION);  					if (E->get().arguments.size()) { -						r_result.insert(E->get().name + "("); +						option.insert_text += "(";  					} else { -						r_result.insert(E->get().name + "()"); +						option.insert_text += "()";  					} +					r_result.insert(option.display, option);  				}  				return; @@ -2082,7 +2112,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context  	}  } -static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p_only_functions, Set<String> &r_result) { +static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p_only_functions, Map<String, ScriptCodeCompletionOption> &r_result) {  	const GDScriptParser::BlockNode *block = p_context.block; @@ -2091,7 +2121,8 @@ static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p  		const GDScriptParser::FunctionNode *f = p_context.function;  		for (int i = 0; i < f->arguments.size(); i++) { -			r_result.insert(f->arguments[i].operator String()); +			ScriptCodeCompletionOption option(f->arguments[i].operator String(), ScriptCodeCompletionOption::KIND_PLAIN_TEXT); +			r_result.insert(option.display, option);  		}  	} @@ -2116,11 +2147,13 @@ static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p  	for (int i = 0; i < GDScriptFunctions::FUNC_MAX; i++) {  		MethodInfo mi = GDScriptFunctions::get_info(GDScriptFunctions::Function(i)); +		ScriptCodeCompletionOption option(String(GDScriptFunctions::get_func_name(GDScriptFunctions::Function(i))), ScriptCodeCompletionOption::KIND_FUNCTION);  		if (mi.arguments.size() || (mi.flags & METHOD_FLAG_VARARG)) { -			r_result.insert(String(GDScriptFunctions::get_func_name(GDScriptFunctions::Function(i))) + "("); +			option.insert_text += "(";  		} else { -			r_result.insert(String(GDScriptFunctions::get_func_name(GDScriptFunctions::Function(i))) + "()"); +			option.insert_text += "()";  		} +		r_result.insert(option.display, option);  	}  	static const char *_type_names[Variant::VARIANT_MAX] = { @@ -2130,7 +2163,8 @@ static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p  	};  	for (int i = 0; i < Variant::VARIANT_MAX; i++) { -		r_result.insert(_type_names[i]); +		ScriptCodeCompletionOption option(_type_names[i], ScriptCodeCompletionOption::KIND_CLASS); +		r_result.insert(option.display, option);  	}  	static const char *_keywords[] = { @@ -2144,7 +2178,8 @@ static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p  	const char **kw = _keywords;  	while (*kw) { -		r_result.insert(*kw); +		ScriptCodeCompletionOption option(*kw, ScriptCodeCompletionOption::KIND_PLAIN_TEXT); +		r_result.insert(option.display, option);  		kw++;  	} @@ -2158,7 +2193,8 @@ static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p  		}  		String path = ProjectSettings::get_singleton()->get(s);  		if (path.begins_with("*")) { -			r_result.insert(s.get_slice("/", 1)); +			ScriptCodeCompletionOption option(s.get_slice("/", 1), ScriptCodeCompletionOption::KIND_CONSTANT); +			r_result.insert(option.display, option);  		}  	} @@ -2166,16 +2202,18 @@ static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p  	List<StringName> named_scripts;  	ScriptServer::get_global_class_list(&named_scripts);  	for (List<StringName>::Element *E = named_scripts.front(); E; E = E->next()) { -		r_result.insert(E->get().operator String()); +		ScriptCodeCompletionOption option(E->get().operator String(), ScriptCodeCompletionOption::KIND_CLASS); +		r_result.insert(option.display, option);  	}  	// Native classes  	for (const Map<StringName, int>::Element *E = GDScriptLanguage::get_singleton()->get_global_map().front(); E; E = E->next()) { -		r_result.insert(E->key().operator String()); +		ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CLASS); +		r_result.insert(option.display, option);  	}  } -static void _find_call_arguments(const GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_method, int p_argidx, bool p_static, Set<String> &r_result, String &r_arghint) { +static void _find_call_arguments(const GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_method, int p_argidx, bool p_static, Map<String, ScriptCodeCompletionOption> &r_result, String &r_arghint) {  	Variant base = p_base.value;  	GDScriptParser::DataType base_type = p_base.type; @@ -2199,7 +2237,9 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con  				if ((p_method == "connect" || p_method == "emit_signal") && p_argidx == 0) {  					for (int i = 0; i < base_type.class_type->_signals.size(); i++) { -						r_result.insert(quote_style + base_type.class_type->_signals[i].name.operator String() + quote_style); +						ScriptCodeCompletionOption option(base_type.class_type->_signals[i].name.operator String(), ScriptCodeCompletionOption::KIND_SIGNAL); +						option.insert_text = quote_style + option.display + quote_style; +						r_result.insert(option.display, option);  					}  				} @@ -2212,7 +2252,9 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con  						List<MethodInfo> signals;  						gds->get_script_signal_list(&signals);  						for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) { -							r_result.insert(quote_style + E->get().name + quote_style); +							ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_SIGNAL); +							option.insert_text = quote_style + option.display + quote_style; +							r_result.insert(option.display, option);  						}  					}  					Ref<GDScript> base_script = gds->get_base_script(); @@ -2250,7 +2292,8 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con  								List<String> options;  								obj->get_argument_options(p_method, p_argidx, &options);  								for (List<String>::Element *F = options.front(); F; F = F->next()) { -									r_result.insert(F->get()); +									ScriptCodeCompletionOption option(F->get(), ScriptCodeCompletionOption::KIND_FUNCTION); +									r_result.insert(option.display, option);  								}  							}  						} @@ -2271,7 +2314,9 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con  					List<MethodInfo> signals;  					ClassDB::get_signal_list(class_name, &signals);  					for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) { -						r_result.insert(quote_style + E->get().name + quote_style); +						ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_SIGNAL); +						option.insert_text = quote_style + option.display + quote_style; +						r_result.insert(option.display, option);  					}  				} @@ -2286,7 +2331,9 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con  							continue;  						}  						String name = s.get_slice("/", 1); -						r_result.insert(quote_style + "/root/" + name + quote_style); +						ScriptCodeCompletionOption option("/root/" + name, ScriptCodeCompletionOption::KIND_NODE_PATH); +						option.insert_text = quote_style + option.display + quote_style; +						r_result.insert(option.display, option);  					}  				} @@ -2300,7 +2347,9 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con  							continue;  						}  						String name = s.get_slice("/", 1); -						r_result.insert(quote_style + name + quote_style); +						ScriptCodeCompletionOption option(name, ScriptCodeCompletionOption::KIND_CONSTANT); +						option.insert_text = quote_style + option.display + quote_style; +						r_result.insert(option.display, option);  					}  				} @@ -2333,7 +2382,7 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con  	}  } -static void _find_call_arguments(GDScriptCompletionContext &p_context, const GDScriptParser::Node *p_node, int p_argidx, Set<String> &r_result, bool &r_forced, String &r_arghint) { +static void _find_call_arguments(GDScriptCompletionContext &p_context, const GDScriptParser::Node *p_node, int p_argidx, Map<String, ScriptCodeCompletionOption> &r_result, bool &r_forced, String &r_arghint) {  	const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\""; @@ -2451,17 +2500,19 @@ static void _find_call_arguments(GDScriptCompletionContext &p_context, const GDS  	_find_call_arguments(p_context, ci, function, p_argidx, _static, r_result, r_arghint);  	if (function == "connect" && p_argidx == 2) { -		Set<String> methods; +		Map<String, ScriptCodeCompletionOption> methods;  		_find_identifiers_in_base(p_context, connect_base, true, methods); -		for (Set<String>::Element *E = methods.front(); E; E = E->next()) { -			r_result.insert(quote_style + E->get().replace("(", "").replace(")", "") + quote_style); +		for (Map<String, ScriptCodeCompletionOption>::Element *E = methods.front(); E; E = E->next()) { +			ScriptCodeCompletionOption &option = E->value(); +			option.insert_text = quote_style + option.display + quote_style; +			r_result.insert(option.display, option);  		}  	}  	r_forced = r_result.size() > 0;  } -Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path, Object *p_owner, List<String> *r_options, bool &r_forced, String &r_call_hint) { +Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path, Object *p_owner, List<ScriptCodeCompletionOption> *r_options, bool &r_forced, String &r_call_hint) {  	const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\""; @@ -2469,7 +2520,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path  	parser.parse(p_code, p_path.get_base_dir(), false, p_path, true);  	r_forced = false; -	Set<String> options; +	Map<String, ScriptCodeCompletionOption> options;  	GDScriptCompletionContext context;  	context._class = parser.get_completion_class();  	context.block = parser.get_completion_block(); @@ -2490,7 +2541,8 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path  			List<StringName> constants;  			Variant::get_constants_for_type(parser.get_completion_built_in_constant(), &constants);  			for (List<StringName>::Element *E = constants.front(); E; E = E->next()) { -				options.insert(E->get().operator String()); +				ScriptCodeCompletionOption option(E->get().operator String(), ScriptCodeCompletionOption::KIND_CONSTANT); +				options.insert(option.display, option);  			}  		} break;  		case GDScriptParser::COMPLETION_PARENT_FUNCTION: { @@ -2515,9 +2567,11 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path  						r_forced = true;  						String idopt = opt.unquote();  						if (idopt.replace("/", "_").is_valid_identifier()) { -							options.insert(idopt); +							ScriptCodeCompletionOption option(idopt, ScriptCodeCompletionOption::KIND_NODE_PATH); +							options.insert(option.display, option);  						} else { -							options.insert(opt); +							ScriptCodeCompletionOption option(opt, ScriptCodeCompletionOption::KIND_NODE_PATH); +							options.insert(option.display, option);  						}  					}  				} @@ -2532,7 +2586,8 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path  						continue;  					}  					String name = s.get_slice("/", 1); -					options.insert(quote_style + "/root/" + name + quote_style); +					ScriptCodeCompletionOption option(quote_style + "/root/" + name + quote_style, ScriptCodeCompletionOption::KIND_NODE_PATH); +					options.insert(option.display, option);  				}  			}  		} break; @@ -2655,7 +2710,8 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path  				}  				method_hint += ":"; -				options.insert(method_hint); +				ScriptCodeCompletionOption option(method_hint, ScriptCodeCompletionOption::KIND_FUNCTION); +				options.insert(option.display, option);  			}  		} break;  		case GDScriptParser::COMPLETION_YIELD: { @@ -2673,7 +2729,9 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path  				switch (base_type.kind) {  					case GDScriptParser::DataType::CLASS: {  						for (int i = 0; i < base_type.class_type->_signals.size(); i++) { -							options.insert(quote_style + base_type.class_type->_signals[i].name.operator String() + quote_style); +							ScriptCodeCompletionOption option(base_type.class_type->_signals[i].name.operator String(), ScriptCodeCompletionOption::KIND_SIGNAL); +							option.insert_text = quote_style + option.display + quote_style; +							options.insert(option.display, option);  						}  						base_type = base_type.class_type->base_type;  					} break; @@ -2684,7 +2742,8 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path  							List<MethodInfo> signals;  							scr->get_script_signal_list(&signals);  							for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) { -								options.insert(quote_style + E->get().name + quote_style); +								ScriptCodeCompletionOption option(quote_style + E->get().name + quote_style, ScriptCodeCompletionOption::KIND_SIGNAL); +								options.insert(option.display, option);  							}  							Ref<Script> base_script = scr->get_base_script();  							if (base_script.is_valid()) { @@ -2711,7 +2770,8 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path  						List<MethodInfo> signals;  						ClassDB::get_signal_list(class_name, &signals);  						for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) { -							options.insert(quote_style + E->get().name + quote_style); +							ScriptCodeCompletionOption option(quote_style + E->get().name + quote_style, ScriptCodeCompletionOption::KIND_SIGNAL); +							options.insert(option.display, option);  						}  					} break;  					default: { @@ -2748,18 +2808,21 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path  					c.line = E->value().expression->line;  					if (_guess_expression_type(c, E->value().expression, constant)) {  						if (constant.type.has_type && constant.type.is_meta_type) { -							options.insert(E->key().operator String()); +							ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CLASS); +							options.insert(option.display, option);  						}  					}  				}  				for (int i = 0; i < clss->subclasses.size(); i++) {  					if (clss->subclasses[i]->name != StringName()) { -						options.insert(clss->subclasses[i]->name.operator String()); +						ScriptCodeCompletionOption option(clss->subclasses[i]->name.operator String(), ScriptCodeCompletionOption::KIND_CLASS); +						options.insert(option.display, option);  					}  				}  				clss = clss->owner;  				for (int i = 0; i < Variant::VARIANT_MAX; i++) { -					options.insert(Variant::get_type_name((Variant::Type)i)); +					ScriptCodeCompletionOption option(Variant::get_type_name((Variant::Type)i), ScriptCodeCompletionOption::KIND_CLASS); +					options.insert(option.display, option);  				}  			} @@ -2773,18 +2836,21 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path  				if (Engine::get_singleton()->has_singleton(class_name)) {  					continue;  				} -				options.insert(class_name); +				ScriptCodeCompletionOption option(class_name, ScriptCodeCompletionOption::KIND_CLASS); +				options.insert(option.display, option);  			}  			// Named scripts  			List<StringName> named_scripts;  			ScriptServer::get_global_class_list(&named_scripts);  			for (List<StringName>::Element *E = named_scripts.front(); E; E = E->next()) { -				options.insert(E->get().operator String()); +				ScriptCodeCompletionOption option(E->get().operator String(), ScriptCodeCompletionOption::KIND_CLASS); +				options.insert(option.display, option);  			}  			if (parser.get_completion_identifier_is_function()) { -				options.insert("void"); +				ScriptCodeCompletionOption option("void", ScriptCodeCompletionOption::KIND_PLAIN_TEXT); +				options.insert(option.display, option);  			}  			r_forced = true;  		} break; @@ -2831,13 +2897,15 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path  								c2.line = E->value().expression->line;  								if (_guess_expression_type(c2, E->value().expression, constant)) {  									if (constant.type.has_type && constant.type.is_meta_type) { -										options.insert(E->key().operator String()); +										ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CLASS); +										options.insert(option.display, option);  									}  								}  							}  							for (int i = 0; i < base_type.class_type->subclasses.size(); i++) {  								if (base_type.class_type->subclasses[i]->name != StringName()) { -									options.insert(base_type.class_type->subclasses[i]->name.operator String()); +									ScriptCodeCompletionOption option(base_type.class_type->subclasses[i]->name.operator String(), ScriptCodeCompletionOption::KIND_CLASS); +									options.insert(option.display, option);  								}  							} @@ -2855,7 +2923,8 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path  							for (Map<StringName, Variant>::Element *E = constants.front(); E; E = E->next()) {  								Ref<Script> const_scr = E->value();  								if (const_scr.is_valid()) { -									options.insert(E->key().operator String()); +									ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CLASS); +									options.insert(option.display, option);  								}  							}  							Ref<Script> base_script = scr->get_base_script(); @@ -2877,7 +2946,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path  		} break;  	} -	for (Set<String>::Element *E = options.front(); E; E = E->next()) { +	for (Map<String, ScriptCodeCompletionOption>::Element *E = options.front(); E; E = E->next()) {  		r_options->push_back(E->get());  	} @@ -2886,7 +2955,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path  #else -Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path, Object *p_owner, List<String> *r_options, bool &r_forced, String &r_call_hint) { +Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path, Object *p_owner, List<ScriptCodeCompletionOption> *r_options, bool &r_forced, String &r_call_hint) {  	return OK;  } |