summaryrefslogtreecommitdiffstats
path: root/editor/editor_help_search.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'editor/editor_help_search.cpp')
-rw-r--r--editor/editor_help_search.cpp68
1 files changed, 51 insertions, 17 deletions
diff --git a/editor/editor_help_search.cpp b/editor/editor_help_search.cpp
index 104b0a73c4..2e0dcb1e13 100644
--- a/editor/editor_help_search.cpp
+++ b/editor/editor_help_search.cpp
@@ -369,7 +369,7 @@ bool EditorHelpSearch::Runner::_phase_match_classes() {
// If the search term is empty, add any classes which are not script docs or which don't start with
// a double-quotation. This will ensure that only C++ classes and explicitly named classes will
// be added.
- match.name = (term.is_empty() && (!class_doc->is_script_doc || class_doc->name[0] != '\"')) || _match_string(term, class_doc->name);
+ match.name = (term.is_empty() && (!class_doc->is_script_doc || class_doc->name[0] != '\"')) || _match_string(term, class_doc->name) || _match_keywords(term, class_doc->keywords);
}
// Match members only if the term is long enough, to avoid slow performance from building a large tree.
@@ -386,35 +386,35 @@ bool EditorHelpSearch::Runner::_phase_match_classes() {
}
if (search_flags & SEARCH_SIGNALS) {
for (int i = 0; i < class_doc->signals.size(); i++) {
- if (_all_terms_in_name(class_doc->signals[i].name)) {
+ if (_all_terms_in_name(class_doc->signals[i].name) || _all_terms_in_keywords(class_doc->signals[i].keywords)) {
match.signals.push_back(const_cast<DocData::MethodDoc *>(&class_doc->signals[i]));
}
}
}
if (search_flags & SEARCH_CONSTANTS) {
for (int i = 0; i < class_doc->constants.size(); i++) {
- if (_all_terms_in_name(class_doc->constants[i].name)) {
+ if (_all_terms_in_name(class_doc->constants[i].name) || _all_terms_in_keywords(class_doc->constants[i].keywords)) {
match.constants.push_back(const_cast<DocData::ConstantDoc *>(&class_doc->constants[i]));
}
}
}
if (search_flags & SEARCH_PROPERTIES) {
for (int i = 0; i < class_doc->properties.size(); i++) {
- if (_all_terms_in_name(class_doc->properties[i].name)) {
+ if (_all_terms_in_name(class_doc->properties[i].name) || _all_terms_in_keywords(class_doc->properties[i].keywords)) {
match.properties.push_back(const_cast<DocData::PropertyDoc *>(&class_doc->properties[i]));
}
}
}
if (search_flags & SEARCH_THEME_ITEMS) {
for (int i = 0; i < class_doc->theme_properties.size(); i++) {
- if (_all_terms_in_name(class_doc->theme_properties[i].name)) {
+ if (_all_terms_in_name(class_doc->theme_properties[i].name) || _all_terms_in_keywords(class_doc->theme_properties[i].keywords)) {
match.theme_properties.push_back(const_cast<DocData::ThemeItemDoc *>(&class_doc->theme_properties[i]));
}
}
}
if (search_flags & SEARCH_ANNOTATIONS) {
for (int i = 0; i < class_doc->annotations.size(); i++) {
- if (_match_string(term, class_doc->annotations[i].name)) {
+ if (_match_string(term, class_doc->annotations[i].name) || _all_terms_in_keywords(class_doc->annotations[i].keywords)) {
match.annotations.push_back(const_cast<DocData::MethodDoc *>(&class_doc->annotations[i]));
}
}
@@ -574,7 +574,8 @@ void EditorHelpSearch::Runner::_match_method_name_and_push_back(Vector<DocData::
// Constructors, Methods, Operators...
for (int i = 0; i < p_methods.size(); i++) {
String method_name = (search_flags & SEARCH_CASE_SENSITIVE) ? p_methods[i].name : p_methods[i].name.to_lower();
- if (_all_terms_in_name(method_name) ||
+ String keywords = (search_flags & SEARCH_CASE_SENSITIVE) ? p_methods[i].keywords : p_methods[i].keywords.to_lower();
+ if (_all_terms_in_name(method_name) || _all_terms_in_keywords(keywords) ||
(term.begins_with(".") && method_name.begins_with(term.substr(1))) ||
(term.ends_with("(") && method_name.ends_with(term.left(term.length() - 1).strip_edges())) ||
(term.begins_with(".") && term.ends_with("(") && method_name == term.substr(1, term.length() - 2).strip_edges())) {
@@ -583,15 +584,24 @@ void EditorHelpSearch::Runner::_match_method_name_and_push_back(Vector<DocData::
}
}
-bool EditorHelpSearch::Runner::_all_terms_in_name(String name) {
+bool EditorHelpSearch::Runner::_all_terms_in_name(const String &p_name) const {
for (int i = 0; i < terms.size(); i++) {
- if (!_match_string(terms[i], name)) {
+ if (!_match_string(terms[i], p_name)) {
return false;
}
}
return true;
}
+bool EditorHelpSearch::Runner::_all_terms_in_keywords(const String &p_keywords) const {
+ for (const String &keyword : p_keywords.split(",")) {
+ if (_all_terms_in_name(keyword.strip_edges())) {
+ return true;
+ }
+ }
+ return false;
+}
+
bool EditorHelpSearch::Runner::_match_string(const String &p_term, const String &p_string) const {
if (search_flags & SEARCH_CASE_SENSITIVE) {
return p_string.find(p_term) > -1;
@@ -600,7 +610,20 @@ bool EditorHelpSearch::Runner::_match_string(const String &p_term, const String
}
}
-void EditorHelpSearch::Runner::_match_item(TreeItem *p_item, const String &p_text) {
+bool EditorHelpSearch::Runner::_match_keywords(const String &p_term, const String &p_keywords) const {
+ for (const String &keyword : p_keywords.split(",")) {
+ if (_match_string(p_term, keyword.strip_edges())) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void EditorHelpSearch::Runner::_match_item(TreeItem *p_item, const String &p_text, bool p_is_keywords) {
+ if (p_text.is_empty()) {
+ return;
+ }
+
float inverse_length = 1.f / float(p_text.length());
// Favor types where search term is a substring close to the start of the type.
@@ -612,6 +635,11 @@ void EditorHelpSearch::Runner::_match_item(TreeItem *p_item, const String &p_tex
w = 0.1f;
score *= (1 - w) + w * (term.length() * inverse_length);
+ // Reduce the score of keywords, since they are an indirect match.
+ if (p_is_keywords) {
+ score *= 0.9f;
+ }
+
if (match_highest_score == 0 || score > match_highest_score) {
matched_item = p_item;
match_highest_score = score;
@@ -711,43 +739,46 @@ TreeItem *EditorHelpSearch::Runner::_create_class_item(TreeItem *p_parent, const
}
_match_item(item, p_doc->name);
+ for (const String &keyword : p_doc->keywords.split(",")) {
+ _match_item(item, keyword.strip_edges(), true);
+ }
return item;
}
TreeItem *EditorHelpSearch::Runner::_create_method_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const String &p_text, const DocData::MethodDoc *p_doc) {
String tooltip = _build_method_tooltip(p_class_doc, p_doc);
- return _create_member_item(p_parent, p_class_doc->name, "MemberMethod", p_doc->name, p_text, TTRC("Method"), "method", tooltip, p_doc->is_deprecated, p_doc->is_experimental);
+ return _create_member_item(p_parent, p_class_doc->name, "MemberMethod", p_doc->name, p_text, TTRC("Method"), "method", tooltip, p_doc->keywords, p_doc->is_deprecated, p_doc->is_experimental);
}
TreeItem *EditorHelpSearch::Runner::_create_signal_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::MethodDoc *p_doc) {
String tooltip = _build_method_tooltip(p_class_doc, p_doc);
- return _create_member_item(p_parent, p_class_doc->name, "MemberSignal", p_doc->name, p_doc->name, TTRC("Signal"), "signal", tooltip, p_doc->is_deprecated, p_doc->is_experimental);
+ return _create_member_item(p_parent, p_class_doc->name, "MemberSignal", p_doc->name, p_doc->name, TTRC("Signal"), "signal", tooltip, p_doc->keywords, p_doc->is_deprecated, p_doc->is_experimental);
}
TreeItem *EditorHelpSearch::Runner::_create_annotation_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const String &p_text, const DocData::MethodDoc *p_doc) {
String tooltip = _build_method_tooltip(p_class_doc, p_doc);
- return _create_member_item(p_parent, p_class_doc->name, "MemberAnnotation", p_doc->name, p_text, TTRC("Annotation"), "annotation", tooltip, p_doc->is_deprecated, p_doc->is_experimental);
+ return _create_member_item(p_parent, p_class_doc->name, "MemberAnnotation", p_doc->name, p_text, TTRC("Annotation"), "annotation", tooltip, p_doc->keywords, p_doc->is_deprecated, p_doc->is_experimental);
}
TreeItem *EditorHelpSearch::Runner::_create_constant_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::ConstantDoc *p_doc) {
String tooltip = p_class_doc->name + "." + p_doc->name;
- return _create_member_item(p_parent, p_class_doc->name, "MemberConstant", p_doc->name, p_doc->name, TTRC("Constant"), "constant", tooltip, p_doc->is_deprecated, p_doc->is_experimental);
+ return _create_member_item(p_parent, p_class_doc->name, "MemberConstant", p_doc->name, p_doc->name, TTRC("Constant"), "constant", tooltip, p_doc->keywords, p_doc->is_deprecated, p_doc->is_experimental);
}
TreeItem *EditorHelpSearch::Runner::_create_property_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::PropertyDoc *p_doc) {
String tooltip = p_doc->type + " " + p_class_doc->name + "." + p_doc->name;
tooltip += "\n " + p_class_doc->name + "." + p_doc->setter + "(value) setter";
tooltip += "\n " + p_class_doc->name + "." + p_doc->getter + "() getter";
- return _create_member_item(p_parent, p_class_doc->name, "MemberProperty", p_doc->name, p_doc->name, TTRC("Property"), "property", tooltip, p_doc->is_deprecated, p_doc->is_experimental);
+ return _create_member_item(p_parent, p_class_doc->name, "MemberProperty", p_doc->name, p_doc->name, TTRC("Property"), "property", tooltip, p_doc->keywords, p_doc->is_deprecated, p_doc->is_experimental);
}
TreeItem *EditorHelpSearch::Runner::_create_theme_property_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::ThemeItemDoc *p_doc) {
String tooltip = p_doc->type + " " + p_class_doc->name + "." + p_doc->name;
- return _create_member_item(p_parent, p_class_doc->name, "MemberTheme", p_doc->name, p_doc->name, TTRC("Theme Property"), "theme_item", tooltip, false, false);
+ return _create_member_item(p_parent, p_class_doc->name, "MemberTheme", p_doc->name, p_doc->name, TTRC("Theme Property"), "theme_item", p_doc->keywords, tooltip, false, false);
}
-TreeItem *EditorHelpSearch::Runner::_create_member_item(TreeItem *p_parent, const String &p_class_name, const String &p_icon, const String &p_name, const String &p_text, const String &p_type, const String &p_metatype, const String &p_tooltip, bool is_deprecated, bool is_experimental) {
+TreeItem *EditorHelpSearch::Runner::_create_member_item(TreeItem *p_parent, const String &p_class_name, const String &p_icon, const String &p_name, const String &p_text, const String &p_type, const String &p_metatype, const String &p_tooltip, const String &p_keywords, bool is_deprecated, bool is_experimental) {
const String item_meta = "class_" + p_metatype + ":" + p_class_name + ":" + p_name;
TreeItem *item = nullptr;
@@ -774,6 +805,9 @@ TreeItem *EditorHelpSearch::Runner::_create_member_item(TreeItem *p_parent, cons
}
_match_item(item, p_name);
+ for (const String &keyword : p_keywords.split(",")) {
+ _match_item(item, keyword.strip_edges(), true);
+ }
return item;
}