@@ -9,11 +9,14 @@ use assistant_tool::{ToolSource, ToolWorkingSet};
use collections::HashMap;
use context_server::manager::ContextServerManager;
use fs::Fs;
-use gpui::{Action, AnyView, App, Entity, EventEmitter, FocusHandle, Focusable, Subscription};
+use gpui::{
+ Action, AnyView, App, Entity, EventEmitter, FocusHandle, Focusable, ScrollHandle, Subscription,
+};
use language_model::{LanguageModelProvider, LanguageModelProviderId, LanguageModelRegistry};
use settings::{Settings, update_settings_file};
use ui::{
- Disclosure, Divider, DividerColor, ElevationIndex, Indicator, Switch, Tooltip, prelude::*,
+ Disclosure, Divider, DividerColor, ElevationIndex, Indicator, Scrollbar, ScrollbarState,
+ Switch, Tooltip, prelude::*,
};
use util::ResultExt as _;
use zed_actions::ExtensionCategoryFilter;
@@ -31,6 +34,8 @@ pub struct AssistantConfiguration {
expanded_context_server_tools: HashMap<Arc<str>, bool>,
tools: Entity<ToolWorkingSet>,
_registry_subscription: Subscription,
+ scroll_handle: ScrollHandle,
+ scrollbar_state: ScrollbarState,
}
impl AssistantConfiguration {
@@ -60,6 +65,9 @@ impl AssistantConfiguration {
},
);
+ let scroll_handle = ScrollHandle::new();
+ let scrollbar_state = ScrollbarState::new(scroll_handle.clone());
+
let mut this = Self {
fs,
focus_handle,
@@ -68,6 +76,8 @@ impl AssistantConfiguration {
expanded_context_server_tools: HashMap::default(),
tools,
_registry_subscription: registry_subscription,
+ scroll_handle,
+ scrollbar_state,
};
this.build_provider_configuration_views(window, cx);
this
@@ -109,7 +119,7 @@ pub enum AssistantConfigurationEvent {
impl EventEmitter<AssistantConfigurationEvent> for AssistantConfiguration {}
impl AssistantConfiguration {
- fn render_provider_configuration(
+ fn render_provider_configuration_block(
&mut self,
provider: &Arc<dyn LanguageModelProvider>,
cx: &mut Context<Self>,
@@ -164,7 +174,7 @@ impl AssistantConfiguration {
.p(DynamicSpacing::Base08.rems(cx))
.bg(cx.theme().colors().editor_background)
.border_1()
- .border_color(cx.theme().colors().border_variant)
+ .border_color(cx.theme().colors().border)
.rounded_sm()
.map(|parent| match configuration_view {
Some(configuration_view) => parent.child(configuration_view),
@@ -175,6 +185,33 @@ impl AssistantConfiguration {
)
}
+ fn render_provider_configuration_section(
+ &mut self,
+ cx: &mut Context<Self>,
+ ) -> impl IntoElement {
+ let providers = LanguageModelRegistry::read_global(cx).providers();
+
+ v_flex()
+ .p(DynamicSpacing::Base16.rems(cx))
+ .pr(DynamicSpacing::Base20.rems(cx))
+ .gap_4()
+ .flex_1()
+ .child(
+ v_flex()
+ .gap_0p5()
+ .child(Headline::new("LLM Providers").size(HeadlineSize::Small))
+ .child(
+ Label::new("Add at least one provider to use AI-powered features.")
+ .color(Color::Muted),
+ ),
+ )
+ .children(
+ providers
+ .into_iter()
+ .map(|provider| self.render_provider_configuration_block(&provider, cx)),
+ )
+ }
+
fn render_command_permission(&mut self, cx: &mut Context<Self>) -> impl IntoElement {
let always_allow_tool_actions = AssistantSettings::get_global(cx).always_allow_tool_actions;
@@ -182,6 +219,7 @@ impl AssistantConfiguration {
v_flex()
.p(DynamicSpacing::Base16.rems(cx))
+ .pr(DynamicSpacing::Base20.rems(cx))
.gap_2()
.flex_1()
.child(Headline::new("General Settings").size(HeadlineSize::Small))
@@ -233,6 +271,7 @@ impl AssistantConfiguration {
v_flex()
.p(DynamicSpacing::Base16.rems(cx))
+ .pr(DynamicSpacing::Base20.rems(cx))
.gap_2()
.flex_1()
.child(
@@ -426,39 +465,51 @@ impl AssistantConfiguration {
impl Render for AssistantConfiguration {
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
- let providers = LanguageModelRegistry::read_global(cx).providers();
-
v_flex()
.id("assistant-configuration")
.key_context("AgentConfiguration")
.track_focus(&self.focus_handle(cx))
- .bg(cx.theme().colors().panel_background)
+ .relative()
.size_full()
- .overflow_y_scroll()
- .child(self.render_command_permission(cx))
- .child(Divider::horizontal().color(DividerColor::Border))
- .child(self.render_context_servers_section(cx))
- .child(Divider::horizontal().color(DividerColor::Border))
+ .pb_8()
+ .bg(cx.theme().colors().panel_background)
.child(
v_flex()
- .p(DynamicSpacing::Base16.rems(cx))
- .mt_1()
- .gap_6()
- .flex_1()
- .child(
- v_flex()
- .gap_0p5()
- .child(Headline::new("LLM Providers").size(HeadlineSize::Small))
- .child(
- Label::new("Add at least one provider to use AI-powered features.")
- .color(Color::Muted),
- ),
- )
- .children(
- providers
- .into_iter()
- .map(|provider| self.render_provider_configuration(&provider, cx)),
- ),
+ .id("assistant-configuration-content")
+ .track_scroll(&self.scroll_handle)
+ .size_full()
+ .overflow_y_scroll()
+ .child(self.render_command_permission(cx))
+ .child(Divider::horizontal().color(DividerColor::Border))
+ .child(self.render_context_servers_section(cx))
+ .child(Divider::horizontal().color(DividerColor::Border))
+ .child(self.render_provider_configuration_section(cx)),
+ )
+ .child(
+ div()
+ .id("assistant-configuration-scrollbar")
+ .occlude()
+ .absolute()
+ .right(px(3.))
+ .top_0()
+ .bottom_0()
+ .pb_6()
+ .w(px(12.))
+ .cursor_default()
+ .on_mouse_move(cx.listener(|_, _, _window, cx| {
+ cx.notify();
+ cx.stop_propagation()
+ }))
+ .on_hover(|_, _window, cx| {
+ cx.stop_propagation();
+ })
+ .on_any_mouse_down(|_, _window, cx| {
+ cx.stop_propagation();
+ })
+ .on_scroll_wheel(cx.listener(|_, _, _window, cx| {
+ cx.notify();
+ }))
+ .children(Scrollbar::vertical(self.scrollbar_state.clone())),
)
}
}