mirror of
https://github.com/nushell/nushell.git
synced 2025-06-23 11:21:43 +02:00
Add substring match algorithm
This commit is contained in:
parent
67ea25afca
commit
8422b512da
@ -23,6 +23,12 @@ pub enum MatchAlgorithm {
|
||||
/// Example:
|
||||
/// "git checkout" is matched by "gco"
|
||||
Fuzzy,
|
||||
|
||||
/// Only show suggestions which have a substring matching with the given input
|
||||
///
|
||||
/// Example:
|
||||
/// "git checkout" is matched by "checkout"
|
||||
Substring,
|
||||
}
|
||||
|
||||
pub struct NuMatcher<'a, T> {
|
||||
@ -42,6 +48,10 @@ enum State<T> {
|
||||
/// Holds (haystack, item, score)
|
||||
items: Vec<(String, T, u16)>,
|
||||
},
|
||||
Substring {
|
||||
/// Holds (haystack, item)
|
||||
items: Vec<(String, T)>,
|
||||
},
|
||||
}
|
||||
|
||||
/// Filters and sorts suggestions
|
||||
@ -86,6 +96,18 @@ impl<T> NuMatcher<'_, T> {
|
||||
},
|
||||
}
|
||||
}
|
||||
MatchAlgorithm::Substring => {
|
||||
let lowercase_needle = if options.case_sensitive {
|
||||
needle.to_owned()
|
||||
} else {
|
||||
needle.to_folded_case()
|
||||
};
|
||||
NuMatcher {
|
||||
options,
|
||||
needle: lowercase_needle,
|
||||
state: State::Substring { items: Vec::new() },
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -130,6 +152,20 @@ impl<T> NuMatcher<'_, T> {
|
||||
}
|
||||
true
|
||||
}
|
||||
State::Substring { items } => {
|
||||
let haystack_folded = if self.options.case_sensitive {
|
||||
Cow::Borrowed(haystack)
|
||||
} else {
|
||||
Cow::Owned(haystack.to_folded_case())
|
||||
};
|
||||
let matches = haystack_folded.contains(self.needle.as_str());
|
||||
if matches {
|
||||
if let Some(item) = item {
|
||||
items.push((haystack.to_string(), item));
|
||||
}
|
||||
}
|
||||
matches
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -180,6 +216,20 @@ impl<T> NuMatcher<'_, T> {
|
||||
.map(|(_, item, _)| item)
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
State::Substring { mut items, .. } => {
|
||||
items.sort_by(|(haystack1, _), (haystack2, _)| {
|
||||
let cmp_sensitive = haystack1.cmp(haystack2);
|
||||
if self.options.case_sensitive {
|
||||
cmp_sensitive
|
||||
} else {
|
||||
haystack1
|
||||
.to_folded_case()
|
||||
.cmp(&haystack2.to_folded_case())
|
||||
.then(cmp_sensitive)
|
||||
}
|
||||
});
|
||||
items.into_iter().map(|(_, item)| item).collect::<Vec<_>>()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -196,6 +246,7 @@ impl From<CompletionAlgorithm> for MatchAlgorithm {
|
||||
match value {
|
||||
CompletionAlgorithm::Prefix => MatchAlgorithm::Prefix,
|
||||
CompletionAlgorithm::Fuzzy => MatchAlgorithm::Fuzzy,
|
||||
CompletionAlgorithm::Substring => MatchAlgorithm::Substring,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -207,6 +258,7 @@ impl TryFrom<String> for MatchAlgorithm {
|
||||
match value.as_str() {
|
||||
"prefix" => Ok(Self::Prefix),
|
||||
"fuzzy" => Ok(Self::Fuzzy),
|
||||
"substring" => Ok(Self::Substring),
|
||||
_ => Err(InvalidMatchAlgorithm::Unknown),
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ pub enum CompletionAlgorithm {
|
||||
#[default]
|
||||
Prefix,
|
||||
Fuzzy,
|
||||
Substring,
|
||||
}
|
||||
|
||||
impl FromStr for CompletionAlgorithm {
|
||||
@ -16,7 +17,8 @@ impl FromStr for CompletionAlgorithm {
|
||||
match s.to_ascii_lowercase().as_str() {
|
||||
"prefix" => Ok(Self::Prefix),
|
||||
"fuzzy" => Ok(Self::Fuzzy),
|
||||
_ => Err("'prefix' or 'fuzzy'"),
|
||||
"substring" => Ok(Self::Substring),
|
||||
_ => Err("'prefix' or 'fuzzy' or 'substring'"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user