diff --git a/crates/file_finder/src/open_path_prompt.rs b/crates/file_finder/src/open_path_prompt.rs index b199c61a5e3b78ab656add6b0b1cfcc80a3ada74..694ef1eaceb720c3b63d4ca9d243ab73e9442970 100644 --- a/crates/file_finder/src/open_path_prompt.rs +++ b/crates/file_finder/src/open_path_prompt.rs @@ -669,7 +669,7 @@ impl PickerDelegate for OpenPathDelegate { ) -> Option { let settings = FileFinderSettings::get_global(cx); let candidate = self.get_entry(ix)?; - let match_positions = match &self.directory_state { + let mut match_positions = match &self.directory_state { DirectoryState::List { .. } => self.string_matches.get(ix)?.positions.clone(), DirectoryState::Create { user_input, .. } => { if let Some(user_input) = user_input { @@ -710,29 +710,38 @@ impl PickerDelegate for OpenPathDelegate { }); match &self.directory_state { - DirectoryState::List { parent_path, .. } => Some( - ListItem::new(ix) - .spacing(ListItemSpacing::Sparse) - .start_slot::(file_icon) - .inset(true) - .toggle_state(selected) - .child(HighlightedLabel::new( - if parent_path == &self.prompt_root { - format!("{}{}", self.prompt_root, candidate.path.string) - } else if is_current_dir_candidate { - "open this directory".to_string() - } else { - candidate.path.string - }, + DirectoryState::List { parent_path, .. } => { + let (label, indices) = if *parent_path == self.prompt_root { + match_positions.iter_mut().for_each(|position| { + *position += self.prompt_root.len(); + }); + ( + format!("{}{}", self.prompt_root, candidate.path.string), match_positions, - )), - ), + ) + } else if is_current_dir_candidate { + ("open this directory".to_string(), vec![]) + } else { + (candidate.path.string, match_positions) + }; + Some( + ListItem::new(ix) + .spacing(ListItemSpacing::Sparse) + .start_slot::(file_icon) + .inset(true) + .toggle_state(selected) + .child(HighlightedLabel::new(label, indices)), + ) + } DirectoryState::Create { parent_path, user_input, .. } => { - let (label, delta) = if parent_path == &self.prompt_root { + let (label, delta) = if *parent_path == self.prompt_root { + match_positions.iter_mut().for_each(|position| { + *position += self.prompt_root.len(); + }); ( format!("{}{}", self.prompt_root, candidate.path.string), self.prompt_root.len(), @@ -740,10 +749,10 @@ impl PickerDelegate for OpenPathDelegate { } else { (candidate.path.string.clone(), 0) }; - let label_len = label.len(); let label_with_highlights = match user_input { Some(user_input) => { + let label_len = label.len(); if user_input.file.string == candidate.path.string { if user_input.exists { let label = if user_input.is_dir { @@ -772,20 +781,10 @@ impl PickerDelegate for OpenPathDelegate { .into_any_element() } } else { - let mut highlight_positions = match_positions; - highlight_positions.iter_mut().for_each(|position| { - *position += delta; - }); - HighlightedLabel::new(label, highlight_positions).into_any_element() + HighlightedLabel::new(label, match_positions).into_any_element() } } - None => { - let mut highlight_positions = match_positions; - highlight_positions.iter_mut().for_each(|position| { - *position += delta; - }); - HighlightedLabel::new(label, highlight_positions).into_any_element() - } + None => HighlightedLabel::new(label, match_positions).into_any_element(), }; Some( diff --git a/crates/git_ui/src/picker_prompt.rs b/crates/git_ui/src/picker_prompt.rs index 9997b0590cedfeab7cad6a7c52bce63f10657a80..6161c62af571f3a90c3110d63cc26ea3a7e032ae 100644 --- a/crates/git_ui/src/picker_prompt.rs +++ b/crates/git_ui/src/picker_prompt.rs @@ -228,7 +228,7 @@ impl PickerDelegate for PickerPromptDelegate { let highlights: Vec<_> = hit .positions .iter() - .filter(|index| index < &&self.max_match_length) + .filter(|&&index| index < self.max_match_length) .copied() .collect(); diff --git a/crates/ui/src/components/label/highlighted_label.rs b/crates/ui/src/components/label/highlighted_label.rs index a3cbc33553f701b1c744b04d4e0481a2bd9de129..840bba7b173fe31a3472d758c64b0b1ef984da2c 100644 --- a/crates/ui/src/components/label/highlighted_label.rs +++ b/crates/ui/src/components/label/highlighted_label.rs @@ -15,9 +15,16 @@ impl HighlightedLabel { /// Constructs a label with the given characters highlighted. /// Characters are identified by UTF-8 byte position. pub fn new(label: impl Into, highlight_indices: Vec) -> Self { + let label = label.into(); + for &run in &highlight_indices { + assert!( + label.is_char_boundary(run), + "highlight index {run} is not a valid UTF-8 boundary" + ); + } Self { base: LabelLike::new(), - label: label.into(), + label, highlight_indices, } }