Allow render_match to return an Option to represent no matches

This commit is contained in:
Marshall Bowers 2023-11-28 10:33:13 -05:00
parent eac4b2d076
commit 63bd4ac999
4 changed files with 55 additions and 49 deletions

View file

@ -294,32 +294,34 @@ impl PickerDelegate for CommandPaletteDelegate {
ix: usize, ix: usize,
selected: bool, selected: bool,
cx: &mut ViewContext<Picker<Self>>, cx: &mut ViewContext<Picker<Self>>,
) -> Self::ListItem { ) -> Option<Self::ListItem> {
let colors = cx.theme().colors(); let colors = cx.theme().colors();
let Some(r#match) = self.matches.get(ix) else { let Some(r#match) = self.matches.get(ix) else {
return div(); return None;
}; };
let Some(command) = self.commands.get(r#match.candidate_id) else { let Some(command) = self.commands.get(r#match.candidate_id) else {
return div(); return None;
}; };
div() Some(
.px_1() div()
.text_color(colors.text) .px_1()
.text_ui() .text_color(colors.text)
.bg(colors.ghost_element_background) .text_ui()
.rounded_md() .bg(colors.ghost_element_background)
.when(selected, |this| this.bg(colors.ghost_element_selected)) .rounded_md()
.hover(|this| this.bg(colors.ghost_element_hover)) .when(selected, |this| this.bg(colors.ghost_element_selected))
.child( .hover(|this| this.bg(colors.ghost_element_hover))
h_stack() .child(
.justify_between() h_stack()
.child(HighlightedLabel::new( .justify_between()
command.name.clone(), .child(HighlightedLabel::new(
r#match.positions.clone(), command.name.clone(),
)) r#match.positions.clone(),
.children(KeyBinding::for_action(&*command.action, cx)), ))
) .children(KeyBinding::for_action(&*command.action, cx)),
),
)
} }
} }

View file

@ -711,7 +711,7 @@ impl PickerDelegate for FileFinderDelegate {
ix: usize, ix: usize,
selected: bool, selected: bool,
cx: &mut ViewContext<Picker<Self>>, cx: &mut ViewContext<Picker<Self>>,
) -> Self::ListItem { ) -> Option<Self::ListItem> {
let path_match = self let path_match = self
.matches .matches
.get(ix) .get(ix)
@ -722,19 +722,21 @@ impl PickerDelegate for FileFinderDelegate {
let (file_name, file_name_positions, full_path, full_path_positions) = let (file_name, file_name_positions, full_path, full_path_positions) =
self.labels_for_match(path_match, cx, ix); self.labels_for_match(path_match, cx, ix);
div() Some(
.px_1() div()
.text_color(colors.text) .px_1()
.text_ui() .text_color(colors.text)
.bg(colors.ghost_element_background) .text_ui()
.rounded_md() .bg(colors.ghost_element_background)
.when(selected, |this| this.bg(colors.ghost_element_selected)) .rounded_md()
.hover(|this| this.bg(colors.ghost_element_hover)) .when(selected, |this| this.bg(colors.ghost_element_selected))
.child( .hover(|this| this.bg(colors.ghost_element_hover))
v_stack() .child(
.child(HighlightedLabel::new(file_name, file_name_positions)) v_stack()
.child(HighlightedLabel::new(full_path, full_path_positions)), .child(HighlightedLabel::new(file_name, file_name_positions))
) .child(HighlightedLabel::new(full_path, full_path_positions)),
),
)
} }
} }

View file

@ -32,7 +32,7 @@ pub trait PickerDelegate: Sized + 'static {
ix: usize, ix: usize,
selected: bool, selected: bool,
cx: &mut ViewContext<Picker<Self>>, cx: &mut ViewContext<Picker<Self>>,
) -> Self::ListItem; ) -> Option<Self::ListItem>;
} }
impl<D: PickerDelegate> FocusableView for Picker<D> { impl<D: PickerDelegate> FocusableView for Picker<D> {
@ -230,7 +230,7 @@ impl<D: PickerDelegate> Render for Picker<D> {
) )
}), }),
) )
.child(picker.delegate.render_match( .children(picker.delegate.render_match(
ix, ix,
ix == selected_index, ix == selected_index,
cx, cx,

View file

@ -51,25 +51,27 @@ impl PickerDelegate for Delegate {
ix: usize, ix: usize,
selected: bool, selected: bool,
cx: &mut gpui::ViewContext<Picker<Self>>, cx: &mut gpui::ViewContext<Picker<Self>>,
) -> Self::ListItem { ) -> Option<Self::ListItem> {
let colors = cx.theme().colors(); let colors = cx.theme().colors();
let Some(candidate_ix) = self.matches.get(ix) else { let Some(candidate_ix) = self.matches.get(ix) else {
return div(); return None;
}; };
// TASK: Make StringMatchCandidate::string a SharedString // TASK: Make StringMatchCandidate::string a SharedString
let candidate = SharedString::from(self.candidates[*candidate_ix].string.clone()); let candidate = SharedString::from(self.candidates[*candidate_ix].string.clone());
div() Some(
.text_color(colors.text) div()
.when(selected, |s| { .text_color(colors.text)
s.border_l_10().border_color(colors.terminal_ansi_yellow) .when(selected, |s| {
}) s.border_l_10().border_color(colors.terminal_ansi_yellow)
.hover(|style| { })
style .hover(|style| {
.bg(colors.element_active) style
.text_color(colors.text_accent) .bg(colors.element_active)
}) .text_color(colors.text_accent)
.child(candidate) })
.child(candidate),
)
} }
fn selected_index(&self) -> usize { fn selected_index(&self) -> usize {