file_finder: Fix open path prompt creating wrong highlight indices (#40488)
Fixes ZED-28R Release Notes: - Fixed open path prompt panicking on certain inputs
This commit is contained in:
@@ -669,7 +669,7 @@ impl PickerDelegate for OpenPathDelegate {
|
||||
) -> Option<Self::ListItem> {
|
||||
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::<Icon>(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::<Icon>(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(
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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<SharedString>, highlight_indices: Vec<usize>) -> 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,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user