repl_store.rs

  1use std::sync::Arc;
  2
  3use anyhow::Result;
  4use collections::HashMap;
  5use gpui::{
  6    prelude::*, AppContext, EntityId, Global, Model, ModelContext, Subscription, Task, View,
  7};
  8use language::Language;
  9use project::Fs;
 10use settings::{Settings, SettingsStore};
 11
 12use crate::kernels::kernel_specifications;
 13use crate::{JupyterSettings, KernelSpecification, Session};
 14
 15struct GlobalReplStore(Model<ReplStore>);
 16
 17impl Global for GlobalReplStore {}
 18
 19pub struct ReplStore {
 20    fs: Arc<dyn Fs>,
 21    enabled: bool,
 22    sessions: HashMap<EntityId, View<Session>>,
 23    kernel_specifications: Vec<KernelSpecification>,
 24    _subscriptions: Vec<Subscription>,
 25}
 26
 27impl ReplStore {
 28    pub(crate) fn init(fs: Arc<dyn Fs>, cx: &mut AppContext) {
 29        let store = cx.new_model(move |cx| Self::new(fs, cx));
 30
 31        cx.set_global(GlobalReplStore(store))
 32    }
 33
 34    pub fn global(cx: &AppContext) -> Model<Self> {
 35        cx.global::<GlobalReplStore>().0.clone()
 36    }
 37
 38    pub fn new(fs: Arc<dyn Fs>, cx: &mut ModelContext<Self>) -> Self {
 39        let subscriptions = vec![cx.observe_global::<SettingsStore>(move |this, cx| {
 40            this.set_enabled(JupyterSettings::enabled(cx), cx);
 41        })];
 42
 43        Self {
 44            fs,
 45            enabled: JupyterSettings::enabled(cx),
 46            sessions: HashMap::default(),
 47            kernel_specifications: Vec::new(),
 48            _subscriptions: subscriptions,
 49        }
 50    }
 51
 52    pub fn is_enabled(&self) -> bool {
 53        self.enabled
 54    }
 55
 56    pub fn kernel_specifications(&self) -> impl Iterator<Item = &KernelSpecification> {
 57        self.kernel_specifications.iter()
 58    }
 59
 60    pub fn sessions(&self) -> impl Iterator<Item = &View<Session>> {
 61        self.sessions.values()
 62    }
 63
 64    fn set_enabled(&mut self, enabled: bool, cx: &mut ModelContext<Self>) {
 65        if self.enabled != enabled {
 66            self.enabled = enabled;
 67            cx.notify();
 68        }
 69    }
 70
 71    pub fn refresh_kernelspecs(&mut self, cx: &mut ModelContext<Self>) -> Task<Result<()>> {
 72        let kernel_specifications = kernel_specifications(self.fs.clone());
 73        cx.spawn(|this, mut cx| async move {
 74            let kernel_specifications = kernel_specifications.await?;
 75
 76            this.update(&mut cx, |this, cx| {
 77                this.kernel_specifications = kernel_specifications;
 78                cx.notify();
 79            })
 80        })
 81    }
 82
 83    pub fn kernelspec(
 84        &self,
 85        language: &Language,
 86        cx: &mut ModelContext<Self>,
 87    ) -> Option<KernelSpecification> {
 88        let settings = JupyterSettings::get_global(cx);
 89        let language_name = language.code_fence_block_name();
 90        let selected_kernel = settings.kernel_selections.get(language_name.as_ref());
 91
 92        self.kernel_specifications
 93            .iter()
 94            .find(|runtime_specification| {
 95                if let Some(selected) = selected_kernel {
 96                    // Top priority is the selected kernel
 97                    runtime_specification.name.to_lowercase() == selected.to_lowercase()
 98                } else {
 99                    // Otherwise, we'll try to find a kernel that matches the language
100                    runtime_specification.kernelspec.language.to_lowercase()
101                        == language_name.to_lowercase()
102                }
103            })
104            .cloned()
105    }
106
107    pub fn get_session(&self, entity_id: EntityId) -> Option<&View<Session>> {
108        self.sessions.get(&entity_id)
109    }
110
111    pub fn insert_session(&mut self, entity_id: EntityId, session: View<Session>) {
112        self.sessions.insert(entity_id, session);
113    }
114
115    pub fn remove_session(&mut self, entity_id: EntityId) {
116        self.sessions.remove(&entity_id);
117    }
118}