diff --git a/yazi-core/src/completion/commands/show.rs b/yazi-core/src/completion/commands/show.rs index b6ccd4b9..83959213 100644 --- a/yazi-core/src/completion/commands/show.rs +++ b/yazi-core/src/completion/commands/show.rs @@ -39,40 +39,35 @@ impl Completion { let candidate_size = 30; // prioritize those with exact prefix - let exact_flow = cache.iter().try_fold(Vec::with_capacity(candidate_size), |mut v, s| { - if s.starts_with(opt.word) && s != opt.word { - v.push(s.to_owned()); - if v.len() >= candidate_size { - return ControlFlow::Break(v); - } - } - ControlFlow::Continue(v) - }); - let mut cand = match exact_flow { - ControlFlow::Continue(v) => v, - ControlFlow::Break(v) => v, - }; - - let fuzzy_flow = - cache.iter().try_fold(Vec::with_capacity(candidate_size - cand.len()), |mut v, s| { - if s.contains(opt.word) && !s.starts_with(opt.word) && s != opt.word { - v.push(s.to_owned()); - if v.len() >= candidate_size - cand.len() { - return ControlFlow::Break(v); + let candidates = cache.iter().try_fold( + (Vec::with_capacity(candidate_size), Vec::with_capacity(candidate_size)), + |(mut prefix_cand, mut fuzzy_cand), s| { + if s.starts_with(opt.word) { + if s != opt.word { + prefix_cand.push(s.to_owned()); + if prefix_cand.len() >= candidate_size { + return ControlFlow::Break((prefix_cand, fuzzy_cand)); + } } + } else if s.contains(opt.word) && fuzzy_cand.len() < candidate_size - prefix_cand.len() { + // here we don't break the control flow, since we want more exact matching. + fuzzy_cand.push(s.to_owned()) } - ControlFlow::Continue(v) - }); - cand.extend( - match fuzzy_flow { - ControlFlow::Continue(v) => v, - ControlFlow::Break(v) => v, - } - .into_iter(), + ControlFlow::Continue((prefix_cand, fuzzy_cand)) + }, ); self.ticket = opt.ticket; - self.cands = cand; + self.cands = { + let (mut prefix_cand, fuzzy_cand) = match candidates { + ControlFlow::Continue(v) => v, + ControlFlow::Break(v) => v, + }; + if prefix_cand.len() < candidate_size { + prefix_cand.extend(fuzzy_cand.into_iter().take(candidate_size - prefix_cand.len())) + } + prefix_cand + }; if self.cands.is_empty() { return mem::replace(&mut self.visible, false); }