assistant: Improve the language model selector (#25125)

This PR includes change such as:

- Ensures the popover width is fixed/not dancing around
- Ensures the popover is not obscuring the trigger in the buffer and
terminal inline assistant scenarios
- Removes ellipsis from the trigger button label
- Ensures the scrollbar doesn't hide the check icon

| Terminal | Prompt Editor | Buffer |
|--------|--------|--------|
| ![Screenshot 2025-02-18 at 8 43
46 PM](https://github.com/user-attachments/assets/9cdfbaf1-f27e-4f48-877e-9cf61767ecee)
| ![Screenshot 2025-02-18 at 8 43
49 PM](https://github.com/user-attachments/assets/7abf9be2-bd2a-43d7-9a5d-d665e7e9fda3)
| ![Screenshot 2025-02-18 at 8 43
52 PM](https://github.com/user-attachments/assets/017bbdb3-185a-4bf6-9005-018ecafef9dd)
|

Release Notes:

- N/A
This commit is contained in:
Danilo Leal 2025-02-18 21:01:09 -03:00 committed by GitHub
parent a6006afdd7
commit 2627a5fdbe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 30 additions and 20 deletions

View file

@ -1610,6 +1610,7 @@ impl Render for PromptEditor {
cx,
)
},
gpui::Corner::TopRight,
))
.map(|el| {
let CodegenStatus::Error(error) = self.codegen.read(cx).status(cx) else {

View file

@ -662,6 +662,7 @@ impl Render for PromptEditor {
cx,
)
},
gpui::Corner::TopRight,
))
.children(
if let CodegenStatus::Error(error) = &self.codegen.read(cx).status {

View file

@ -61,13 +61,9 @@ impl Render for AssistantModelSelector {
h_flex()
.gap_0p5()
.child(
div().max_w_32().child(
Label::new(model_name)
.size(LabelSize::Small)
.color(Color::Muted)
.text_ellipsis()
.into_any_element(),
),
Label::new(model_name)
.size(LabelSize::Small)
.color(Color::Muted),
)
.child(
Icon::new(IconName::ChevronDown)
@ -84,6 +80,7 @@ impl Render for AssistantModelSelector {
cx,
)
},
gpui::Corner::BottomRight,
)
.with_handle(self.menu_handle.clone())
}

View file

@ -2404,13 +2404,9 @@ impl ContextEditor {
h_flex()
.gap_0p5()
.child(
div().max_w_32().child(
Label::new(model_name)
.size(LabelSize::Small)
.color(Color::Muted)
.text_ellipsis()
.into_any_element(),
),
Label::new(model_name)
.size(LabelSize::Small)
.color(Color::Muted),
)
.child(
Icon::new(IconName::ChevronDown)
@ -2427,6 +2423,7 @@ impl ContextEditor {
cx,
)
},
gpui::Corner::BottomLeft,
)
.with_handle(self.language_model_selector_menu_handle.clone())
}

View file

@ -2,8 +2,8 @@ use std::sync::Arc;
use feature_flags::ZedPro;
use gpui::{
Action, AnyElement, AnyView, App, DismissEvent, Entity, EventEmitter, FocusHandle, Focusable,
Subscription, Task, WeakEntity,
Action, AnyElement, AnyView, App, Corner, DismissEvent, Entity, EventEmitter, FocusHandle,
Focusable, Subscription, Task, WeakEntity,
};
use language_model::{LanguageModel, LanguageModelAvailability, LanguageModelRegistry};
use picker::{Picker, PickerDelegate};
@ -37,12 +37,13 @@ impl LanguageModelSelector {
on_model_changed: on_model_changed.clone(),
all_models: all_models.clone(),
filtered_models: all_models,
selected_index: 0,
selected_index: Self::get_active_model_index(cx),
};
let picker = cx.new(|cx| {
Picker::uniform_list(delegate, window, cx)
.show_scrollbar(true)
.width(rems(20.))
.max_height(Some(rems(20.).into()))
});
@ -100,6 +101,16 @@ impl LanguageModelSelector {
})
.collect::<Vec<_>>()
}
fn get_active_model_index(cx: &App) -> usize {
let active_model = LanguageModelRegistry::read_global(cx).active_model();
Self::all_models(cx)
.iter()
.position(|model_info| {
Some(model_info.model.id()) == active_model.as_ref().map(|model| model.id())
})
.unwrap_or(0)
}
}
impl EventEmitter<DismissEvent> for LanguageModelSelector {}
@ -126,6 +137,7 @@ where
trigger: T,
tooltip: TT,
handle: Option<PopoverMenuHandle<LanguageModelSelector>>,
anchor: Corner,
}
impl<T, TT> LanguageModelSelectorPopoverMenu<T, TT>
@ -137,12 +149,14 @@ where
language_model_selector: Entity<LanguageModelSelector>,
trigger: T,
tooltip: TT,
anchor: Corner,
) -> Self {
Self {
language_model_selector,
trigger,
tooltip,
handle: None,
anchor,
}
}
@ -163,7 +177,7 @@ where
PopoverMenu::new("model-switcher")
.menu(move |_window, _cx| Some(language_model_selector.clone()))
.trigger_with_tooltip(self.trigger, self.tooltip)
.anchor(gpui::Corner::BottomRight)
.anchor(self.anchor)
.when_some(self.handle.clone(), |menu, handle| menu.with_handle(handle))
.offset(gpui::Point {
x: px(0.0),
@ -360,7 +374,7 @@ impl PickerDelegate for LanguageModelPickerDelegate {
.items_center()
.gap_1p5()
.pl_0p5()
.min_w(px(240.))
.w(px(240.))
.child(
div().max_w_40().child(
Label::new(model_info.model.name().0.clone()).text_ellipsis(),
@ -387,7 +401,7 @@ impl PickerDelegate for LanguageModelPickerDelegate {
}),
),
)
.end_slot(div().when(is_selected, |this| {
.end_slot(div().pr_3().when(is_selected, |this| {
this.child(
Icon::new(IconName::Check)
.color(Color::Accent)