Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve searching of component browser entries #5645

Merged
merged 9 commits into from
Feb 16, 2023
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@
- [Added restoring of last project snapshot on shortcut.][4050]
- [Added contextual suggestions to argument dropdowns][4072]. Dropdowns will now
contain suggestions which are based on evaluated data.
- [Improved component browser entry filtering and sorting][5645]. The component
browser will now provide suggestions matching either the component's label or
the corresponding code.

#### EnsoGL (rendering engine)

Expand Down Expand Up @@ -473,6 +476,7 @@
[4120]: https://github.com/enso-org/enso/pull/4120
[4050]: https://github.com/enso-org/enso/pull/4050
[4072]: https://github.com/enso-org/enso/pull/4072
[5645]: https://github.com/enso-org/enso/pull/5645
[5646]: https://github.com/enso-org/enso/pull/5646

#### Enso Compiler
Expand Down
32 changes: 28 additions & 4 deletions app/gui/src/controller/searcher/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,36 @@ impl Component {
///
/// It should be called each time the filtering pattern changes.
pub fn update_matching_info(&self, pattern: impl Str) {
// Match the input pattern to the component label.
let label = self.label();
let matches = fuzzly::matches(&label, pattern.as_ref());
let subsequence = matches.and_option_from(|| {
let label_matches = fuzzly::matches(&label, pattern.as_ref());
let label_subsequence = label_matches.and_option_from(|| {
let metric = fuzzly::metric::default();
fuzzly::find_best_subsequence(label, pattern, metric)
fuzzly::find_best_subsequence(label, pattern.as_ref(), metric)
});

// Match the input pattern to the code to be inserted.
let code = match &self.data {
Data::FromDatabase { entry, .. } => entry.code_to_insert(true).to_string(),
Data::Virtual { snippet } => snippet.code.to_string(),
};
let code_matches = fuzzly::matches(&code, pattern.as_ref());
let code_subsequence = code_matches.and_option_from(|| {
let metric = fuzzly::metric::default();
fuzzly::find_best_subsequence(code, pattern.as_ref(), metric)
});

// Pick the best match score of the two, use only the character indices matching the label.
let subsequence = match (label_subsequence, code_subsequence) {
(Some(label), Some(code)) => {
let score = label.score.max(code.score);
Some(fuzzly::Subsequence { score, ..label })
}
(None, Some(code)) => Some(fuzzly::Subsequence { indices: Vec::new(), ..code }),
(Some(label), None) => Some(label),
(None, None) => None,
};

*self.match_info.borrow_mut() = match subsequence {
Some(subsequence) => MatchInfo::Matches { subsequence },
None => MatchInfo::DoesNotMatch,
Expand Down Expand Up @@ -192,7 +216,7 @@ impl Display for Component {
let self_type_not_here = self_type_ref.filter(|t| *t != &entry.defined_in);
if let Some(self_type) = self_type_not_here {
let self_name = self_type.name().from_case(Case::Snake).to_case(Case::Title);
write!(f, "{self_name} {entry_name}")
write!(f, "{entry_name} ({self_name})")
} else {
write!(f, "{entry_name}")
}
Expand Down