|
@@ -127,7 +127,7 @@ void EditorHelpSearch::_notification(int p_what) {
|
|
|
if (search->work()) {
|
|
|
// Search done.
|
|
|
|
|
|
- // Only point to the perfect match if it's a new search, and not just reopening a old one.
|
|
|
+ // Only point to the match if it's a new search, and not just reopening a old one.
|
|
|
if (!old_search)
|
|
|
results_tree->ensure_cursor_is_visible();
|
|
|
else
|
|
@@ -321,6 +321,7 @@ bool EditorHelpSearch::Runner::_phase_match_classes_init() {
|
|
|
iterator_doc = EditorHelp::get_doc_data()->class_list.front();
|
|
|
matches.clear();
|
|
|
matched_item = NULL;
|
|
|
+ match_highest_score = 0;
|
|
|
|
|
|
return true;
|
|
|
}
|
|
@@ -444,15 +445,20 @@ bool EditorHelpSearch::Runner::_match_string(const String &p_term, const String
|
|
|
}
|
|
|
|
|
|
void EditorHelpSearch::Runner::_match_item(TreeItem *p_item, const String &p_text) {
|
|
|
+ float inverse_length = 1.f / float(p_text.length());
|
|
|
|
|
|
- if (!matched_item) {
|
|
|
- if (search_flags & SEARCH_CASE_SENSITIVE) {
|
|
|
- if (p_text.casecmp_to(term) == 0)
|
|
|
- matched_item = p_item;
|
|
|
- } else {
|
|
|
- if (p_text.nocasecmp_to(term) == 0)
|
|
|
- matched_item = p_item;
|
|
|
- }
|
|
|
+ // Favor types where search term is a substring close to the start of the type.
|
|
|
+ float w = 0.5f;
|
|
|
+ int pos = p_text.findn(term);
|
|
|
+ float score = (pos > -1) ? 1.0f - w * MIN(1, 3 * pos * inverse_length) : MAX(0.f, .9f - w);
|
|
|
+
|
|
|
+ // Favor shorter items: they resemble the search term more.
|
|
|
+ w = 0.1f;
|
|
|
+ score *= (1 - w) + w * (term.length() * inverse_length);
|
|
|
+
|
|
|
+ if (match_highest_score == 0 || score > match_highest_score) {
|
|
|
+ matched_item = p_item;
|
|
|
+ match_highest_score = score;
|
|
|
}
|
|
|
}
|
|
|
|