Add REPL dropdown menu to toolbar (#14493)
TODO: - [x] Actions run from menu not firing - [x] Menu differentiates idle and busy for running kernel Menu States: - [x] No session && no support known No session && no kernel installed for languages of known support - (TODO after) Intro to REPL - [x] Link to docs No session but can start one - [x] Start REPL - (TODO after) More info -> Docs? Yes Session - [x] Info: Kernel name, language example: chatlab-3.7-adsf87fsa (Python) example: condapy-3.7 (Python) - [x] Change Kernel -> https://zed.dev/docs/repl#change-kernel - --- - [x] Run - [x] Interrupt - [x] Clear Outputs - --- - [x] Shutdown (Release notes left empty as the change will be documented in the REPL release!) Reserved for a follow on PR: ``` - [ ] Status should update when the menu is open (missing `cx.notify`?) - [ ] Shutdown all kernels action - [ ] Restart action - [ ] [Default kernel changed - restart (this kernel) to apply] // todo!(kyle): need some kind of state thing that says if this has happened ``` Release Notes: - N/A --------- Co-authored-by: Marshall Bowers <elliott.codes@gmail.com> Co-authored-by: Kyle Kelley <rgbkrk@gmail.com> Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
This commit is contained in:
parent
1856320516
commit
fa3d29087d
12 changed files with 489 additions and 71 deletions
|
@ -81,6 +81,52 @@ pub enum Kernel {
|
|||
Shutdown,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum KernelStatus {
|
||||
Idle,
|
||||
Busy,
|
||||
Starting,
|
||||
Error,
|
||||
ShuttingDown,
|
||||
Shutdown,
|
||||
}
|
||||
impl KernelStatus {
|
||||
pub fn is_connected(&self) -> bool {
|
||||
match self {
|
||||
KernelStatus::Idle | KernelStatus::Busy => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for KernelStatus {
|
||||
fn to_string(&self) -> String {
|
||||
match self {
|
||||
KernelStatus::Idle => "Idle".to_string(),
|
||||
KernelStatus::Busy => "Busy".to_string(),
|
||||
KernelStatus::Starting => "Starting".to_string(),
|
||||
KernelStatus::Error => "Error".to_string(),
|
||||
KernelStatus::ShuttingDown => "Shutting Down".to_string(),
|
||||
KernelStatus::Shutdown => "Shutdown".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Kernel> for KernelStatus {
|
||||
fn from(kernel: &Kernel) -> Self {
|
||||
match kernel {
|
||||
Kernel::RunningKernel(kernel) => match kernel.execution_state {
|
||||
ExecutionState::Idle => KernelStatus::Idle,
|
||||
ExecutionState::Busy => KernelStatus::Busy,
|
||||
},
|
||||
Kernel::StartingKernel(_) => KernelStatus::Starting,
|
||||
Kernel::ErroredLaunch(_) => KernelStatus::Error,
|
||||
Kernel::ShuttingDown => KernelStatus::ShuttingDown,
|
||||
Kernel::Shutdown => KernelStatus::Shutdown,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Kernel {
|
||||
pub fn dot(&self) -> Indicator {
|
||||
match self {
|
||||
|
@ -95,6 +141,10 @@ impl Kernel {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn status(&self) -> KernelStatus {
|
||||
self.into()
|
||||
}
|
||||
|
||||
pub fn set_execution_state(&mut self, status: &ExecutionState) {
|
||||
match self {
|
||||
Kernel::RunningKernel(running_kernel) => {
|
||||
|
|
|
@ -12,7 +12,7 @@ mod stdio;
|
|||
|
||||
pub use jupyter_settings::JupyterSettings;
|
||||
pub use kernels::{Kernel, KernelSpecification};
|
||||
pub use runtime_panel::Run;
|
||||
pub use runtime_panel::{ClearOutputs, Interrupt, Run, Shutdown};
|
||||
pub use runtime_panel::{RuntimePanel, SessionSupport};
|
||||
pub use runtimelib::ExecutionState;
|
||||
pub use session::Session;
|
||||
|
|
|
@ -23,7 +23,7 @@ use workspace::{
|
|||
Workspace,
|
||||
};
|
||||
|
||||
actions!(repl, [Run, ClearOutputs]);
|
||||
actions!(repl, [Run, ClearOutputs, Interrupt, Shutdown]);
|
||||
actions!(repl_panel, [ToggleFocus]);
|
||||
|
||||
pub fn init(cx: &mut AppContext) {
|
||||
|
@ -51,6 +51,8 @@ pub struct RuntimePanel {
|
|||
pub enum ReplEvent {
|
||||
Run(WeakView<Editor>),
|
||||
ClearOutputs(WeakView<Editor>),
|
||||
Interrupt(WeakView<Editor>),
|
||||
Shutdown(WeakView<Editor>),
|
||||
}
|
||||
|
||||
impl RuntimePanel {
|
||||
|
@ -108,6 +110,40 @@ impl RuntimePanel {
|
|||
},
|
||||
)
|
||||
.detach();
|
||||
|
||||
editor
|
||||
.register_action({
|
||||
let editor = cx.view().downgrade();
|
||||
let repl_editor_event_tx = repl_editor_event_tx.clone();
|
||||
|
||||
move |_: &Interrupt, cx: &mut WindowContext| {
|
||||
if !JupyterSettings::enabled(cx) {
|
||||
return;
|
||||
}
|
||||
repl_editor_event_tx
|
||||
.unbounded_send(ReplEvent::Interrupt(
|
||||
editor.clone(),
|
||||
))
|
||||
.ok();
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
|
||||
editor
|
||||
.register_action({
|
||||
let editor = cx.view().downgrade();
|
||||
let repl_editor_event_tx = repl_editor_event_tx.clone();
|
||||
|
||||
move |_: &Shutdown, cx: &mut WindowContext| {
|
||||
if !JupyterSettings::enabled(cx) {
|
||||
return;
|
||||
}
|
||||
repl_editor_event_tx
|
||||
.unbounded_send(ReplEvent::Shutdown(editor.clone()))
|
||||
.ok();
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
},
|
||||
),
|
||||
];
|
||||
|
@ -123,6 +159,12 @@ impl RuntimePanel {
|
|||
ReplEvent::ClearOutputs(editor) => {
|
||||
runtime_panel.clear_outputs(editor, cx);
|
||||
}
|
||||
ReplEvent::Interrupt(editor) => {
|
||||
runtime_panel.interrupt(editor, cx);
|
||||
}
|
||||
ReplEvent::Shutdown(editor) => {
|
||||
runtime_panel.shutdown(editor, cx);
|
||||
}
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
|
@ -320,11 +362,31 @@ impl RuntimePanel {
|
|||
cx.notify();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn interrupt(&mut self, editor: WeakView<Editor>, cx: &mut ViewContext<Self>) {
|
||||
let entity_id = editor.entity_id();
|
||||
if let Some(session) = self.sessions.get_mut(&entity_id) {
|
||||
session.update(cx, |session, cx| {
|
||||
session.interrupt(cx);
|
||||
});
|
||||
cx.notify();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn shutdown(&self, editor: WeakView<Editor>, cx: &mut ViewContext<RuntimePanel>) {
|
||||
let entity_id = editor.entity_id();
|
||||
if let Some(session) = self.sessions.get(&entity_id) {
|
||||
session.update(cx, |session, cx| {
|
||||
session.shutdown(cx);
|
||||
});
|
||||
cx.notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum SessionSupport {
|
||||
ActiveSession(View<Session>),
|
||||
Inactive(KernelSpecification),
|
||||
Inactive(Box<KernelSpecification>),
|
||||
RequiresSetup(Arc<str>),
|
||||
Unsupported,
|
||||
}
|
||||
|
@ -350,7 +412,7 @@ impl RuntimePanel {
|
|||
let kernelspec = self.kernelspec(&language, cx);
|
||||
|
||||
match kernelspec {
|
||||
Some(kernelspec) => SessionSupport::Inactive(kernelspec),
|
||||
Some(kernelspec) => SessionSupport::Inactive(Box::new(kernelspec)),
|
||||
None => {
|
||||
// If no kernelspec but language is one of typescript or python
|
||||
// then we return RequiresSetup
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue