Skip to content

Commit

Permalink
Code Editor: Add documentation tooltips
Browse files Browse the repository at this point in the history
  • Loading branch information
dalexeev committed Dec 7, 2024
1 parent aa8d9b8 commit bec6fd0
Show file tree
Hide file tree
Showing 21 changed files with 751 additions and 173 deletions.
33 changes: 26 additions & 7 deletions core/object/script_language.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ class Script : public Resource {
virtual Error reload(bool p_keep_state = false) = 0;

#ifdef TOOLS_ENABLED
virtual StringName get_doc_class_name() const = 0;
virtual Vector<DocData::ClassDoc> get_documentation() const = 0;
virtual String get_class_icon_path() const = 0;
virtual PropertyInfo get_class_category() const;
Expand Down Expand Up @@ -181,7 +182,7 @@ class Script : public Resource {
virtual int get_member_line(const StringName &p_member) const { return -1; }

virtual void get_constants(HashMap<StringName, Variant> *p_constants) {}
virtual void get_members(HashSet<StringName> *p_constants) {}
virtual void get_members(HashSet<StringName> *p_members) {}

virtual bool is_placeholder_fallback_enabled() const { return false; }

Expand Down Expand Up @@ -340,25 +341,43 @@ class ScriptLanguage : public Object {
virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<CodeCompletionOption> *r_options, bool &r_force, String &r_call_hint) { return ERR_UNAVAILABLE; }

enum LookupResultType {
LOOKUP_RESULT_SCRIPT_LOCATION,
LOOKUP_RESULT_SCRIPT_LOCATION, // Use if none of the options below apply.
LOOKUP_RESULT_CLASS,
LOOKUP_RESULT_CLASS_CONSTANT,
LOOKUP_RESULT_CLASS_PROPERTY,
LOOKUP_RESULT_CLASS_METHOD,
LOOKUP_RESULT_CLASS_SIGNAL,
LOOKUP_RESULT_CLASS_ENUM,
LOOKUP_RESULT_CLASS_TBD_GLOBALSCOPE,
LOOKUP_RESULT_CLASS_TBD_GLOBALSCOPE, // Deprecated.
LOOKUP_RESULT_CLASS_ANNOTATION,
LOOKUP_RESULT_MAX
LOOKUP_RESULT_LOCAL_CONSTANT,
LOOKUP_RESULT_LOCAL_VARIABLE,
LOOKUP_RESULT_MAX,
};

struct LookupResult {
LookupResultType type;
Ref<Script> script;

// For `CLASS_*`.
String class_name;
String class_member;
String class_path;
int location;

// For `LOCAL_*`.
String description;
bool is_deprecated = false;
String deprecated_message;
bool is_experimental = false;
String experimental_message;

// For `LOCAL_*`.
String doc_type;
String enumeration;
bool is_bitfield = false;

// `SCRIPT_LOCATION` and `LOCAL_*` must have, `CLASS_*` can have.
Ref<Script> script;
String script_path;
int location = -1;
};

virtual Error lookup_code(const String &p_code, const String &p_symbol, const String &p_path, Object *p_owner, LookupResult &r_result) { return ERR_UNAVAILABLE; }
Expand Down
5 changes: 4 additions & 1 deletion core/object/script_language_extension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ void ScriptExtension::_bind_methods() {
GDVIRTUAL_BIND(_set_source_code, "code");
GDVIRTUAL_BIND(_reload, "keep_state");

GDVIRTUAL_BIND(_get_doc_class_name);
GDVIRTUAL_BIND(_get_documentation);
GDVIRTUAL_BIND(_get_class_icon_path);

Expand Down Expand Up @@ -169,8 +170,10 @@ void ScriptLanguageExtension::_bind_methods() {
BIND_ENUM_CONSTANT(LOOKUP_RESULT_CLASS_METHOD);
BIND_ENUM_CONSTANT(LOOKUP_RESULT_CLASS_SIGNAL);
BIND_ENUM_CONSTANT(LOOKUP_RESULT_CLASS_ENUM);
BIND_ENUM_CONSTANT(LOOKUP_RESULT_CLASS_TBD_GLOBALSCOPE);
BIND_ENUM_CONSTANT(LOOKUP_RESULT_CLASS_TBD_GLOBALSCOPE); // Deprecated.
BIND_ENUM_CONSTANT(LOOKUP_RESULT_CLASS_ANNOTATION);
BIND_ENUM_CONSTANT(LOOKUP_RESULT_LOCAL_CONSTANT);
BIND_ENUM_CONSTANT(LOOKUP_RESULT_LOCAL_VARIABLE);
BIND_ENUM_CONSTANT(LOOKUP_RESULT_MAX);

BIND_ENUM_CONSTANT(LOCATION_LOCAL);
Expand Down
38 changes: 26 additions & 12 deletions core/object/script_language_extension.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,16 @@ class ScriptExtension : public Script {
EXBIND1(set_source_code, const String &)
EXBIND1R(Error, reload, bool)

GDVIRTUAL0RC_REQUIRED(StringName, _get_doc_class_name)
GDVIRTUAL0RC_REQUIRED(TypedArray<Dictionary>, _get_documentation)
GDVIRTUAL0RC(String, _get_class_icon_path)
#ifdef TOOLS_ENABLED
virtual StringName get_doc_class_name() const override {
StringName ret;
GDVIRTUAL_CALL(_get_doc_class_name, ret);
return ret;
}

virtual Vector<DocData::ClassDoc> get_documentation() const override {
TypedArray<Dictionary> doc;
GDVIRTUAL_CALL(_get_documentation, doc);
Expand Down Expand Up @@ -454,22 +461,29 @@ class ScriptLanguageExtension : public ScriptLanguage {
virtual Error lookup_code(const String &p_code, const String &p_symbol, const String &p_path, Object *p_owner, LookupResult &r_result) override {
Dictionary ret;
GDVIRTUAL_CALL(_lookup_code, p_code, p_symbol, p_path, p_owner, ret);
if (!ret.has("result")) {
return ERR_UNAVAILABLE;
}

ERR_FAIL_COND_V(!ret.has("result"), ERR_UNAVAILABLE);
const Error result = Error(int(ret["result"]));

ERR_FAIL_COND_V(!ret.has("type"), ERR_UNAVAILABLE);
r_result.type = LookupResultType(int(ret["type"]));
ERR_FAIL_COND_V(!ret.has("script"), ERR_UNAVAILABLE);
r_result.script = ret["script"];
ERR_FAIL_COND_V(!ret.has("class_name"), ERR_UNAVAILABLE);
r_result.class_name = ret["class_name"];
ERR_FAIL_COND_V(!ret.has("class_path"), ERR_UNAVAILABLE);
r_result.class_path = ret["class_path"];
ERR_FAIL_COND_V(!ret.has("location"), ERR_UNAVAILABLE);
r_result.location = ret["location"];

Error result = Error(int(ret["result"]));
r_result.class_name = ret.get("class_name", "");
r_result.class_member = ret.get("class_member", "");

r_result.description = ret.get("description", "");
r_result.is_deprecated = ret.get("is_deprecated", false);
r_result.deprecated_message = ret.get("deprecated_message", "");
r_result.is_deprecated = ret.get("is_deprecated", false);
r_result.experimental_message = ret.get("experimental_message", "");

r_result.doc_type = ret.get("doc_type", "");
r_result.enumeration = ret.get("enumeration", "");
r_result.is_bitfield = ret.get("is_bitfield", false);

r_result.script = ret.get("script", Ref<Script>());
r_result.script_path = ret.get("script_path", "");
r_result.location = ret.get("location", -1);

return result;
}
Expand Down
13 changes: 13 additions & 0 deletions doc/classes/CodeEdit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,9 @@
<member name="symbol_lookup_on_click" type="bool" setter="set_symbol_lookup_on_click_enabled" getter="is_symbol_lookup_on_click_enabled" default="false">
Set when a validated word from [signal symbol_validate] is clicked, the [signal symbol_lookup] should be emitted.
</member>
<member name="symbol_tooltip_on_hover" type="bool" setter="set_symbol_tooltip_on_hover_enabled" getter="is_symbol_tooltip_on_hover_enabled" default="false">
Set when a word is hovered, the [signal symbol_hovered] should be emitted.
</member>
<member name="text_direction" type="int" setter="set_text_direction" getter="get_text_direction" overrides="TextEdit" enum="Control.TextDirection" default="1" />
</members>
<signals>
Expand All @@ -601,6 +604,15 @@
Emitted when the user requests code completion. This signal will not be sent if [method _request_code_completion] is overridden or [member code_completion_enabled] is [code]false[/code].
</description>
</signal>
<signal name="symbol_hovered">
<param index="0" name="symbol" type="String" />
<param index="1" name="line" type="int" />
<param index="2" name="column" type="int" />
<description>
Emitted when the user hovers over a symbol. Unlike [signal Control.mouse_entered], this signal is not emitted immediately, but when the cursor is over the symbol for [member ProjectSettings.gui/timers/tooltip_delay_sec] seconds.
[b]Note:[/b] [member symbol_tooltip_on_hover] must be [code]true[/code] for this signal to be emitted.
</description>
</signal>
<signal name="symbol_lookup">
<param index="0" name="symbol" type="String" />
<param index="1" name="line" type="int" />
Expand All @@ -613,6 +625,7 @@
<param index="0" name="symbol" type="String" />
<description>
Emitted when the user hovers over a symbol. The symbol should be validated and responded to, by calling [method set_symbol_lookup_word_as_valid].
[b]Note:[/b] [member symbol_lookup_on_click] must be [code]true[/code] for this signal to be emitted.
</description>
</signal>
</signals>
Expand Down
5 changes: 5 additions & 0 deletions doc/classes/ScriptExtension.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
<description>
</description>
</method>
<method name="_get_doc_class_name" qualifiers="virtual const">
<return type="StringName" />
<description>
</description>
</method>
<method name="_get_documentation" qualifiers="virtual const">
<return type="Dictionary[]" />
<description>
Expand Down
8 changes: 6 additions & 2 deletions doc/classes/ScriptLanguageExtension.xml
Original file line number Diff line number Diff line change
Expand Up @@ -387,11 +387,15 @@
</constant>
<constant name="LOOKUP_RESULT_CLASS_ENUM" value="6" enum="LookupResultType">
</constant>
<constant name="LOOKUP_RESULT_CLASS_TBD_GLOBALSCOPE" value="7" enum="LookupResultType">
<constant name="LOOKUP_RESULT_CLASS_TBD_GLOBALSCOPE" value="7" enum="LookupResultType" deprecated="">
</constant>
<constant name="LOOKUP_RESULT_CLASS_ANNOTATION" value="8" enum="LookupResultType">
</constant>
<constant name="LOOKUP_RESULT_MAX" value="9" enum="LookupResultType">
<constant name="LOOKUP_RESULT_LOCAL_CONSTANT" value="9" enum="LookupResultType">
</constant>
<constant name="LOOKUP_RESULT_LOCAL_VARIABLE" value="10" enum="LookupResultType">
</constant>
<constant name="LOOKUP_RESULT_MAX" value="11" enum="LookupResultType">
</constant>
<constant name="LOCATION_LOCAL" value="0" enum="CodeCompletionLocation">
The option is local to the location of the code completion query - e.g. a local variable. Subsequent value of location represent options from the outer class, the exact value represent how far they are (in terms of inner classes).
Expand Down
Loading

0 comments on commit bec6fd0

Please sign in to comment.