@@ -2,7 +2,7 @@ use context_server::{ContextServerSettings, ServerCommand, ServerConfig};
use gpui::{DismissEvent, Entity, EventEmitter, FocusHandle, Focusable, WeakEntity, prelude::*};
use serde_json::json;
use settings::update_settings_file;
-use ui::{Modal, ModalFooter, ModalHeader, Section, Tooltip, prelude::*};
+use ui::{KeyBinding, Modal, ModalFooter, ModalHeader, Section, Tooltip, prelude::*};
use ui_input::SingleLineInput;
use workspace::{ModalView, Workspace};
@@ -34,9 +34,9 @@ impl AddContextServerModal {
cx: &mut Context<Self>,
) -> Self {
let name_editor =
- cx.new(|cx| SingleLineInput::new(window, cx, "Your server name").label("Name"));
+ cx.new(|cx| SingleLineInput::new(window, cx, "my-custom-server").label("Name"));
let command_editor = cx.new(|cx| {
- SingleLineInput::new(window, cx, "Command").label("Command to run the context server")
+ SingleLineInput::new(window, cx, "Command").label("Command to run the MCP server")
});
Self {
@@ -46,7 +46,7 @@ impl AddContextServerModal {
}
}
- fn confirm(&mut self, cx: &mut Context<Self>) {
+ fn confirm(&mut self, _: &menu::Confirm, cx: &mut Context<Self>) {
let name = self
.name_editor
.read(cx)
@@ -96,7 +96,7 @@ impl AddContextServerModal {
cx.emit(DismissEvent);
}
- fn cancel(&mut self, cx: &mut Context<Self>) {
+ fn cancel(&mut self, _: &menu::Cancel, cx: &mut Context<Self>) {
cx.emit(DismissEvent);
}
}
@@ -112,38 +112,68 @@ impl Focusable for AddContextServerModal {
impl EventEmitter<DismissEvent> for AddContextServerModal {}
impl Render for AddContextServerModal {
- fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
+ fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let is_name_empty = self.name_editor.read(cx).is_empty(cx);
let is_command_empty = self.command_editor.read(cx).is_empty(cx);
+ let focus_handle = self.focus_handle(cx);
+
div()
.elevation_3(cx)
.w(rems(34.))
.key_context("AddContextServerModal")
- .on_action(cx.listener(|this, _: &menu::Cancel, _window, cx| this.cancel(cx)))
- .on_action(cx.listener(|this, _: &menu::Confirm, _window, cx| this.confirm(cx)))
+ .on_action(
+ cx.listener(|this, _: &menu::Cancel, _window, cx| this.cancel(&menu::Cancel, cx)),
+ )
+ .on_action(
+ cx.listener(|this, _: &menu::Confirm, _window, cx| {
+ this.confirm(&menu::Confirm, cx)
+ }),
+ )
.capture_any_mouse_down(cx.listener(|this, _, window, cx| {
this.focus_handle(cx).focus(window);
}))
.on_mouse_down_out(cx.listener(|_this, _, _, cx| cx.emit(DismissEvent)))
.child(
Modal::new("add-context-server", None)
- .header(ModalHeader::new().headline("Add Context Server"))
+ .header(ModalHeader::new().headline("Add MCP Server"))
.section(
- Section::new()
- .child(self.name_editor.clone())
- .child(self.command_editor.clone()),
+ Section::new().child(
+ v_flex()
+ .gap_2()
+ .child(self.name_editor.clone())
+ .child(self.command_editor.clone()),
+ ),
)
.footer(
ModalFooter::new()
.start_slot(
- Button::new("cancel", "Cancel").on_click(
- cx.listener(|this, _event, _window, cx| this.cancel(cx)),
- ),
+ Button::new("cancel", "Cancel")
+ .key_binding(
+ KeyBinding::for_action_in(
+ &menu::Cancel,
+ &focus_handle,
+ window,
+ cx,
+ )
+ .map(|kb| kb.size(rems_from_px(12.))),
+ )
+ .on_click(cx.listener(|this, _event, _window, cx| {
+ this.cancel(&menu::Cancel, cx)
+ })),
)
.end_slot(
Button::new("add-server", "Add Server")
.disabled(is_name_empty || is_command_empty)
+ .key_binding(
+ KeyBinding::for_action_in(
+ &menu::Confirm,
+ &focus_handle,
+ window,
+ cx,
+ )
+ .map(|kb| kb.size(rems_from_px(12.))),
+ )
.map(|button| {
if is_name_empty {
button.tooltip(Tooltip::text("Name is required"))
@@ -153,9 +183,9 @@ impl Render for AddContextServerModal {
button
}
})
- .on_click(
- cx.listener(|this, _event, _window, cx| this.confirm(cx)),
- ),
+ .on_click(cx.listener(|this, _event, _window, cx| {
+ this.confirm(&menu::Confirm, cx)
+ })),
),
),
)
@@ -47,7 +47,7 @@ use crate::thread_history::{PastContext, PastThread, ThreadHistory};
use crate::thread_store::ThreadStore;
use crate::ui::UsageBanner;
use crate::{
- AgentDiff, ExpandMessageEditor, InlineAssistant, NewTextThread, NewThread,
+ AddContextServer, AgentDiff, ExpandMessageEditor, InlineAssistant, NewTextThread, NewThread,
OpenActiveThreadAsMarkdown, OpenAgentDiff, OpenHistory, ThreadEvent, ToggleContextPicker,
};
@@ -1123,14 +1123,16 @@ impl AssistantPanel {
.action("Prompt Library", Box::new(OpenPromptLibrary::default()))
.action("Settings", Box::new(OpenConfiguration))
.separator()
+ .header("MCPs")
.action(
- "Install MCPs",
+ "View Server Extensions",
Box::new(zed_actions::Extensions {
category_filter: Some(
zed_actions::ExtensionCategoryFilter::ContextServers,
),
}),
)
+ .action("Add Custom Server", Box::new(AddContextServer))
},
))
}),