Compare commits
7 Commits
inline-ass
...
stateful-r
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
80c2f9dc6c | ||
|
|
baf90b31c9 | ||
|
|
e8e66428f0 | ||
|
|
946ef41822 | ||
|
|
0135d1ae27 | ||
|
|
feee7b3f27 | ||
|
|
99840ce814 |
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -16012,7 +16012,6 @@ dependencies = [
|
||||
"outline_panel",
|
||||
"parking_lot",
|
||||
"paths",
|
||||
"picker",
|
||||
"profiling",
|
||||
"project",
|
||||
"project_panel",
|
||||
|
||||
@@ -2,27 +2,29 @@ use crate::kernels::KernelSpecification;
|
||||
use crate::repl_store::ReplStore;
|
||||
use crate::KERNEL_DOCS_URL;
|
||||
|
||||
use editor::Editor;
|
||||
use gpui::DismissEvent;
|
||||
|
||||
use gpui::FontWeight;
|
||||
use gpui::WeakView;
|
||||
use picker::Picker;
|
||||
use picker::PickerDelegate;
|
||||
use project::WorktreeId;
|
||||
use ui::ButtonLike;
|
||||
use ui::Tooltip;
|
||||
|
||||
use std::sync::Arc;
|
||||
use ui::ListItemSpacing;
|
||||
|
||||
use gpui::SharedString;
|
||||
use gpui::Task;
|
||||
use ui::{prelude::*, ListItem, PopoverMenu, PopoverMenuHandle, PopoverTrigger};
|
||||
use ui::{prelude::*, ListItem, PopoverMenu, PopoverMenuHandle};
|
||||
|
||||
type OnSelect = Box<dyn Fn(KernelSpecification, &mut WindowContext)>;
|
||||
pub type OnSelect = Box<dyn Fn(KernelSpecification, &mut WindowContext)>;
|
||||
|
||||
#[derive(IntoElement)]
|
||||
pub struct KernelSelector<T: PopoverTrigger> {
|
||||
pub struct KernelSelector {
|
||||
handle: Option<PopoverMenuHandle<Picker<KernelPickerDelegate>>>,
|
||||
on_select: OnSelect,
|
||||
trigger: T,
|
||||
editor: WeakView<Editor>,
|
||||
info_text: Option<SharedString>,
|
||||
worktree_id: WorktreeId,
|
||||
}
|
||||
@@ -32,6 +34,7 @@ pub struct KernelPickerDelegate {
|
||||
filtered_kernels: Vec<KernelSpecification>,
|
||||
selected_kernelspec: Option<KernelSpecification>,
|
||||
on_select: OnSelect,
|
||||
group: Group,
|
||||
}
|
||||
|
||||
// Helper function to truncate long paths
|
||||
@@ -44,12 +47,15 @@ fn truncate_path(path: &SharedString, max_length: usize) -> SharedString {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PopoverTrigger> KernelSelector<T> {
|
||||
pub fn new(on_select: OnSelect, worktree_id: WorktreeId, trigger: T) -> Self {
|
||||
impl KernelSelector {
|
||||
pub fn new(
|
||||
worktree_id: WorktreeId,
|
||||
editor: WeakView<Editor>,
|
||||
_cx: &mut ViewContext<Self>,
|
||||
) -> Self {
|
||||
KernelSelector {
|
||||
on_select,
|
||||
editor,
|
||||
handle: None,
|
||||
trigger,
|
||||
info_text: None,
|
||||
worktree_id,
|
||||
}
|
||||
@@ -66,6 +72,14 @@ impl<T: PopoverTrigger> KernelSelector<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub enum Group {
|
||||
All,
|
||||
Jupyter,
|
||||
Python,
|
||||
Remote,
|
||||
}
|
||||
|
||||
impl PickerDelegate for KernelPickerDelegate {
|
||||
type ListItem = ListItem;
|
||||
|
||||
@@ -204,6 +218,75 @@ impl PickerDelegate for KernelPickerDelegate {
|
||||
)
|
||||
}
|
||||
|
||||
fn render_header(&self, cx: &mut ViewContext<Picker<Self>>) -> Option<gpui::AnyElement> {
|
||||
let mode = Group::All;
|
||||
|
||||
Some(
|
||||
h_flex()
|
||||
.child(
|
||||
div()
|
||||
.id("all")
|
||||
.px_2()
|
||||
.py_1()
|
||||
.cursor_pointer()
|
||||
.border_b_2()
|
||||
.when(mode == Group::All, |this| {
|
||||
this.border_color(cx.theme().colors().border)
|
||||
})
|
||||
.child(Label::new("All"))
|
||||
.on_click(cx.listener(|this, _, cx| {
|
||||
this.delegate.set_group(Group::All, cx);
|
||||
})),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.id("jupyter")
|
||||
.px_2()
|
||||
.py_1()
|
||||
.cursor_pointer()
|
||||
.border_b_2()
|
||||
.when(mode == Group::Jupyter, |this| {
|
||||
this.border_color(cx.theme().colors().border)
|
||||
})
|
||||
.child(Label::new("Jupyter"))
|
||||
.on_click(cx.listener(|this, _, cx| {
|
||||
this.delegate.set_group(Group::Jupyter, cx);
|
||||
})),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.id("python")
|
||||
.px_2()
|
||||
.py_1()
|
||||
.cursor_pointer()
|
||||
.border_b_2()
|
||||
.when(mode == Group::Python, |this| {
|
||||
this.border_color(cx.theme().colors().border)
|
||||
})
|
||||
.child(Label::new("Python"))
|
||||
.on_click(cx.listener(|this, _, cx| {
|
||||
this.delegate.set_group(Group::Python, cx);
|
||||
})),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.id("remote")
|
||||
.px_2()
|
||||
.py_1()
|
||||
.cursor_pointer()
|
||||
.border_b_2()
|
||||
.when(mode == Group::Remote, |this| {
|
||||
this.border_color(cx.theme().colors().border)
|
||||
})
|
||||
.child(Label::new("Remote"))
|
||||
.on_click(cx.listener(|this, _, cx| {
|
||||
this.delegate.set_group(Group::Remote, cx);
|
||||
})),
|
||||
)
|
||||
.into_any_element(),
|
||||
)
|
||||
}
|
||||
|
||||
fn render_footer(&self, cx: &mut ViewContext<Picker<Self>>) -> Option<gpui::AnyElement> {
|
||||
Some(
|
||||
h_flex()
|
||||
@@ -225,8 +308,29 @@ impl PickerDelegate for KernelPickerDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PopoverTrigger> RenderOnce for KernelSelector<T> {
|
||||
fn render(self, cx: &mut WindowContext) -> impl IntoElement {
|
||||
impl KernelPickerDelegate {
|
||||
fn new(
|
||||
on_select: OnSelect,
|
||||
kernels: Vec<KernelSpecification>,
|
||||
selected_kernelspec: Option<KernelSpecification>,
|
||||
) -> Self {
|
||||
Self {
|
||||
on_select,
|
||||
all_kernels: kernels.clone(),
|
||||
filtered_kernels: kernels,
|
||||
group: Group::All,
|
||||
selected_kernelspec,
|
||||
}
|
||||
}
|
||||
|
||||
fn set_group(&mut self, group: Group, cx: &mut ViewContext<Picker<Self>>) {
|
||||
self.group = group;
|
||||
cx.notify();
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for KernelSelector {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||
let store = ReplStore::global(cx).read(cx);
|
||||
|
||||
let all_kernels: Vec<KernelSpecification> = store
|
||||
@@ -235,13 +339,18 @@ impl<T: PopoverTrigger> RenderOnce for KernelSelector<T> {
|
||||
.collect();
|
||||
|
||||
let selected_kernelspec = store.active_kernelspec(self.worktree_id, None, cx);
|
||||
let current_kernel_name = selected_kernelspec.as_ref().map(|spec| spec.name()).clone();
|
||||
|
||||
let delegate = KernelPickerDelegate {
|
||||
on_select: self.on_select,
|
||||
all_kernels: all_kernels.clone(),
|
||||
filtered_kernels: all_kernels,
|
||||
selected_kernelspec,
|
||||
};
|
||||
let editor = self.editor.clone();
|
||||
let on_select: OnSelect = Box::new(move |kernelspec, cx| {
|
||||
crate::assign_kernelspec(kernelspec, editor.clone(), cx).ok();
|
||||
});
|
||||
|
||||
let menu_handle: PopoverMenuHandle<Picker<KernelPickerDelegate>> =
|
||||
PopoverMenuHandle::default();
|
||||
|
||||
let delegate =
|
||||
KernelPickerDelegate::new(on_select, all_kernels, selected_kernelspec.clone());
|
||||
|
||||
let picker_view = cx.new_view(|cx| {
|
||||
let picker = Picker::uniform_list(delegate, cx)
|
||||
@@ -252,8 +361,42 @@ impl<T: PopoverTrigger> RenderOnce for KernelSelector<T> {
|
||||
|
||||
PopoverMenu::new("kernel-switcher")
|
||||
.menu(move |_cx| Some(picker_view.clone()))
|
||||
.trigger(self.trigger)
|
||||
.trigger(
|
||||
ButtonLike::new("kernel-selector")
|
||||
.style(ButtonStyle::Subtle)
|
||||
.child(
|
||||
h_flex()
|
||||
.w_full()
|
||||
.gap_0p5()
|
||||
.child(
|
||||
div()
|
||||
.overflow_x_hidden()
|
||||
.flex_grow()
|
||||
.whitespace_nowrap()
|
||||
.child(
|
||||
Label::new(if let Some(name) = current_kernel_name {
|
||||
name
|
||||
} else {
|
||||
SharedString::from("Select Kernel")
|
||||
})
|
||||
.size(LabelSize::Small)
|
||||
.color(if selected_kernelspec.is_some() {
|
||||
Color::Default
|
||||
} else {
|
||||
Color::Placeholder
|
||||
})
|
||||
.into_any_element(),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
Icon::new(IconName::ChevronDown)
|
||||
.color(Color::Muted)
|
||||
.size(IconSize::XSmall),
|
||||
),
|
||||
)
|
||||
.tooltip(move |cx| Tooltip::text("Select Kernel", cx)),
|
||||
)
|
||||
.attach(gpui::AnchorCorner::BottomLeft)
|
||||
.when_some(self.handle, |menu, handle| menu.with_handle(handle))
|
||||
.with_handle(menu_handle)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,6 @@ outline.workspace = true
|
||||
outline_panel.workspace = true
|
||||
parking_lot.workspace = true
|
||||
paths.workspace = true
|
||||
picker.workspace = true
|
||||
profiling.workspace = true
|
||||
project.workspace = true
|
||||
project_panel.workspace = true
|
||||
|
||||
@@ -13,6 +13,8 @@ use gpui::{
|
||||
Action, AnchorCorner, ClickEvent, ElementId, EventEmitter, FocusHandle, FocusableView,
|
||||
InteractiveElement, ParentElement, Render, Styled, Subscription, View, ViewContext, WeakView,
|
||||
};
|
||||
use repl::worktree_id_for_editor;
|
||||
use repl_menu::ReplMenu;
|
||||
use search::{buffer_search, BufferSearchBar};
|
||||
use settings::{Settings, SettingsStore};
|
||||
use ui::{
|
||||
@@ -33,6 +35,7 @@ pub struct QuickActionBar {
|
||||
toggle_selections_handle: PopoverMenuHandle<ContextMenu>,
|
||||
toggle_settings_handle: PopoverMenuHandle<ContextMenu>,
|
||||
workspace: WeakView<Workspace>,
|
||||
repl_menu: Option<View<ReplMenu>>,
|
||||
}
|
||||
|
||||
impl QuickActionBar {
|
||||
@@ -49,6 +52,7 @@ impl QuickActionBar {
|
||||
toggle_selections_handle: Default::default(),
|
||||
toggle_settings_handle: Default::default(),
|
||||
workspace: workspace.weak_handle(),
|
||||
repl_menu: None,
|
||||
};
|
||||
this.apply_settings(cx);
|
||||
cx.observe_global::<SettingsStore>(|this, cx| this.apply_settings(cx))
|
||||
@@ -350,7 +354,7 @@ impl Render for QuickActionBar {
|
||||
h_flex()
|
||||
.id("quick action bar")
|
||||
.gap(DynamicSpacing::Base06.rems(cx))
|
||||
.children(self.render_repl_menu(cx))
|
||||
.children(self.repl_menu.clone())
|
||||
.children(self.render_toggle_markdown_preview(self.workspace.clone(), cx))
|
||||
.children(search_button)
|
||||
.when(
|
||||
@@ -425,7 +429,15 @@ impl ToolbarItemView for QuickActionBar {
|
||||
if let Some(active_item) = active_pane_item {
|
||||
self._inlay_hints_enabled_subscription.take();
|
||||
|
||||
if let Some(editor) = active_item.downcast::<Editor>() {
|
||||
let editor = active_item.downcast::<Editor>();
|
||||
|
||||
let work_tree_id = active_item
|
||||
.downcast::<Editor>()
|
||||
.and_then(|editor| worktree_id_for_editor(editor.downgrade(), cx));
|
||||
|
||||
if let (Some(editor), Some(work_tree_id)) = (editor, work_tree_id) {
|
||||
self.repl_menu =
|
||||
Some(cx.new_view(|cx| ReplMenu::new(work_tree_id, editor.downgrade(), cx)));
|
||||
let mut inlay_hints_enabled = editor.read(cx).inlay_hints_enabled();
|
||||
let mut supports_inlay_hints = editor.read(cx).supports_inlay_hints(cx);
|
||||
self._inlay_hints_enabled_subscription =
|
||||
@@ -441,6 +453,8 @@ impl ToolbarItemView for QuickActionBar {
|
||||
cx.notify()
|
||||
}
|
||||
}));
|
||||
} else {
|
||||
self.repl_menu = None
|
||||
}
|
||||
}
|
||||
self.get_toolbar_item_location()
|
||||
|
||||
@@ -1,24 +1,22 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use gpui::ElementId;
|
||||
use editor::Editor;
|
||||
use gpui::{percentage, Animation, AnimationExt, AnyElement, Transformation, View};
|
||||
use picker::Picker;
|
||||
use gpui::{ElementId, WeakView};
|
||||
use project::WorktreeId;
|
||||
use repl::{
|
||||
components::{KernelPickerDelegate, KernelSelector},
|
||||
worktree_id_for_editor, ExecutionState, JupyterSettings, Kernel, KernelSpecification,
|
||||
components::KernelSelector, ExecutionState, JupyterSettings, Kernel, KernelSpecification,
|
||||
KernelStatus, Session, SessionSupport,
|
||||
};
|
||||
use ui::{
|
||||
prelude::*, ButtonLike, ContextMenu, IconWithIndicator, Indicator, IntoElement, PopoverMenu,
|
||||
PopoverMenuHandle, Tooltip,
|
||||
Tooltip,
|
||||
};
|
||||
use util::ResultExt;
|
||||
|
||||
use super::QuickActionBar;
|
||||
|
||||
const ZED_REPL_DOCUMENTATION: &str = "https://zed.dev/docs/repl";
|
||||
|
||||
struct ReplMenuState {
|
||||
struct ReplSessionState {
|
||||
tooltip: SharedString,
|
||||
icon: IconName,
|
||||
icon_color: Color,
|
||||
@@ -31,47 +29,73 @@ struct ReplMenuState {
|
||||
kernel_language: SharedString,
|
||||
}
|
||||
|
||||
impl QuickActionBar {
|
||||
pub fn render_repl_menu(&self, cx: &mut ViewContext<Self>) -> Option<AnyElement> {
|
||||
pub struct ReplMenu {
|
||||
active_editor: WeakView<Editor>,
|
||||
kernel_menu: View<KernelSelector>,
|
||||
}
|
||||
|
||||
impl ReplMenu {
|
||||
pub fn new(
|
||||
work_tree_id: WorktreeId,
|
||||
editor: WeakView<Editor>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Self {
|
||||
Self {
|
||||
kernel_menu: cx.new_view(|cx| KernelSelector::new(work_tree_id, editor.clone(), cx)),
|
||||
active_editor: editor.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for ReplMenu {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||
if !JupyterSettings::enabled(cx) {
|
||||
return None;
|
||||
return div().into_any_element();
|
||||
}
|
||||
|
||||
let editor = self.active_editor()?;
|
||||
let editor = self.active_editor.clone();
|
||||
|
||||
let is_local_project = editor
|
||||
.read(cx)
|
||||
.workspace()
|
||||
.map(|workspace| workspace.read(cx).project().read(cx).is_local())
|
||||
.upgrade()
|
||||
.as_ref()
|
||||
.map(|editor| {
|
||||
editor
|
||||
.read(cx)
|
||||
.workspace()
|
||||
.map(|workspace| workspace.read(cx).project().read(cx).is_local())
|
||||
.unwrap_or(false)
|
||||
})
|
||||
.unwrap_or(false);
|
||||
|
||||
if !is_local_project {
|
||||
return None;
|
||||
return div().into_any_element();
|
||||
}
|
||||
|
||||
let has_nonempty_selection = {
|
||||
editor.update(cx, |this, cx| {
|
||||
this.selections
|
||||
.count()
|
||||
.ne(&0)
|
||||
.then(|| {
|
||||
let latest = this.selections.newest_display(cx);
|
||||
!latest.is_empty()
|
||||
})
|
||||
.unwrap_or_default()
|
||||
})
|
||||
editor
|
||||
.update(cx, |this, cx| {
|
||||
this.selections
|
||||
.count()
|
||||
.ne(&0)
|
||||
.then(|| {
|
||||
let latest = this.selections.newest_display(cx);
|
||||
!latest.is_empty()
|
||||
})
|
||||
.unwrap_or_default()
|
||||
})
|
||||
.unwrap_or(false)
|
||||
};
|
||||
|
||||
let session = repl::session(editor.downgrade(), cx);
|
||||
let session = repl::session(editor.clone(), cx);
|
||||
let session = match session {
|
||||
SessionSupport::ActiveSession(session) => session,
|
||||
SessionSupport::Inactive(spec) => {
|
||||
return self.render_repl_launch_menu(spec, cx);
|
||||
return self.render_repl_launch_menu(spec, cx).into_any_element();
|
||||
}
|
||||
SessionSupport::RequiresSetup(language) => {
|
||||
return self.render_repl_setup(&language.0, cx);
|
||||
return self.render_repl_setup(&language.0, cx).into_any_element();
|
||||
}
|
||||
SessionSupport::Unsupported => return None,
|
||||
SessionSupport::Unsupported => return div().into_any_element(),
|
||||
};
|
||||
|
||||
let menu_state = session_state(session.clone(), cx);
|
||||
@@ -80,7 +104,7 @@ impl QuickActionBar {
|
||||
|
||||
let element_id = |suffix| ElementId::Name(format!("{}-{}", id, suffix).into());
|
||||
|
||||
let editor = editor.downgrade();
|
||||
let editor = editor.clone();
|
||||
let dropdown_menu = PopoverMenu::new(element_id("menu"))
|
||||
.menu(move |cx| {
|
||||
let editor = editor.clone();
|
||||
@@ -245,138 +269,85 @@ impl QuickActionBar {
|
||||
.on_click(|_, cx| cx.dispatch_action(Box::new(repl::Run {})))
|
||||
.into_any_element();
|
||||
|
||||
Some(
|
||||
h_flex()
|
||||
.child(self.render_kernel_selector(cx))
|
||||
.child(button)
|
||||
.child(dropdown_menu)
|
||||
.into_any_element(),
|
||||
)
|
||||
}
|
||||
pub fn render_repl_launch_menu(
|
||||
&self,
|
||||
kernel_specification: KernelSpecification,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Option<AnyElement> {
|
||||
let tooltip: SharedString =
|
||||
SharedString::from(format!("Start REPL for {}", kernel_specification.name()));
|
||||
|
||||
Some(
|
||||
h_flex()
|
||||
.child(self.render_kernel_selector(cx))
|
||||
.child(
|
||||
IconButton::new("toggle_repl_icon", IconName::ReplNeutral)
|
||||
.size(ButtonSize::Compact)
|
||||
.icon_color(Color::Muted)
|
||||
.style(ButtonStyle::Subtle)
|
||||
.tooltip(move |cx| Tooltip::text(tooltip.clone(), cx))
|
||||
.on_click(|_, cx| cx.dispatch_action(Box::new(repl::Run {}))),
|
||||
)
|
||||
.into_any_element(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn render_kernel_selector(&self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||
let editor = if let Some(editor) = self.active_editor() {
|
||||
editor
|
||||
} else {
|
||||
return div().into_any_element();
|
||||
};
|
||||
|
||||
let Some(worktree_id) = worktree_id_for_editor(editor.downgrade(), cx) else {
|
||||
return div().into_any_element();
|
||||
};
|
||||
|
||||
let session = repl::session(editor.downgrade(), cx);
|
||||
|
||||
let current_kernelspec = match session {
|
||||
SessionSupport::ActiveSession(view) => Some(view.read(cx).kernel_specification.clone()),
|
||||
SessionSupport::Inactive(kernel_specification) => Some(kernel_specification),
|
||||
SessionSupport::RequiresSetup(_language_name) => None,
|
||||
SessionSupport::Unsupported => None,
|
||||
};
|
||||
|
||||
let current_kernel_name = current_kernelspec.as_ref().map(|spec| spec.name());
|
||||
|
||||
let menu_handle: PopoverMenuHandle<Picker<KernelPickerDelegate>> =
|
||||
PopoverMenuHandle::default();
|
||||
KernelSelector::new(
|
||||
{
|
||||
Box::new(move |kernelspec, cx| {
|
||||
repl::assign_kernelspec(kernelspec, editor.downgrade(), cx).ok();
|
||||
})
|
||||
},
|
||||
worktree_id,
|
||||
ButtonLike::new("kernel-selector")
|
||||
.style(ButtonStyle::Subtle)
|
||||
.child(
|
||||
h_flex()
|
||||
.w_full()
|
||||
.gap_0p5()
|
||||
.child(
|
||||
div()
|
||||
.overflow_x_hidden()
|
||||
.flex_grow()
|
||||
.whitespace_nowrap()
|
||||
.child(
|
||||
Label::new(if let Some(name) = current_kernel_name {
|
||||
name
|
||||
} else {
|
||||
SharedString::from("Select Kernel")
|
||||
})
|
||||
.size(LabelSize::Small)
|
||||
.color(if current_kernelspec.is_some() {
|
||||
Color::Default
|
||||
} else {
|
||||
Color::Placeholder
|
||||
})
|
||||
.into_any_element(),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
Icon::new(IconName::ChevronDown)
|
||||
.color(Color::Muted)
|
||||
.size(IconSize::XSmall),
|
||||
),
|
||||
)
|
||||
.tooltip(move |cx| Tooltip::text("Select Kernel", cx)),
|
||||
)
|
||||
.with_handle(menu_handle.clone())
|
||||
.into_any_element()
|
||||
}
|
||||
|
||||
pub fn render_repl_setup(
|
||||
&self,
|
||||
language: &str,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Option<AnyElement> {
|
||||
let tooltip: SharedString = SharedString::from(format!("Setup Zed REPL for {}", language));
|
||||
Some(
|
||||
h_flex()
|
||||
.child(self.render_kernel_selector(cx))
|
||||
.child(
|
||||
IconButton::new("toggle_repl_icon", IconName::ReplNeutral)
|
||||
.size(ButtonSize::Compact)
|
||||
.icon_color(Color::Muted)
|
||||
.style(ButtonStyle::Subtle)
|
||||
.tooltip(move |cx| Tooltip::text(tooltip.clone(), cx))
|
||||
.on_click(|_, cx| {
|
||||
cx.open_url(&format!("{}#installation", ZED_REPL_DOCUMENTATION))
|
||||
}),
|
||||
)
|
||||
.into_any_element(),
|
||||
)
|
||||
h_flex()
|
||||
.child(self.kernel_menu.clone())
|
||||
.child(button)
|
||||
.child(dropdown_menu)
|
||||
.into_any_element()
|
||||
}
|
||||
}
|
||||
|
||||
fn session_state(session: View<Session>, cx: &WindowContext) -> ReplMenuState {
|
||||
impl ReplMenu {
|
||||
pub fn render_repl_launch_menu(
|
||||
&self,
|
||||
kernel_specification: KernelSpecification,
|
||||
_cx: &mut ViewContext<Self>,
|
||||
) -> impl IntoElement {
|
||||
let tooltip: SharedString =
|
||||
SharedString::from(format!("Start REPL for {}", kernel_specification.name()));
|
||||
|
||||
h_flex().child(self.kernel_menu.clone()).child(
|
||||
IconButton::new("toggle_repl_icon", IconName::ReplNeutral)
|
||||
.size(ButtonSize::Compact)
|
||||
.icon_color(Color::Muted)
|
||||
.style(ButtonStyle::Subtle)
|
||||
.tooltip(move |cx| Tooltip::text(tooltip.clone(), cx))
|
||||
.on_click(|_, cx| cx.dispatch_action(Box::new(repl::Run {}))),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn render_repl_setup(&self, language: &str, _cx: &mut ViewContext<Self>) -> AnyElement {
|
||||
let tooltip: SharedString = SharedString::from(format!("Setup Zed REPL for {}", language));
|
||||
h_flex()
|
||||
.child(self.kernel_menu.clone())
|
||||
.child(
|
||||
IconButton::new("toggle_repl_icon", IconName::ReplNeutral)
|
||||
.size(ButtonSize::Compact)
|
||||
.icon_color(Color::Muted)
|
||||
.style(ButtonStyle::Subtle)
|
||||
.tooltip(move |cx| Tooltip::text(tooltip.clone(), cx))
|
||||
.on_click(|_, cx| {
|
||||
cx.open_url(&format!("{}#installation", ZED_REPL_DOCUMENTATION))
|
||||
}),
|
||||
)
|
||||
.into_any_element()
|
||||
}
|
||||
}
|
||||
|
||||
// struct KernelMenu {
|
||||
// menu_handle: PopoverMenuHandle<Picker<KernelPickerDelegate>>,
|
||||
// editor: WeakView<Editor>,
|
||||
// }
|
||||
|
||||
// impl KernelMenu {
|
||||
// pub fn new(editor: WeakView<Editor>, cx: &mut ViewContext<Self>) -> Self {
|
||||
|
||||
// Self {
|
||||
// editor,
|
||||
// menu_handle,
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// impl Render for KernelMenu {
|
||||
// fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||
// let Some(worktree_id) = worktree_id_for_editor(self.editor.clone(), cx) else {
|
||||
// return div().into_any_element();
|
||||
// };
|
||||
|
||||
// KernelSelector::new(self.editor.clone(), worktree_id)
|
||||
// .with_handle(self.menu_handle.clone())
|
||||
// .into_any_element()
|
||||
// }
|
||||
// }
|
||||
|
||||
fn session_state(session: View<Session>, cx: &WindowContext) -> ReplSessionState {
|
||||
let session = session.read(cx);
|
||||
|
||||
let kernel_name = session.kernel_specification.name();
|
||||
let kernel_language: SharedString = session.kernel_specification.language();
|
||||
|
||||
let fill_fields = || {
|
||||
ReplMenuState {
|
||||
ReplSessionState {
|
||||
tooltip: "Nothing running".into(),
|
||||
icon: IconName::ReplNeutral,
|
||||
icon_color: Color::Default,
|
||||
@@ -392,7 +363,7 @@ fn session_state(session: View<Session>, cx: &WindowContext) -> ReplMenuState {
|
||||
};
|
||||
|
||||
match &session.kernel {
|
||||
Kernel::Restarting => ReplMenuState {
|
||||
Kernel::Restarting => ReplSessionState {
|
||||
tooltip: format!("Restarting {}", kernel_name).into(),
|
||||
icon_is_animating: true,
|
||||
popover_disabled: true,
|
||||
@@ -402,13 +373,13 @@ fn session_state(session: View<Session>, cx: &WindowContext) -> ReplMenuState {
|
||||
..fill_fields()
|
||||
},
|
||||
Kernel::RunningKernel(kernel) => match &kernel.execution_state() {
|
||||
ExecutionState::Idle => ReplMenuState {
|
||||
ExecutionState::Idle => ReplSessionState {
|
||||
tooltip: format!("Run code on {} ({})", kernel_name, kernel_language).into(),
|
||||
indicator: Some(Indicator::dot().color(Color::Success)),
|
||||
status: session.kernel.status(),
|
||||
..fill_fields()
|
||||
},
|
||||
ExecutionState::Busy => ReplMenuState {
|
||||
ExecutionState::Busy => ReplSessionState {
|
||||
tooltip: format!("Interrupt {} ({})", kernel_name, kernel_language).into(),
|
||||
icon_is_animating: true,
|
||||
popover_disabled: false,
|
||||
@@ -417,7 +388,7 @@ fn session_state(session: View<Session>, cx: &WindowContext) -> ReplMenuState {
|
||||
..fill_fields()
|
||||
},
|
||||
},
|
||||
Kernel::StartingKernel(_) => ReplMenuState {
|
||||
Kernel::StartingKernel(_) => ReplSessionState {
|
||||
tooltip: format!("{} is starting", kernel_name).into(),
|
||||
icon_is_animating: true,
|
||||
popover_disabled: true,
|
||||
@@ -426,14 +397,14 @@ fn session_state(session: View<Session>, cx: &WindowContext) -> ReplMenuState {
|
||||
status: session.kernel.status(),
|
||||
..fill_fields()
|
||||
},
|
||||
Kernel::ErroredLaunch(e) => ReplMenuState {
|
||||
Kernel::ErroredLaunch(e) => ReplSessionState {
|
||||
tooltip: format!("Error with kernel {}: {}", kernel_name, e).into(),
|
||||
popover_disabled: false,
|
||||
indicator: Some(Indicator::dot().color(Color::Error)),
|
||||
status: session.kernel.status(),
|
||||
..fill_fields()
|
||||
},
|
||||
Kernel::ShuttingDown => ReplMenuState {
|
||||
Kernel::ShuttingDown => ReplSessionState {
|
||||
tooltip: format!("{} is shutting down", kernel_name).into(),
|
||||
popover_disabled: true,
|
||||
icon_color: Color::Muted,
|
||||
@@ -441,7 +412,7 @@ fn session_state(session: View<Session>, cx: &WindowContext) -> ReplMenuState {
|
||||
status: session.kernel.status(),
|
||||
..fill_fields()
|
||||
},
|
||||
Kernel::Shutdown => ReplMenuState {
|
||||
Kernel::Shutdown => ReplSessionState {
|
||||
tooltip: "Nothing running".into(),
|
||||
icon: IconName::ReplNeutral,
|
||||
icon_color: Color::Default,
|
||||
|
||||
Reference in New Issue
Block a user