repl.rs

 1pub mod components;
 2mod jupyter_settings;
 3pub mod kernels;
 4pub mod notebook;
 5mod outputs;
 6mod repl_editor;
 7mod repl_sessions_ui;
 8mod repl_settings;
 9mod repl_store;
10mod session;
11
12use std::{sync::Arc, time::Duration};
13
14use async_dispatcher::{Dispatcher, Runnable, set_dispatcher};
15use gpui::{App, PlatformDispatcher, Priority, RunnableMeta};
16use project::Fs;
17pub use runtimelib::ExecutionState;
18
19pub use crate::jupyter_settings::JupyterSettings;
20pub use crate::kernels::{Kernel, KernelSpecification, KernelStatus, PythonEnvKernelSpecification};
21pub use crate::repl_editor::*;
22pub use crate::repl_sessions_ui::{
23    ClearCurrentOutput, ClearOutputs, Interrupt, ReplSessionsPage, Restart, Run, Sessions, Shutdown,
24};
25pub use crate::repl_settings::ReplSettings;
26pub use crate::repl_store::ReplStore;
27pub use crate::session::Session;
28
29pub const KERNEL_DOCS_URL: &str = "https://zed.dev/docs/repl#changing-kernels";
30
31pub fn init(fs: Arc<dyn Fs>, cx: &mut App) {
32    set_dispatcher(zed_dispatcher(cx));
33    repl_sessions_ui::init(cx);
34    ReplStore::init(fs, cx);
35}
36
37fn zed_dispatcher(cx: &mut App) -> impl Dispatcher {
38    struct ZedDispatcher {
39        dispatcher: Arc<dyn PlatformDispatcher>,
40    }
41
42    // PlatformDispatcher is _super_ close to the same interface we put in
43    // async-dispatcher, except for the task label in dispatch. Later we should
44    // just make that consistent so we have this dispatcher ready to go for
45    // other crates in Zed.
46    impl Dispatcher for ZedDispatcher {
47        #[track_caller]
48        fn dispatch(&self, runnable: Runnable) {
49            let location = core::panic::Location::caller();
50            let (wrapper, task) = async_task::Builder::new()
51                .metadata(RunnableMeta { location })
52                .spawn(|_| async move { runnable.run() }, {
53                    let dispatcher = self.dispatcher.clone();
54                    move |r| dispatcher.dispatch(r, Priority::default())
55                });
56            wrapper.schedule();
57            task.detach();
58        }
59
60        #[track_caller]
61        fn dispatch_after(&self, duration: Duration, runnable: Runnable) {
62            let location = core::panic::Location::caller();
63            let (wrapper, task) = async_task::Builder::new()
64                .metadata(RunnableMeta { location })
65                .spawn(|_| async move { runnable.run() }, {
66                    let dispatcher = self.dispatcher.clone();
67                    move |r| dispatcher.dispatch_after(duration, r)
68                });
69            wrapper.schedule();
70            task.detach();
71        }
72    }
73
74    ZedDispatcher {
75        dispatcher: cx.background_executor().dispatcher().clone(),
76    }
77}