Improve StringMatchCandidate::new interface (#22011)

Release Notes:

- N/A
This commit is contained in:
Michael Sloan 2024-12-14 13:35:36 -07:00 committed by GitHub
parent 9daa426e93
commit 25970650a7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
28 changed files with 92 additions and 184 deletions

View file

@ -716,7 +716,7 @@ impl ContextStore {
let candidates = metadata
.iter()
.enumerate()
.map(|(id, metadata)| StringMatchCandidate::new(id, metadata.title.clone()))
.map(|(id, metadata)| StringMatchCandidate::new(id, &metadata.title))
.collect::<Vec<_>>();
let matches = fuzzy::match_strings(
&candidates,

View file

@ -1439,10 +1439,7 @@ impl PromptStore {
.iter()
.enumerate()
.filter_map(|(ix, metadata)| {
Some(StringMatchCandidate::new(
ix,
metadata.title.as_ref()?.to_string(),
))
Some(StringMatchCandidate::new(ix, metadata.title.as_ref()?))
})
.collect::<Vec<_>>();
let matches = fuzzy::match_strings(

View file

@ -78,11 +78,7 @@ impl SlashCommandCompletionProvider {
.command_names(cx)
.into_iter()
.enumerate()
.map(|(ix, def)| StringMatchCandidate {
id: ix,
string: def.to_string(),
char_bag: def.as_ref().into(),
})
.map(|(ix, def)| StringMatchCandidate::new(ix, &def))
.collect::<Vec<_>>();
let command_name = command_name.to_string();
let editor = self.editor.clone();

View file

@ -218,10 +218,7 @@ impl Options {
}
fn match_candidates_for_args() -> [StringMatchCandidate; 1] {
[StringMatchCandidate::new(
0,
INCLUDE_WARNINGS_ARGUMENT.to_string(),
)]
[StringMatchCandidate::new(0, INCLUDE_WARNINGS_ARGUMENT)]
}
}

View file

@ -249,11 +249,7 @@ fn tab_items_for_queries(
.enumerate()
.filter_map(|(id, (full_path, ..))| {
let path_string = full_path.as_deref()?.to_string_lossy().to_string();
Some(fuzzy::StringMatchCandidate {
id,
char_bag: path_string.as_str().into(),
string: path_string,
})
Some(fuzzy::StringMatchCandidate::new(id, &path_string))
})
.collect::<Vec<_>>();
let mut processed_matches = HashSet::default();

View file

@ -381,11 +381,7 @@ impl MessageEditor {
let candidates = names
.into_iter()
.map(|user| StringMatchCandidate {
id: 0,
string: user.clone(),
char_bag: user.chars().collect(),
})
.map(|user| StringMatchCandidate::new(0, &user))
.collect::<Vec<_>>();
Some((start_anchor, query, candidates))
@ -401,11 +397,7 @@ impl MessageEditor {
LazyLock::new(|| {
let emojis = emojis::iter()
.flat_map(|s| s.shortcodes())
.map(|emoji| StringMatchCandidate {
id: 0,
string: emoji.to_string(),
char_bag: emoji.chars().collect(),
})
.map(|emoji| StringMatchCandidate::new(0, emoji))
.collect::<Vec<_>>();
emojis
});

View file

@ -393,11 +393,8 @@ impl CollabPanel {
// Populate the active user.
if let Some(user) = user_store.current_user() {
self.match_candidates.clear();
self.match_candidates.push(StringMatchCandidate {
id: 0,
string: user.github_login.clone(),
char_bag: user.github_login.chars().collect(),
});
self.match_candidates
.push(StringMatchCandidate::new(0, &user.github_login));
let matches = executor.block(match_strings(
&self.match_candidates,
&query,
@ -436,11 +433,10 @@ impl CollabPanel {
self.match_candidates.clear();
self.match_candidates
.extend(room.remote_participants().values().map(|participant| {
StringMatchCandidate {
id: participant.user.id as usize,
string: participant.user.github_login.clone(),
char_bag: participant.user.github_login.chars().collect(),
}
StringMatchCandidate::new(
participant.user.id as usize,
&participant.user.github_login,
)
}));
let mut matches = executor.block(match_strings(
&self.match_candidates,
@ -489,10 +485,8 @@ impl CollabPanel {
self.match_candidates.clear();
self.match_candidates
.extend(room.pending_participants().iter().enumerate().map(
|(id, participant)| StringMatchCandidate {
id,
string: participant.github_login.clone(),
char_bag: participant.github_login.chars().collect(),
|(id, participant)| {
StringMatchCandidate::new(id, &participant.github_login)
},
));
let matches = executor.block(match_strings(
@ -519,17 +513,12 @@ impl CollabPanel {
if channel_store.channel_count() > 0 || self.channel_editing_state.is_some() {
self.match_candidates.clear();
self.match_candidates
.extend(
channel_store
.ordered_channels()
.enumerate()
.map(|(ix, (_, channel))| StringMatchCandidate {
id: ix,
string: channel.name.clone().into(),
char_bag: channel.name.chars().collect(),
}),
);
self.match_candidates.extend(
channel_store
.ordered_channels()
.enumerate()
.map(|(ix, (_, channel))| StringMatchCandidate::new(ix, &channel.name)),
);
let matches = executor.block(match_strings(
&self.match_candidates,
&query,
@ -600,14 +589,12 @@ impl CollabPanel {
let channel_invites = channel_store.channel_invitations();
if !channel_invites.is_empty() {
self.match_candidates.clear();
self.match_candidates
.extend(channel_invites.iter().enumerate().map(|(ix, channel)| {
StringMatchCandidate {
id: ix,
string: channel.name.clone().into(),
char_bag: channel.name.chars().collect(),
}
}));
self.match_candidates.extend(
channel_invites
.iter()
.enumerate()
.map(|(ix, channel)| StringMatchCandidate::new(ix, &channel.name)),
);
let matches = executor.block(match_strings(
&self.match_candidates,
&query,
@ -637,17 +624,12 @@ impl CollabPanel {
let incoming = user_store.incoming_contact_requests();
if !incoming.is_empty() {
self.match_candidates.clear();
self.match_candidates
.extend(
incoming
.iter()
.enumerate()
.map(|(ix, user)| StringMatchCandidate {
id: ix,
string: user.github_login.clone(),
char_bag: user.github_login.chars().collect(),
}),
);
self.match_candidates.extend(
incoming
.iter()
.enumerate()
.map(|(ix, user)| StringMatchCandidate::new(ix, &user.github_login)),
);
let matches = executor.block(match_strings(
&self.match_candidates,
&query,
@ -666,17 +648,12 @@ impl CollabPanel {
let outgoing = user_store.outgoing_contact_requests();
if !outgoing.is_empty() {
self.match_candidates.clear();
self.match_candidates
.extend(
outgoing
.iter()
.enumerate()
.map(|(ix, user)| StringMatchCandidate {
id: ix,
string: user.github_login.clone(),
char_bag: user.github_login.chars().collect(),
}),
);
self.match_candidates.extend(
outgoing
.iter()
.enumerate()
.map(|(ix, user)| StringMatchCandidate::new(ix, &user.github_login)),
);
let matches = executor.block(match_strings(
&self.match_candidates,
&query,
@ -703,17 +680,12 @@ impl CollabPanel {
let contacts = user_store.contacts();
if !contacts.is_empty() {
self.match_candidates.clear();
self.match_candidates
.extend(
contacts
.iter()
.enumerate()
.map(|(ix, contact)| StringMatchCandidate {
id: ix,
string: contact.user.github_login.clone(),
char_bag: contact.user.github_login.chars().collect(),
}),
);
self.match_candidates.extend(
contacts
.iter()
.enumerate()
.map(|(ix, contact)| StringMatchCandidate::new(ix, &contact.user.github_login)),
);
let matches = executor.block(match_strings(
&self.match_candidates,

View file

@ -272,11 +272,7 @@ impl PickerDelegate for ChannelModalDelegate {
self.match_candidates.clear();
self.match_candidates
.extend(self.members.iter().enumerate().map(|(id, member)| {
StringMatchCandidate {
id,
string: member.user.github_login.clone(),
char_bag: member.user.github_login.chars().collect(),
}
StringMatchCandidate::new(id, &member.user.github_login)
}));
let matches = cx.background_executor().block(match_strings(

View file

@ -283,11 +283,7 @@ impl PickerDelegate for CommandPaletteDelegate {
let candidates = commands
.iter()
.enumerate()
.map(|(ix, command)| StringMatchCandidate {
id: ix,
string: command.name.to_string(),
char_bag: command.name.chars().collect(),
})
.map(|(ix, command)| StringMatchCandidate::new(ix, &command.name))
.collect::<Vec<_>>();
let matches = if query.is_empty() {
candidates

View file

@ -163,7 +163,7 @@ impl CompletionsMenu {
.map(|(id, completion)| {
StringMatchCandidate::new(
id,
completion.label.text[completion.label.filter_range.clone()].into(),
&completion.label.text[completion.label.filter_range.clone()],
)
})
.collect();
@ -211,7 +211,7 @@ impl CompletionsMenu {
let match_candidates = choices
.iter()
.enumerate()
.map(|(id, completion)| StringMatchCandidate::new(id, completion.to_string()))
.map(|(id, completion)| StringMatchCandidate::new(id, &completion))
.collect();
let matches = choices
.iter()

View file

@ -13293,7 +13293,7 @@ fn snippet_completions(
snippet
.prefix
.iter()
.map(move |prefix| StringMatchCandidate::new(ix, prefix.clone()))
.map(move |prefix| StringMatchCandidate::new(ix, &prefix))
})
.collect::<Vec<StringMatchCandidate>>();

View file

@ -113,13 +113,7 @@ impl PickerDelegate for ExtensionVersionSelectorDelegate {
.iter()
.enumerate()
.map(|(id, extension)| {
let text = format!("v{}", extension.manifest.version);
StringMatchCandidate {
id,
char_bag: text.as_str().into(),
string: text,
}
StringMatchCandidate::new(id, &format!("v{}", extension.manifest.version))
})
.collect::<Vec<_>>();

View file

@ -328,11 +328,7 @@ impl ExtensionsPage {
let match_candidates = dev_extensions
.iter()
.enumerate()
.map(|(ix, manifest)| StringMatchCandidate {
id: ix,
string: manifest.name.clone(),
char_bag: manifest.name.as_str().into(),
})
.map(|(ix, manifest)| StringMatchCandidate::new(ix, &manifest.name))
.collect::<Vec<_>>();
let matches = match_strings(

View file

@ -131,7 +131,7 @@ impl PickerDelegate for OpenPathDelegate {
.iter()
.enumerate()
.map(|(ix, path)| {
StringMatchCandidate::new(ix, path.to_string_lossy().into())
StringMatchCandidate::new(ix, &path.to_string_lossy())
})
.collect::<Vec<_>>();

View file

@ -18,22 +18,12 @@ pub struct StringMatchCandidate {
pub char_bag: CharBag,
}
impl Match for StringMatch {
fn score(&self) -> f64 {
self.score
}
fn set_positions(&mut self, positions: Vec<usize>) {
self.positions = positions;
}
}
impl StringMatchCandidate {
pub fn new(id: usize, string: String) -> Self {
pub fn new(id: usize, string: &str) -> Self {
Self {
id,
char_bag: CharBag::from(string.as_str()),
string,
string: string.into(),
char_bag: string.into(),
}
}
}
@ -56,6 +46,16 @@ pub struct StringMatch {
pub string: String,
}
impl Match for StringMatch {
fn score(&self) -> f64 {
self.score
}
fn set_positions(&mut self, positions: Vec<usize>) {
self.positions = positions;
}
}
impl StringMatch {
pub fn ranges(&self) -> impl '_ + Iterator<Item = Range<usize>> {
let mut positions = self.positions.iter().peekable();

View file

@ -208,7 +208,7 @@ impl IndexedDocsStore {
let candidates = items
.iter()
.enumerate()
.map(|(ix, item_path)| StringMatchCandidate::new(ix, item_path.clone()))
.map(|(ix, item_path)| StringMatchCandidate::new(ix, &item_path))
.collect::<Vec<_>>();
let matches = fuzzy::match_strings(

View file

@ -73,8 +73,8 @@ impl<T> Outline<T> {
.map(|range| &item.text[range.start..range.end])
.collect::<String>();
path_candidates.push(StringMatchCandidate::new(id, path_text.clone()));
candidates.push(StringMatchCandidate::new(id, candidate_text));
path_candidates.push(StringMatchCandidate::new(id, &path_text));
candidates.push(StringMatchCandidate::new(id, &candidate_text));
}
Self {

View file

@ -112,7 +112,7 @@ impl LanguageSelectorDelegate {
.then_some(name)
})
.enumerate()
.map(|(candidate_id, name)| StringMatchCandidate::new(candidate_id, name))
.map(|(candidate_id, name)| StringMatchCandidate::new(candidate_id, &name))
.collect::<Vec<_>>();
Self {

View file

@ -3296,40 +3296,32 @@ impl OutlinePanel {
if let Some(file_name) =
self.relative_path(fs_entry, cx).as_deref().map(file_name)
{
state.match_candidates.push(StringMatchCandidate {
id,
string: file_name.to_string(),
char_bag: file_name.chars().collect(),
});
state
.match_candidates
.push(StringMatchCandidate::new(id, &file_name));
}
}
PanelEntry::FoldedDirs(worktree_id, entries) => {
let dir_names = self.dir_names_string(entries, *worktree_id, cx);
{
state.match_candidates.push(StringMatchCandidate {
id,
string: dir_names.clone(),
char_bag: dir_names.chars().collect(),
});
state
.match_candidates
.push(StringMatchCandidate::new(id, &dir_names));
}
}
PanelEntry::Outline(outline_entry) => match outline_entry {
OutlineEntry::Outline(_, _, outline) => {
state.match_candidates.push(StringMatchCandidate {
id,
string: outline.text.clone(),
char_bag: outline.text.chars().collect(),
});
state
.match_candidates
.push(StringMatchCandidate::new(id, &outline.text));
}
OutlineEntry::Excerpt(..) => {}
},
PanelEntry::Search(new_search_entry) => {
if let Some(search_data) = new_search_entry.render_data.get() {
state.match_candidates.push(StringMatchCandidate {
id,
char_bag: search_data.context_text.chars().collect(),
string: search_data.context_text.clone(),
});
state
.match_candidates
.push(StringMatchCandidate::new(id, &search_data.context_text));
}
}
}

View file

@ -179,7 +179,7 @@ impl PickerDelegate for ProjectSymbolsDelegate {
.map(|(id, symbol)| {
StringMatchCandidate::new(
id,
symbol.label.text[symbol.label.filter_range.clone()].to_string(),
&symbol.label.text[symbol.label.filter_range.clone()],
)
})
.partition(|candidate| {
@ -313,7 +313,7 @@ mod tests {
let candidates = fake_symbols
.iter()
.enumerate()
.map(|(id, symbol)| StringMatchCandidate::new(id, symbol.name.clone()))
.map(|(id, symbol)| StringMatchCandidate::new(id, &symbol.name))
.collect::<Vec<_>>();
let matches = if params.query.is_empty() {
Vec::new()

View file

@ -228,7 +228,7 @@ impl PickerDelegate for RecentProjectsDelegate {
.join(""),
};
StringMatchCandidate::new(id, combined_string)
StringMatchCandidate::new(id, &combined_string)
})
.collect::<Vec<_>>();
self.matches = smol::block_on(fuzzy::match_strings(

View file

@ -96,7 +96,7 @@ impl ScopeSelectorDelegate {
let candidates = candidates
.chain(languages)
.enumerate()
.map(|(candidate_id, name)| StringMatchCandidate::new(candidate_id, name))
.map(|(candidate_id, name)| StringMatchCandidate::new(candidate_id, &name))
.collect::<Vec<_>>();
Self {

View file

@ -22,11 +22,7 @@ impl Delegate {
.iter()
.copied()
.enumerate()
.map(|(id, string)| StringMatchCandidate {
id,
char_bag: string.into(),
string: string.into(),
})
.map(|(id, string)| StringMatchCandidate::new(id, string))
.collect(),
matches: vec![],
selected_ix: 0,

View file

@ -516,7 +516,7 @@ fn string_match_candidates<'a>(
.map(|(index, (_, candidate))| StringMatchCandidate {
id: index,
char_bag: candidate.resolved_label.chars().collect(),
string: candidate.display_label().to_owned(),
string: candidate.display_label().into(),
})
.collect()
}

View file

@ -230,11 +230,7 @@ impl PickerDelegate for ThemeSelectorDelegate {
.themes
.iter()
.enumerate()
.map(|(id, meta)| StringMatchCandidate {
id,
char_bag: meta.name.as_ref().into(),
string: meta.name.to_string(),
})
.map(|(id, meta)| StringMatchCandidate::new(id, &meta.name))
.collect::<Vec<_>>();
cx.spawn(|this, mut cx| async move {

View file

@ -296,7 +296,7 @@ impl PickerDelegate for ToolchainSelectorDelegate {
.map(|(candidate_id, toolchain)| {
let path = Self::relativize_path(toolchain.path, &worktree_root_path);
let string = format!("{}{}", toolchain.name, path);
StringMatchCandidate::new(candidate_id, string)
StringMatchCandidate::new(candidate_id, &string)
})
.collect::<Vec<_>>();
match_strings(

View file

@ -172,11 +172,7 @@ impl PickerDelegate for BranchListDelegate {
branches
.into_iter()
.enumerate()
.map(|(ix, command)| StringMatchCandidate {
id: ix,
char_bag: command.name.chars().collect(),
string: command.name.into(),
})
.map(|(ix, command)| StringMatchCandidate::new(ix, &command.name))
.collect::<Vec<StringMatchCandidate>>()
});
let Some(candidates) = candidates.log_err() else {

View file

@ -127,11 +127,7 @@ impl PickerDelegate for BaseKeymapSelectorDelegate {
let background = cx.background_executor().clone();
let candidates = BaseKeymap::names()
.enumerate()
.map(|(id, name)| StringMatchCandidate {
id,
char_bag: name.into(),
string: name.into(),
})
.map(|(id, name)| StringMatchCandidate::new(id, name))
.collect::<Vec<_>>();
cx.spawn(|this, mut cx| async move {