Stick REPL icon in quick action bar (#14064)
REPL Quick Actions <img width="325" alt="image" src="https://github.com/zed-industries/zed/assets/836375/faaf4c8f-ef12-4417-a9dd-158d5beae8ba"> When the Jupyter REPL is enabled and a kernel is available, show the status in the editor bar:  Release Notes: - N/A --------- Co-authored-by: Nate Butler <iamnbutler@gmail.com>
This commit is contained in:
parent
9282bf97ae
commit
896b9bda23
15 changed files with 345 additions and 16 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -8274,6 +8274,7 @@ dependencies = [
|
||||||
"assistant",
|
"assistant",
|
||||||
"editor",
|
"editor",
|
||||||
"gpui",
|
"gpui",
|
||||||
|
"repl",
|
||||||
"search",
|
"search",
|
||||||
"settings",
|
"settings",
|
||||||
"ui",
|
"ui",
|
||||||
|
|
14
assets/icons/repl_neutral.svg
Normal file
14
assets/icons/repl_neutral.svg
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_32_58)">
|
||||||
|
<path d="M19 7C20.1046 7 21 6.10457 21 5C21 3.89543 20.1046 3 19 3C17.8954 3 17 3.89543 17 5C17 6.10457 17.8954 7 19 7Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M5 21C6.10457 21 7 20.1046 7 19C7 17.8954 6.10457 17 5 17C3.89543 17 3 17.8954 3 19C3 20.1046 3.89543 21 5 21Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M10.3999 21.9C12.3227 22.2159 14.2958 21.9632 16.0769 21.173C17.858 20.3827 19.3694 19.0893 20.4254 17.4517C21.4814 15.8142 22.036 13.9037 22.021 11.9553C22.006 10.0068 21.422 8.10512 20.3409 6.48401" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M13.4998 2.10002C11.5849 1.8076 9.62631 2.07763 7.86198 2.87732C6.09765 3.677 4.60356 4.9719 3.56126 6.60468C2.51896 8.23745 1.97332 10.1378 1.99063 12.0748C2.00795 14.0118 2.58749 15.9021 3.65882 17.516" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M12 13C12.5523 13 13 12.5523 13 12C13 11.4477 12.5523 11 12 11C11.4477 11 11 11.4477 11 12C11 12.5523 11.4477 13 12 13Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_32_58">
|
||||||
|
<rect width="24" height="24" fill="white"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
20
assets/icons/repl_off.svg
Normal file
20
assets/icons/repl_off.svg
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_39_129)">
|
||||||
|
<path d="M22.0209 11.9553C22.0059 10.0068 21.4219 8.10512 20.3408 6.48401" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M10.1001 2.18C11.355 1.93537 12.1493 1.93674 13.5027 2.10594" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M21.8198 10.1C22.0644 11.3548 22.0644 12.6451 21.8198 13.9" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M20.2898 17.6C19.5716 18.6622 18.6548 19.5757 17.5898 20.29" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M13.9008 21.82C12.6459 22.0644 11.6432 22.1543 10.3883 21.91" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M2.18005 13.9C1.93543 12.6451 1.93543 11.3548 2.18005 10.1" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M3.70996 6.40002C4.42822 5.33775 5.34503 4.42433 6.40996 3.71002" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M12 13C12.5523 13 13 12.5523 13 12C13 11.4477 12.5523 11 12 11C11.4477 11 11 11.4477 11 12C11 12.5523 11.4477 13 12 13Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M19 7C20.1046 7 21 6.10457 21 5C21 3.89543 20.1046 3 19 3C17.8954 3 17 3.89543 17 5C17 6.10457 17.8954 7 19 7Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M5 21C6.10457 21 7 20.1046 7 19C7 17.8954 6.10457 17 5 17C3.89543 17 3 17.8954 3 19C3 20.1046 3.89543 21 5 21Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M1.99072 12.0748C2.00804 14.0118 2.58758 15.9021 3.65891 17.516" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_39_129">
|
||||||
|
<rect width="24" height="24" fill="white"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2 KiB |
15
assets/icons/repl_pause.svg
Normal file
15
assets/icons/repl_pause.svg
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_32_70)">
|
||||||
|
<path d="M19 7C20.1046 7 21 6.10457 21 5C21 3.89543 20.1046 3 19 3C17.8954 3 17 3.89543 17 5C17 6.10457 17.8954 7 19 7Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M5 21C6.10457 21 7 20.1046 7 19C7 17.8954 6.10457 17 5 17C3.89543 17 3 17.8954 3 19C3 20.1046 3.89543 21 5 21Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M10.3999 21.9C12.3227 22.2159 14.2958 21.9632 16.0769 21.173C17.858 20.3827 19.3694 19.0893 20.4254 17.4517C21.4814 15.8142 22.036 13.9037 22.021 11.9553C22.006 10.0068 21.422 8.10512 20.3409 6.48401" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M13.4998 2.10002C11.5849 1.8076 9.62631 2.07763 7.86198 2.87732C6.09765 3.677 4.60356 4.9719 3.56126 6.60468C2.51896 8.23745 1.97332 10.1378 1.99063 12.0748C2.00795 14.0118 2.58749 15.9021 3.65882 17.516" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M10 15V9" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M14 15V9" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_32_70">
|
||||||
|
<rect width="24" height="24" fill="white"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
14
assets/icons/repl_play.svg
Normal file
14
assets/icons/repl_play.svg
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_32_64)">
|
||||||
|
<path d="M19 7C20.1046 7 21 6.10457 21 5C21 3.89543 20.1046 3 19 3C17.8954 3 17 3.89543 17 5C17 6.10457 17.8954 7 19 7Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M5 21C6.10457 21 7 20.1046 7 19C7 17.8954 6.10457 17 5 17C3.89543 17 3 17.8954 3 19C3 20.1046 3.89543 21 5 21Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M10.3999 21.9C12.3227 22.2159 14.2958 21.9632 16.0769 21.173C17.858 20.3827 19.3694 19.0893 20.4254 17.4517C21.4814 15.8142 22.036 13.9037 22.021 11.9553C22.006 10.0068 21.422 8.10512 20.3409 6.48401" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M13.4998 2.10002C11.5849 1.8076 9.62631 2.07763 7.86198 2.87732C6.09765 3.677 4.60356 4.9719 3.56126 6.60468C2.51896 8.23745 1.97332 10.1378 1.99063 12.0748C2.00795 14.0118 2.58749 15.9021 3.65882 17.516" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M10 8.56055C10 8.32095 10.267 8.17803 10.4664 8.31094L15.6256 11.7504C15.8037 11.8691 15.8037 12.1309 15.6256 12.2496L10.4664 15.6891C10.267 15.822 10 15.6791 10 15.4394V8.56055Z" fill="white" stroke="white" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_32_64">
|
||||||
|
<rect width="24" height="24" fill="white"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
|
@ -20,6 +20,7 @@ search.workspace = true
|
||||||
settings.workspace = true
|
settings.workspace = true
|
||||||
ui.workspace = true
|
ui.workspace = true
|
||||||
workspace.workspace = true
|
workspace.workspace = true
|
||||||
|
repl.workspace = true
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
editor = { workspace = true, features = ["test-support"] }
|
editor = { workspace = true, features = ["test-support"] }
|
||||||
|
|
|
@ -20,8 +20,11 @@ use workspace::{
|
||||||
item::ItemHandle, ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView, Workspace,
|
item::ItemHandle, ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView, Workspace,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mod repl_menu;
|
||||||
|
|
||||||
pub struct QuickActionBar {
|
pub struct QuickActionBar {
|
||||||
buffer_search_bar: View<BufferSearchBar>,
|
buffer_search_bar: View<BufferSearchBar>,
|
||||||
|
repl_menu: Option<View<ContextMenu>>,
|
||||||
toggle_settings_menu: Option<View<ContextMenu>>,
|
toggle_settings_menu: Option<View<ContextMenu>>,
|
||||||
toggle_selections_menu: Option<View<ContextMenu>>,
|
toggle_selections_menu: Option<View<ContextMenu>>,
|
||||||
active_item: Option<Box<dyn ItemHandle>>,
|
active_item: Option<Box<dyn ItemHandle>>,
|
||||||
|
@ -40,6 +43,7 @@ impl QuickActionBar {
|
||||||
buffer_search_bar,
|
buffer_search_bar,
|
||||||
toggle_settings_menu: None,
|
toggle_settings_menu: None,
|
||||||
toggle_selections_menu: None,
|
toggle_selections_menu: None,
|
||||||
|
repl_menu: None,
|
||||||
active_item: None,
|
active_item: None,
|
||||||
_inlay_hints_enabled_subscription: None,
|
_inlay_hints_enabled_subscription: None,
|
||||||
workspace: workspace.weak_handle(),
|
workspace: workspace.weak_handle(),
|
||||||
|
@ -290,9 +294,13 @@ impl Render for QuickActionBar {
|
||||||
.child(
|
.child(
|
||||||
h_flex()
|
h_flex()
|
||||||
.gap(Spacing::Medium.rems(cx))
|
.gap(Spacing::Medium.rems(cx))
|
||||||
|
.children(self.render_repl_menu(cx))
|
||||||
.children(editor_selections_dropdown)
|
.children(editor_selections_dropdown)
|
||||||
.child(editor_settings_dropdown),
|
.child(editor_settings_dropdown),
|
||||||
)
|
)
|
||||||
|
.when_some(self.repl_menu.as_ref(), |el, repl_menu| {
|
||||||
|
el.child(Self::render_menu_overlay(repl_menu))
|
||||||
|
})
|
||||||
.when_some(
|
.when_some(
|
||||||
self.toggle_settings_menu.as_ref(),
|
self.toggle_settings_menu.as_ref(),
|
||||||
|el, toggle_settings_menu| {
|
|el, toggle_settings_menu| {
|
||||||
|
|
116
crates/quick_action_bar/src/repl_menu.rs
Normal file
116
crates/quick_action_bar/src/repl_menu.rs
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
use gpui::AnyElement;
|
||||||
|
use repl::{
|
||||||
|
ExecutionState, JupyterSettings, Kernel, KernelSpecification, RuntimePanel, Session,
|
||||||
|
SessionSupport,
|
||||||
|
};
|
||||||
|
use ui::{prelude::*, ButtonLike, IconWithIndicator, IntoElement, Tooltip};
|
||||||
|
|
||||||
|
use crate::QuickActionBar;
|
||||||
|
|
||||||
|
const ZED_REPL_DOCUMENTATION: &str = "https://zed.dev/docs/repl";
|
||||||
|
|
||||||
|
impl QuickActionBar {
|
||||||
|
pub fn render_repl_menu(&self, cx: &mut ViewContext<Self>) -> Option<AnyElement> {
|
||||||
|
if !JupyterSettings::enabled(cx) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let workspace = self.workspace.upgrade()?.read(cx);
|
||||||
|
|
||||||
|
let (editor, repl_panel) = if let (Some(editor), Some(repl_panel)) =
|
||||||
|
(self.active_editor(), workspace.panel::<RuntimePanel>(cx))
|
||||||
|
{
|
||||||
|
(editor, repl_panel)
|
||||||
|
} else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
|
||||||
|
let session = repl_panel.update(cx, |repl_panel, cx| {
|
||||||
|
repl_panel.session(editor.downgrade(), cx)
|
||||||
|
});
|
||||||
|
|
||||||
|
let session = match session {
|
||||||
|
SessionSupport::ActiveSession(session) => session.read(cx),
|
||||||
|
SessionSupport::Inactive(spec) => {
|
||||||
|
return self.render_repl_launch_menu(spec, cx);
|
||||||
|
}
|
||||||
|
SessionSupport::RequiresSetup(language) => {
|
||||||
|
return self.render_repl_setup(&language, cx);
|
||||||
|
}
|
||||||
|
SessionSupport::Unsupported => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let kernel_name: SharedString = session.kernel_specification.name.clone().into();
|
||||||
|
let kernel_language: SharedString = session
|
||||||
|
.kernel_specification
|
||||||
|
.kernelspec
|
||||||
|
.language
|
||||||
|
.clone()
|
||||||
|
.into();
|
||||||
|
|
||||||
|
let tooltip = |session: &Session| match &session.kernel {
|
||||||
|
Kernel::RunningKernel(kernel) => match &kernel.execution_state {
|
||||||
|
ExecutionState::Idle => {
|
||||||
|
format!("Run code on {} ({})", kernel_name, kernel_language)
|
||||||
|
}
|
||||||
|
ExecutionState::Busy => format!("Interrupt {} ({})", kernel_name, kernel_language),
|
||||||
|
},
|
||||||
|
Kernel::StartingKernel(_) => format!("{} is starting", kernel_name),
|
||||||
|
Kernel::ErroredLaunch(e) => format!("Error with kernel {}: {}", kernel_name, e),
|
||||||
|
Kernel::ShuttingDown => format!("{} is shutting down", kernel_name),
|
||||||
|
Kernel::Shutdown => "Nothing running".to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let tooltip_text: SharedString = SharedString::from(tooltip(&session).clone());
|
||||||
|
|
||||||
|
let button = ButtonLike::new("toggle_repl_icon")
|
||||||
|
.child(
|
||||||
|
IconWithIndicator::new(Icon::new(IconName::Play), Some(session.kernel.dot()))
|
||||||
|
.indicator_border_color(Some(cx.theme().colors().border)),
|
||||||
|
)
|
||||||
|
.size(ButtonSize::Compact)
|
||||||
|
.style(ButtonStyle::Subtle)
|
||||||
|
.tooltip(move |cx| Tooltip::text(tooltip_text.clone(), cx))
|
||||||
|
.on_click(|_, cx| cx.dispatch_action(Box::new(repl::Run {})))
|
||||||
|
.on_click(|_, cx| cx.dispatch_action(Box::new(repl::Run {})))
|
||||||
|
.into_any_element();
|
||||||
|
|
||||||
|
Some(button)
|
||||||
|
}
|
||||||
|
|
||||||
|
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(
|
||||||
|
IconButton::new("toggle_repl_icon", IconName::Play)
|
||||||
|
.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_repl_setup(
|
||||||
|
&self,
|
||||||
|
language: &str,
|
||||||
|
_cx: &mut ViewContext<Self>,
|
||||||
|
) -> Option<AnyElement> {
|
||||||
|
let tooltip: SharedString = SharedString::from(format!("Setup Zed REPL for {}", language));
|
||||||
|
Some(
|
||||||
|
IconButton::new("toggle_repl_icon", IconName::Play)
|
||||||
|
.size(ButtonSize::Compact)
|
||||||
|
.icon_color(Color::Muted)
|
||||||
|
.style(ButtonStyle::Subtle)
|
||||||
|
.tooltip(move |cx| Tooltip::text(tooltip.clone(), cx))
|
||||||
|
.on_click(|_, cx| cx.open_url(ZED_REPL_DOCUMENTATION))
|
||||||
|
.into_any_element(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -82,7 +82,7 @@ pub enum Kernel {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Kernel {
|
impl Kernel {
|
||||||
pub fn dot(&mut self) -> Indicator {
|
pub fn dot(&self) -> Indicator {
|
||||||
match self {
|
match self {
|
||||||
Kernel::RunningKernel(kernel) => match kernel.execution_state {
|
Kernel::RunningKernel(kernel) => match kernel.execution_state {
|
||||||
ExecutionState::Idle => Indicator::dot().color(Color::Success),
|
ExecutionState::Idle => Indicator::dot().color(Color::Success),
|
||||||
|
|
|
@ -11,7 +11,11 @@ mod session;
|
||||||
mod stdio;
|
mod stdio;
|
||||||
|
|
||||||
pub use jupyter_settings::JupyterSettings;
|
pub use jupyter_settings::JupyterSettings;
|
||||||
pub use runtime_panel::RuntimePanel;
|
pub use kernels::{Kernel, KernelSpecification};
|
||||||
|
pub use runtime_panel::Run;
|
||||||
|
pub use runtime_panel::{RuntimePanel, SessionSupport};
|
||||||
|
pub use runtimelib::ExecutionState;
|
||||||
|
pub use session::Session;
|
||||||
|
|
||||||
fn zed_dispatcher(cx: &mut AppContext) -> impl Dispatcher {
|
fn zed_dispatcher(cx: &mut AppContext) -> impl Dispatcher {
|
||||||
struct ZedDispatcher {
|
struct ZedDispatcher {
|
||||||
|
|
|
@ -241,6 +241,17 @@ impl RuntimePanel {
|
||||||
Some((selected_text, language_name, anchor_range))
|
Some((selected_text, language_name, anchor_range))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn language(
|
||||||
|
&self,
|
||||||
|
editor: WeakView<Editor>,
|
||||||
|
cx: &mut ViewContext<Self>,
|
||||||
|
) -> Option<Arc<str>> {
|
||||||
|
match self.snippet(editor, cx) {
|
||||||
|
Some((_, language, _)) => Some(language),
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn refresh_kernelspecs(&mut self, cx: &mut ViewContext<Self>) -> Task<anyhow::Result<()>> {
|
pub fn refresh_kernelspecs(&mut self, cx: &mut ViewContext<Self>) -> Task<anyhow::Result<()>> {
|
||||||
let kernel_specifications = kernel_specifications(self.fs.clone());
|
let kernel_specifications = kernel_specifications(self.fs.clone());
|
||||||
cx.spawn(|this, mut cx| async move {
|
cx.spawn(|this, mut cx| async move {
|
||||||
|
@ -336,6 +347,50 @@ impl RuntimePanel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum SessionSupport {
|
||||||
|
ActiveSession(View<Session>),
|
||||||
|
Inactive(KernelSpecification),
|
||||||
|
RequiresSetup(String),
|
||||||
|
Unsupported,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RuntimePanel {
|
||||||
|
pub fn session(
|
||||||
|
&mut self,
|
||||||
|
editor: WeakView<Editor>,
|
||||||
|
cx: &mut ViewContext<Self>,
|
||||||
|
) -> SessionSupport {
|
||||||
|
let entity_id = editor.entity_id();
|
||||||
|
let session = self.sessions.get(&entity_id).cloned();
|
||||||
|
|
||||||
|
match session {
|
||||||
|
Some(session) => SessionSupport::ActiveSession(session),
|
||||||
|
None => {
|
||||||
|
let language = self.language(editor, cx);
|
||||||
|
let language = match language {
|
||||||
|
Some(language) => language,
|
||||||
|
None => return SessionSupport::Unsupported,
|
||||||
|
};
|
||||||
|
// Check for kernelspec
|
||||||
|
let kernelspec = self.kernelspec(&language, cx);
|
||||||
|
|
||||||
|
match kernelspec {
|
||||||
|
Some(kernelspec) => SessionSupport::Inactive(kernelspec),
|
||||||
|
None => {
|
||||||
|
let language: String = language.to_lowercase();
|
||||||
|
// If no kernelspec but language is one of typescript, python, r, or julia
|
||||||
|
// then we return RequiresSetup
|
||||||
|
match language.as_str() {
|
||||||
|
"typescript" | "python" => SessionSupport::RequiresSetup(language),
|
||||||
|
_ => SessionSupport::Unsupported,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Panel for RuntimePanel {
|
impl Panel for RuntimePanel {
|
||||||
fn persistent_name() -> &'static str {
|
fn persistent_name() -> &'static str {
|
||||||
"RuntimePanel"
|
"RuntimePanel"
|
||||||
|
|
|
@ -22,11 +22,11 @@ use theme::{ActiveTheme, ThemeSettings};
|
||||||
use ui::{h_flex, prelude::*, v_flex, ButtonLike, ButtonStyle, Label};
|
use ui::{h_flex, prelude::*, v_flex, ButtonLike, ButtonStyle, Label};
|
||||||
|
|
||||||
pub struct Session {
|
pub struct Session {
|
||||||
editor: WeakView<Editor>,
|
pub editor: WeakView<Editor>,
|
||||||
kernel: Kernel,
|
pub kernel: Kernel,
|
||||||
blocks: HashMap<String, EditorBlock>,
|
blocks: HashMap<String, EditorBlock>,
|
||||||
messaging_task: Task<()>,
|
pub messaging_task: Task<()>,
|
||||||
kernel_specification: KernelSpecification,
|
pub kernel_specification: KernelSpecification,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct EditorBlock {
|
struct EditorBlock {
|
||||||
|
@ -310,7 +310,7 @@ impl Session {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn interrupt(&mut self, cx: &mut ViewContext<Self>) {
|
pub fn interrupt(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
match &mut self.kernel {
|
match &mut self.kernel {
|
||||||
Kernel::RunningKernel(_kernel) => {
|
Kernel::RunningKernel(_kernel) => {
|
||||||
self.send(InterruptRequest {}.into(), cx).ok();
|
self.send(InterruptRequest {}.into(), cx).ok();
|
||||||
|
@ -322,7 +322,7 @@ impl Session {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shutdown(&mut self, cx: &mut ViewContext<Self>) {
|
pub fn shutdown(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
let kernel = std::mem::replace(&mut self.kernel, Kernel::ShuttingDown);
|
let kernel = std::mem::replace(&mut self.kernel, Kernel::ShuttingDown);
|
||||||
|
|
||||||
match kernel {
|
match kernel {
|
||||||
|
|
|
@ -160,11 +160,11 @@ pub enum IconName {
|
||||||
Font,
|
Font,
|
||||||
FontSize,
|
FontSize,
|
||||||
FontWeight,
|
FontWeight,
|
||||||
Github,
|
|
||||||
GenericMinimize,
|
|
||||||
GenericMaximize,
|
|
||||||
GenericClose,
|
GenericClose,
|
||||||
|
GenericMaximize,
|
||||||
|
GenericMinimize,
|
||||||
GenericRestore,
|
GenericRestore,
|
||||||
|
Github,
|
||||||
Hash,
|
Hash,
|
||||||
HistoryRerun,
|
HistoryRerun,
|
||||||
Indicator,
|
Indicator,
|
||||||
|
@ -194,6 +194,10 @@ pub enum IconName {
|
||||||
PullRequest,
|
PullRequest,
|
||||||
Quote,
|
Quote,
|
||||||
Regex,
|
Regex,
|
||||||
|
ReplPlay,
|
||||||
|
ReplOff,
|
||||||
|
ReplPause,
|
||||||
|
ReplNeutral,
|
||||||
Replace,
|
Replace,
|
||||||
ReplaceAll,
|
ReplaceAll,
|
||||||
ReplaceNext,
|
ReplaceNext,
|
||||||
|
@ -231,12 +235,12 @@ pub enum IconName {
|
||||||
Trash,
|
Trash,
|
||||||
TriangleRight,
|
TriangleRight,
|
||||||
Update,
|
Update,
|
||||||
|
Visible,
|
||||||
WholeWord,
|
WholeWord,
|
||||||
XCircle,
|
XCircle,
|
||||||
ZedAssistant,
|
ZedAssistant,
|
||||||
ZedAssistantFilled,
|
ZedAssistantFilled,
|
||||||
ZedXCopilot,
|
ZedXCopilot,
|
||||||
Visible,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IconName {
|
impl IconName {
|
||||||
|
@ -308,11 +312,11 @@ impl IconName {
|
||||||
IconName::Font => "icons/font.svg",
|
IconName::Font => "icons/font.svg",
|
||||||
IconName::FontSize => "icons/font_size.svg",
|
IconName::FontSize => "icons/font_size.svg",
|
||||||
IconName::FontWeight => "icons/font_weight.svg",
|
IconName::FontWeight => "icons/font_weight.svg",
|
||||||
IconName::Github => "icons/github.svg",
|
|
||||||
IconName::GenericMinimize => "icons/generic_minimize.svg",
|
|
||||||
IconName::GenericMaximize => "icons/generic_maximize.svg",
|
|
||||||
IconName::GenericClose => "icons/generic_close.svg",
|
IconName::GenericClose => "icons/generic_close.svg",
|
||||||
|
IconName::GenericMaximize => "icons/generic_maximize.svg",
|
||||||
|
IconName::GenericMinimize => "icons/generic_minimize.svg",
|
||||||
IconName::GenericRestore => "icons/generic_restore.svg",
|
IconName::GenericRestore => "icons/generic_restore.svg",
|
||||||
|
IconName::Github => "icons/github.svg",
|
||||||
IconName::Hash => "icons/hash.svg",
|
IconName::Hash => "icons/hash.svg",
|
||||||
IconName::HistoryRerun => "icons/history_rerun.svg",
|
IconName::HistoryRerun => "icons/history_rerun.svg",
|
||||||
IconName::Indicator => "icons/indicator.svg",
|
IconName::Indicator => "icons/indicator.svg",
|
||||||
|
@ -342,6 +346,10 @@ impl IconName {
|
||||||
IconName::PullRequest => "icons/pull_request.svg",
|
IconName::PullRequest => "icons/pull_request.svg",
|
||||||
IconName::Quote => "icons/quote.svg",
|
IconName::Quote => "icons/quote.svg",
|
||||||
IconName::Regex => "icons/regex.svg",
|
IconName::Regex => "icons/regex.svg",
|
||||||
|
IconName::ReplPlay => "icons/repl_play.svg",
|
||||||
|
IconName::ReplPause => "icons/repl_pause.svg",
|
||||||
|
IconName::ReplNeutral => "icons/repl_neutral.svg",
|
||||||
|
IconName::ReplOff => "icons/repl_off.svg",
|
||||||
IconName::Replace => "icons/replace.svg",
|
IconName::Replace => "icons/replace.svg",
|
||||||
IconName::ReplaceAll => "icons/replace_all.svg",
|
IconName::ReplaceAll => "icons/replace_all.svg",
|
||||||
IconName::ReplaceNext => "icons/replace_next.svg",
|
IconName::ReplaceNext => "icons/replace_next.svg",
|
||||||
|
@ -379,12 +387,12 @@ impl IconName {
|
||||||
IconName::Trash => "icons/trash.svg",
|
IconName::Trash => "icons/trash.svg",
|
||||||
IconName::TriangleRight => "icons/triangle_right.svg",
|
IconName::TriangleRight => "icons/triangle_right.svg",
|
||||||
IconName::Update => "icons/update.svg",
|
IconName::Update => "icons/update.svg",
|
||||||
|
IconName::Visible => "icons/visible.svg",
|
||||||
IconName::WholeWord => "icons/word_search.svg",
|
IconName::WholeWord => "icons/word_search.svg",
|
||||||
IconName::XCircle => "icons/error.svg",
|
IconName::XCircle => "icons/error.svg",
|
||||||
IconName::ZedAssistant => "icons/zed_assistant.svg",
|
IconName::ZedAssistant => "icons/zed_assistant.svg",
|
||||||
IconName::ZedAssistantFilled => "icons/zed_assistant_filled.svg",
|
IconName::ZedAssistantFilled => "icons/zed_assistant_filled.svg",
|
||||||
IconName::ZedXCopilot => "icons/zed_x_copilot.svg",
|
IconName::ZedXCopilot => "icons/zed_x_copilot.svg",
|
||||||
IconName::Visible => "icons/visible.svg",
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
- [Collaboration](./collaboration.md)
|
- [Collaboration](./collaboration.md)
|
||||||
- [Tasks](./tasks.md)
|
- [Tasks](./tasks.md)
|
||||||
- [Remote Development](./remote-development.md)
|
- [Remote Development](./remote-development.md)
|
||||||
|
- [Repl](./repl.md)
|
||||||
|
|
||||||
# Language Support
|
# Language Support
|
||||||
|
|
||||||
|
|
72
docs/src/repl.md
Normal file
72
docs/src/repl.md
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
# REPL
|
||||||
|
|
||||||
|
Read. Eval. Print. Loop.
|
||||||
|
|
||||||
|
<div class="warning">
|
||||||
|
|
||||||
|
This feature is in active development. Details may change. We're delighted to get feedback as the REPL feature evolves.
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
The built-in REPL for Zed allows you to run code interactively in your editor similarly to a notebook with your own text files.
|
||||||
|
|
||||||
|
<!-- TODO: Include GIF in action -->
|
||||||
|
|
||||||
|
To start using the REPL, add the following to your Zed `settings.json` to bring the power of [Jupyter kernels](https://docs.jupyter.org/en/latest/projects/kernels.html) to your editor:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"jupyter": {
|
||||||
|
"enabled": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
After that, install any of the supported kernels:
|
||||||
|
|
||||||
|
* [Python](#python)
|
||||||
|
* [TypeScript via Deno](#deno)
|
||||||
|
|
||||||
|
## Python
|
||||||
|
|
||||||
|
### Global environment
|
||||||
|
|
||||||
|
To setup your current python to have an available kernel, run:
|
||||||
|
|
||||||
|
```
|
||||||
|
python -m ipykernel install --user
|
||||||
|
```
|
||||||
|
|
||||||
|
### Conda Environment
|
||||||
|
|
||||||
|
```
|
||||||
|
source activate myenv
|
||||||
|
conda install ipykernel
|
||||||
|
python -m ipykernel install --user --name myenv --display-name "Python (myenv)"
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Virtualenv with pip
|
||||||
|
|
||||||
|
```
|
||||||
|
source activate myenv
|
||||||
|
pip install ipykernel
|
||||||
|
python -m ipykernel install --user --name myenv --display-name "Python (myenv)"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Deno
|
||||||
|
|
||||||
|
[Install Deno](https://docs.deno.com/runtime/manual/getting_started/installation/) and then install the Deno jupyter kernel:
|
||||||
|
|
||||||
|
```
|
||||||
|
deno jupyter --unstable --install
|
||||||
|
```
|
||||||
|
|
||||||
|
## Other languages
|
||||||
|
|
||||||
|
* [Julia](https://github.com/JuliaLang/IJulia.jl)
|
||||||
|
* R
|
||||||
|
- [Ark Kernel from Positron, formerly RStudio](https://github.com/posit-dev/ark)
|
||||||
|
- [Xeus-R](https://github.com/jupyter-xeus/xeus-r)
|
||||||
|
* [Scala](https://almond.sh/docs/quick-start-install)
|
Loading…
Add table
Add a link
Reference in a new issue