language_registry.rs

  1use crate::{
  2    language_settings::{
  3        all_language_settings, AllLanguageSettingsContent, LanguageSettingsContent,
  4    },
  5    task_context::ContextProvider,
  6    CachedLspAdapter, File, Language, LanguageConfig, LanguageId, LanguageMatcher,
  7    LanguageServerName, LspAdapter, LspAdapterDelegate, PARSER, PLAIN_TEXT,
  8};
  9use anyhow::{anyhow, Context as _, Result};
 10use collections::{hash_map, HashMap};
 11use futures::TryFutureExt;
 12use futures::{
 13    channel::{mpsc, oneshot},
 14    future::Shared,
 15    Future, FutureExt as _,
 16};
 17use gpui::{AppContext, BackgroundExecutor, Task};
 18use lsp::LanguageServerId;
 19use parking_lot::{Mutex, RwLock};
 20use postage::watch;
 21use std::{
 22    borrow::Cow,
 23    ffi::OsStr,
 24    ops::Not,
 25    path::{Path, PathBuf},
 26    sync::Arc,
 27};
 28use sum_tree::Bias;
 29use text::{Point, Rope};
 30use theme::Theme;
 31use unicase::UniCase;
 32use util::{maybe, paths::PathExt, post_inc, ResultExt};
 33
 34pub struct LanguageRegistry {
 35    state: RwLock<LanguageRegistryState>,
 36    language_server_download_dir: Option<Arc<Path>>,
 37    login_shell_env_loaded: Shared<Task<()>>,
 38    executor: BackgroundExecutor,
 39    lsp_binary_status_tx: LspBinaryStatusSender,
 40}
 41
 42struct LanguageRegistryState {
 43    next_language_server_id: usize,
 44    languages: Vec<Arc<Language>>,
 45    language_settings: AllLanguageSettingsContent,
 46    available_languages: Vec<AvailableLanguage>,
 47    grammars: HashMap<Arc<str>, AvailableGrammar>,
 48    lsp_adapters: HashMap<Arc<str>, Vec<Arc<CachedLspAdapter>>>,
 49    loading_languages: HashMap<LanguageId, Vec<oneshot::Sender<Result<Arc<Language>>>>>,
 50    subscription: (watch::Sender<()>, watch::Receiver<()>),
 51    theme: Option<Arc<Theme>>,
 52    version: usize,
 53    reload_count: usize,
 54
 55    #[cfg(any(test, feature = "test-support"))]
 56    fake_server_txs:
 57        HashMap<Arc<str>, Vec<futures::channel::mpsc::UnboundedSender<lsp::FakeLanguageServer>>>,
 58}
 59
 60#[derive(Clone, Debug, PartialEq, Eq)]
 61pub enum LanguageServerBinaryStatus {
 62    None,
 63    CheckingForUpdate,
 64    Downloading,
 65    Failed { error: String },
 66}
 67
 68pub struct PendingLanguageServer {
 69    pub server_id: LanguageServerId,
 70    pub task: Task<Result<(lsp::LanguageServer, Option<serde_json::Value>)>>,
 71    pub container_dir: Option<Arc<Path>>,
 72}
 73
 74#[derive(Clone)]
 75struct AvailableLanguage {
 76    id: LanguageId,
 77    name: Arc<str>,
 78    grammar: Option<Arc<str>>,
 79    matcher: LanguageMatcher,
 80    load: Arc<
 81        dyn Fn() -> Result<(
 82                LanguageConfig,
 83                LanguageQueries,
 84                Option<Arc<dyn ContextProvider>>,
 85            )>
 86            + 'static
 87            + Send
 88            + Sync,
 89    >,
 90    loaded: bool,
 91}
 92
 93enum AvailableGrammar {
 94    Native(tree_sitter::Language),
 95    Loaded(#[allow(unused)] PathBuf, tree_sitter::Language),
 96    Loading(
 97        #[allow(unused)] PathBuf,
 98        Vec<oneshot::Sender<Result<tree_sitter::Language, Arc<anyhow::Error>>>>,
 99    ),
100    Unloaded(PathBuf),
101    LoadFailed(Arc<anyhow::Error>),
102}
103
104#[derive(Debug)]
105pub struct LanguageNotFound;
106
107impl std::fmt::Display for LanguageNotFound {
108    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
109        write!(f, "language not found")
110    }
111}
112
113pub const QUERY_FILENAME_PREFIXES: &[(
114    &str,
115    fn(&mut LanguageQueries) -> &mut Option<Cow<'static, str>>,
116)] = &[
117    ("highlights", |q| &mut q.highlights),
118    ("brackets", |q| &mut q.brackets),
119    ("outline", |q| &mut q.outline),
120    ("indents", |q| &mut q.indents),
121    ("embedding", |q| &mut q.embedding),
122    ("injections", |q| &mut q.injections),
123    ("overrides", |q| &mut q.overrides),
124    ("redactions", |q| &mut q.redactions),
125];
126
127/// Tree-sitter language queries for a given language.
128#[derive(Debug, Default)]
129pub struct LanguageQueries {
130    pub highlights: Option<Cow<'static, str>>,
131    pub brackets: Option<Cow<'static, str>>,
132    pub indents: Option<Cow<'static, str>>,
133    pub outline: Option<Cow<'static, str>>,
134    pub embedding: Option<Cow<'static, str>>,
135    pub injections: Option<Cow<'static, str>>,
136    pub overrides: Option<Cow<'static, str>>,
137    pub redactions: Option<Cow<'static, str>>,
138}
139
140#[derive(Clone, Default)]
141struct LspBinaryStatusSender {
142    txs: Arc<Mutex<Vec<mpsc::UnboundedSender<(LanguageServerName, LanguageServerBinaryStatus)>>>>,
143}
144
145impl LanguageRegistry {
146    pub fn new(login_shell_env_loaded: Task<()>, executor: BackgroundExecutor) -> Self {
147        let this = Self {
148            state: RwLock::new(LanguageRegistryState {
149                next_language_server_id: 0,
150                languages: Vec::new(),
151                available_languages: Vec::new(),
152                grammars: Default::default(),
153                language_settings: Default::default(),
154                loading_languages: Default::default(),
155                lsp_adapters: Default::default(),
156                subscription: watch::channel(),
157                theme: Default::default(),
158                version: 0,
159                reload_count: 0,
160
161                #[cfg(any(test, feature = "test-support"))]
162                fake_server_txs: Default::default(),
163            }),
164            language_server_download_dir: None,
165            login_shell_env_loaded: login_shell_env_loaded.shared(),
166            lsp_binary_status_tx: Default::default(),
167            executor,
168        };
169        this.add(PLAIN_TEXT.clone());
170        this
171    }
172
173    #[cfg(any(test, feature = "test-support"))]
174    pub fn test(executor: BackgroundExecutor) -> Self {
175        let mut this = Self::new(Task::ready(()), executor);
176        this.language_server_download_dir = Some(Path::new("/the-download-dir").into());
177        this
178    }
179
180    /// Clears out all of the loaded languages and reload them from scratch.
181    pub fn reload(&self) {
182        self.state.write().reload();
183    }
184
185    /// Removes the specified languages and grammars from the registry.
186    pub fn remove_languages(
187        &self,
188        languages_to_remove: &[Arc<str>],
189        grammars_to_remove: &[Arc<str>],
190    ) {
191        self.state
192            .write()
193            .remove_languages(languages_to_remove, grammars_to_remove)
194    }
195
196    pub fn remove_lsp_adapter(&self, language_name: &str, name: &LanguageServerName) {
197        let mut state = self.state.write();
198        if let Some(adapters) = state.lsp_adapters.get_mut(language_name) {
199            adapters.retain(|adapter| &adapter.name != name)
200        }
201        state.version += 1;
202        state.reload_count += 1;
203        *state.subscription.0.borrow_mut() = ();
204    }
205
206    #[cfg(any(feature = "test-support", test))]
207    pub fn register_test_language(&self, config: LanguageConfig) {
208        self.register_language(
209            config.name.clone(),
210            config.grammar.clone(),
211            config.matcher.clone(),
212            move || Ok((config.clone(), Default::default(), None)),
213        )
214    }
215
216    pub fn register_lsp_adapter(&self, language_name: Arc<str>, adapter: Arc<dyn LspAdapter>) {
217        self.state
218            .write()
219            .lsp_adapters
220            .entry(language_name)
221            .or_default()
222            .push(CachedLspAdapter::new(adapter, true));
223    }
224
225    pub fn register_secondary_lsp_adapter(
226        &self,
227        language_name: Arc<str>,
228        adapter: Arc<dyn LspAdapter>,
229    ) {
230        self.state
231            .write()
232            .lsp_adapters
233            .entry(language_name)
234            .or_default()
235            .push(CachedLspAdapter::new(adapter, false));
236    }
237
238    #[cfg(any(feature = "test-support", test))]
239    pub fn register_fake_lsp_adapter(
240        &self,
241        language_name: &str,
242        adapter: crate::FakeLspAdapter,
243    ) -> futures::channel::mpsc::UnboundedReceiver<lsp::FakeLanguageServer> {
244        self.register_specific_fake_lsp_adapter(language_name, true, adapter)
245    }
246
247    #[cfg(any(feature = "test-support", test))]
248    pub fn register_specific_fake_lsp_adapter(
249        &self,
250        language_name: &str,
251        primary: bool,
252        adapter: crate::FakeLspAdapter,
253    ) -> futures::channel::mpsc::UnboundedReceiver<lsp::FakeLanguageServer> {
254        self.state
255            .write()
256            .lsp_adapters
257            .entry(language_name.into())
258            .or_default()
259            .push(CachedLspAdapter::new(Arc::new(adapter), primary));
260        self.fake_language_servers(language_name)
261    }
262
263    #[cfg(any(feature = "test-support", test))]
264    pub fn fake_language_servers(
265        &self,
266        language_name: &str,
267    ) -> futures::channel::mpsc::UnboundedReceiver<lsp::FakeLanguageServer> {
268        let (servers_tx, servers_rx) = futures::channel::mpsc::unbounded();
269        self.state
270            .write()
271            .fake_server_txs
272            .entry(language_name.into())
273            .or_default()
274            .push(servers_tx);
275        servers_rx
276    }
277
278    /// Adds a language to the registry, which can be loaded if needed.
279    pub fn register_language(
280        &self,
281        name: Arc<str>,
282        grammar_name: Option<Arc<str>>,
283        matcher: LanguageMatcher,
284        load: impl Fn() -> Result<(
285                LanguageConfig,
286                LanguageQueries,
287                Option<Arc<dyn ContextProvider>>,
288            )>
289            + 'static
290            + Send
291            + Sync,
292    ) {
293        let load = Arc::new(load);
294        let state = &mut *self.state.write();
295
296        for existing_language in &mut state.available_languages {
297            if existing_language.name == name {
298                existing_language.grammar = grammar_name;
299                existing_language.matcher = matcher;
300                existing_language.load = load;
301                return;
302            }
303        }
304
305        state.available_languages.push(AvailableLanguage {
306            id: LanguageId::new(),
307            name,
308            grammar: grammar_name,
309            matcher,
310            load,
311            loaded: false,
312        });
313        state.version += 1;
314        state.reload_count += 1;
315        *state.subscription.0.borrow_mut() = ();
316    }
317
318    /// Adds grammars to the registry. Language configurations reference a grammar by name. The
319    /// grammar controls how the source code is parsed.
320    pub fn register_native_grammars(
321        &self,
322        grammars: impl IntoIterator<Item = (impl Into<Arc<str>>, tree_sitter::Language)>,
323    ) {
324        self.state.write().grammars.extend(
325            grammars
326                .into_iter()
327                .map(|(name, grammar)| (name.into(), AvailableGrammar::Native(grammar))),
328        );
329    }
330
331    /// Adds paths to WASM grammar files, which can be loaded if needed.
332    pub fn register_wasm_grammars(
333        &self,
334        grammars: impl IntoIterator<Item = (impl Into<Arc<str>>, PathBuf)>,
335    ) {
336        let mut state = self.state.write();
337        state.grammars.extend(
338            grammars
339                .into_iter()
340                .map(|(name, path)| (name.into(), AvailableGrammar::Unloaded(path))),
341        );
342        state.version += 1;
343        state.reload_count += 1;
344        *state.subscription.0.borrow_mut() = ();
345    }
346
347    pub fn language_settings(&self) -> AllLanguageSettingsContent {
348        self.state.read().language_settings.clone()
349    }
350
351    pub fn language_names(&self) -> Vec<String> {
352        let state = self.state.read();
353        let mut result = state
354            .available_languages
355            .iter()
356            .filter_map(|l| l.loaded.not().then_some(l.name.to_string()))
357            .chain(state.languages.iter().map(|l| l.config.name.to_string()))
358            .collect::<Vec<_>>();
359        result.sort_unstable_by_key(|language_name| language_name.to_lowercase());
360        result
361    }
362
363    pub fn grammar_names(&self) -> Vec<Arc<str>> {
364        let state = self.state.read();
365        let mut result = state.grammars.keys().cloned().collect::<Vec<_>>();
366        result.sort_unstable_by_key(|grammar_name| grammar_name.to_lowercase());
367        result
368    }
369
370    /// Add a pre-loaded language to the registry.
371    pub fn add(&self, language: Arc<Language>) {
372        let mut state = self.state.write();
373        state.available_languages.push(AvailableLanguage {
374            id: language.id,
375            name: language.name(),
376            grammar: language.config.grammar.clone(),
377            matcher: language.config.matcher.clone(),
378            load: Arc::new(|| Err(anyhow!("already loaded"))),
379            loaded: true,
380        });
381        state.add(language);
382    }
383
384    pub fn subscribe(&self) -> watch::Receiver<()> {
385        self.state.read().subscription.1.clone()
386    }
387
388    /// Returns the number of times that the registry has been changed,
389    /// by adding languages or reloading.
390    pub fn version(&self) -> usize {
391        self.state.read().version
392    }
393
394    /// Returns the number of times that the registry has been reloaded.
395    pub fn reload_count(&self) -> usize {
396        self.state.read().reload_count
397    }
398
399    pub fn set_theme(&self, theme: Arc<Theme>) {
400        let mut state = self.state.write();
401        state.theme = Some(theme.clone());
402        for language in &state.languages {
403            language.set_theme(theme.syntax());
404        }
405    }
406
407    pub fn set_language_server_download_dir(&mut self, path: impl Into<Arc<Path>>) {
408        self.language_server_download_dir = Some(path.into());
409    }
410
411    pub fn language_for_name(
412        self: &Arc<Self>,
413        name: &str,
414    ) -> impl Future<Output = Result<Arc<Language>>> {
415        let name = UniCase::new(name);
416        let rx = self.get_or_load_language(|language_name, _| {
417            if UniCase::new(language_name) == name {
418                1
419            } else {
420                0
421            }
422        });
423        async move { rx.await? }
424    }
425
426    pub fn language_for_name_or_extension(
427        self: &Arc<Self>,
428        string: &str,
429    ) -> impl Future<Output = Result<Arc<Language>>> {
430        let string = UniCase::new(string);
431        let rx = self.get_or_load_language(|name, config| {
432            if UniCase::new(name) == string
433                || config
434                    .path_suffixes
435                    .iter()
436                    .any(|suffix| UniCase::new(suffix) == string)
437            {
438                1
439            } else {
440                0
441            }
442        });
443        async move { rx.await? }
444    }
445
446    pub fn language_for_file(
447        self: &Arc<Self>,
448        file: &Arc<dyn File>,
449        content: Option<&Rope>,
450        cx: &AppContext,
451    ) -> impl Future<Output = Result<Arc<Language>>> {
452        let user_file_types = all_language_settings(Some(file), cx);
453        self.language_for_file_internal(
454            &file.full_path(cx),
455            content,
456            Some(&user_file_types.file_types),
457        )
458    }
459
460    pub fn language_for_file_path<'a>(
461        self: &Arc<Self>,
462        path: &'a Path,
463    ) -> impl Future<Output = Result<Arc<Language>>> + 'a {
464        self.language_for_file_internal(path, None, None)
465            .map_err(|error| error.context(format!("language for file path {}", path.display())))
466    }
467
468    fn language_for_file_internal(
469        self: &Arc<Self>,
470        path: &Path,
471        content: Option<&Rope>,
472        user_file_types: Option<&HashMap<Arc<str>, Vec<String>>>,
473    ) -> impl Future<Output = Result<Arc<Language>>> {
474        let filename = path.file_name().and_then(|name| name.to_str());
475        let extension = path.extension_or_hidden_file_name();
476        let path_suffixes = [extension, filename];
477        let empty = Vec::new();
478
479        let rx = self.get_or_load_language(move |language_name, config| {
480            let path_matches_default_suffix = config
481                .path_suffixes
482                .iter()
483                .any(|suffix| path_suffixes.contains(&Some(suffix.as_str())));
484            let path_matches_custom_suffix = user_file_types
485                .and_then(|types| types.get(language_name))
486                .unwrap_or(&empty)
487                .iter()
488                .any(|suffix| path_suffixes.contains(&Some(suffix.as_str())));
489            let content_matches = content.zip(config.first_line_pattern.as_ref()).map_or(
490                false,
491                |(content, pattern)| {
492                    let end = content.clip_point(Point::new(0, 256), Bias::Left);
493                    let end = content.point_to_offset(end);
494                    let text = content.chunks_in_range(0..end).collect::<String>();
495                    pattern.is_match(&text)
496                },
497            );
498            if path_matches_custom_suffix {
499                2
500            } else if path_matches_default_suffix || content_matches {
501                1
502            } else {
503                0
504            }
505        });
506        async move { rx.await? }
507    }
508
509    fn get_or_load_language(
510        self: &Arc<Self>,
511        callback: impl Fn(&str, &LanguageMatcher) -> usize,
512    ) -> oneshot::Receiver<Result<Arc<Language>>> {
513        let (tx, rx) = oneshot::channel();
514
515        let mut state = self.state.write();
516        let Some((language, _)) = state
517            .available_languages
518            .iter()
519            .filter_map(|language| {
520                let score = callback(&language.name, &language.matcher);
521                if score > 0 {
522                    Some((language.clone(), score))
523                } else {
524                    None
525                }
526            })
527            .max_by_key(|e| e.1)
528            .clone()
529        else {
530            let _ = tx.send(Err(anyhow!(LanguageNotFound)));
531            return rx;
532        };
533
534        // If the language is already loaded, resolve with it immediately.
535        for loaded_language in state.languages.iter() {
536            if loaded_language.id == language.id {
537                let _ = tx.send(Ok(loaded_language.clone()));
538                return rx;
539            }
540        }
541
542        match state.loading_languages.entry(language.id) {
543            // If the language is already being loaded, then add this
544            // channel to a list that will be sent to when the load completes.
545            hash_map::Entry::Occupied(mut entry) => entry.get_mut().push(tx),
546
547            // Otherwise, start loading the language.
548            hash_map::Entry::Vacant(entry) => {
549                let this = self.clone();
550                self.executor
551                    .spawn(async move {
552                        let id = language.id;
553                        let name = language.name.clone();
554                        let language = async {
555                            let (config, queries, provider) = (language.load)()?;
556
557                            if let Some(grammar) = config.grammar.clone() {
558                                let grammar = Some(this.get_or_load_grammar(grammar).await?);
559                                Language::new_with_id(id, config, grammar)
560                                    .with_context_provider(provider)
561                                    .with_queries(queries)
562                            } else {
563                                Ok(Language::new_with_id(id, config, None)
564                                    .with_context_provider(provider))
565                            }
566                        }
567                        .await;
568
569                        match language {
570                            Ok(language) => {
571                                let language = Arc::new(language);
572                                let mut state = this.state.write();
573
574                                state.add(language.clone());
575                                state.mark_language_loaded(id);
576                                if let Some(mut txs) = state.loading_languages.remove(&id) {
577                                    for tx in txs.drain(..) {
578                                        let _ = tx.send(Ok(language.clone()));
579                                    }
580                                }
581                            }
582                            Err(e) => {
583                                log::error!("failed to load language {name}:\n{:?}", e);
584                                let mut state = this.state.write();
585                                state.mark_language_loaded(id);
586                                if let Some(mut txs) = state.loading_languages.remove(&id) {
587                                    for tx in txs.drain(..) {
588                                        let _ = tx.send(Err(anyhow!(
589                                            "failed to load language {}: {}",
590                                            name,
591                                            e
592                                        )));
593                                    }
594                                }
595                            }
596                        };
597                    })
598                    .detach();
599                entry.insert(vec![tx]);
600            }
601        }
602
603        rx
604    }
605
606    fn get_or_load_grammar(
607        self: &Arc<Self>,
608        name: Arc<str>,
609    ) -> impl Future<Output = Result<tree_sitter::Language>> {
610        let (tx, rx) = oneshot::channel();
611        let mut state = self.state.write();
612
613        if let Some(grammar) = state.grammars.get_mut(name.as_ref()) {
614            match grammar {
615                AvailableGrammar::LoadFailed(error) => {
616                    tx.send(Err(error.clone())).ok();
617                }
618                AvailableGrammar::Native(grammar) | AvailableGrammar::Loaded(_, grammar) => {
619                    tx.send(Ok(grammar.clone())).ok();
620                }
621                AvailableGrammar::Loading(_, txs) => {
622                    txs.push(tx);
623                }
624                AvailableGrammar::Unloaded(wasm_path) => {
625                    let this = self.clone();
626                    let wasm_path = wasm_path.clone();
627                    *grammar = AvailableGrammar::Loading(wasm_path.clone(), vec![tx]);
628                    self.executor
629                        .spawn(async move {
630                            let grammar_result = maybe!({
631                                let wasm_bytes = std::fs::read(&wasm_path)?;
632                                let grammar_name = wasm_path
633                                    .file_stem()
634                                    .and_then(OsStr::to_str)
635                                    .ok_or_else(|| anyhow!("invalid grammar filename"))?;
636                                anyhow::Ok(PARSER.with(|parser| {
637                                    let mut parser = parser.borrow_mut();
638                                    let mut store = parser.take_wasm_store().unwrap();
639                                    let grammar = store.load_language(&grammar_name, &wasm_bytes);
640                                    parser.set_wasm_store(store).unwrap();
641                                    grammar
642                                })?)
643                            })
644                            .map_err(Arc::new);
645
646                            let value = match &grammar_result {
647                                Ok(grammar) => AvailableGrammar::Loaded(wasm_path, grammar.clone()),
648                                Err(error) => AvailableGrammar::LoadFailed(error.clone()),
649                            };
650
651                            let old_value = this.state.write().grammars.insert(name, value);
652                            if let Some(AvailableGrammar::Loading(_, txs)) = old_value {
653                                for tx in txs {
654                                    tx.send(grammar_result.clone()).ok();
655                                }
656                            }
657                        })
658                        .detach();
659                }
660            }
661        } else {
662            tx.send(Err(Arc::new(anyhow!("no such grammar {}", name))))
663                .ok();
664        }
665
666        async move { rx.await?.map_err(|e| anyhow!(e)) }
667    }
668
669    pub fn to_vec(&self) -> Vec<Arc<Language>> {
670        self.state.read().languages.iter().cloned().collect()
671    }
672
673    pub fn lsp_adapters(&self, language: &Arc<Language>) -> Vec<Arc<CachedLspAdapter>> {
674        self.state
675            .read()
676            .lsp_adapters
677            .get(&language.config.name)
678            .cloned()
679            .unwrap_or_default()
680    }
681
682    pub fn all_prettier_plugins(&self) -> Vec<Arc<str>> {
683        let state = self.state.read();
684        state
685            .languages
686            .iter()
687            .flat_map(|language| language.config.prettier_plugins.iter().cloned())
688            .collect()
689    }
690
691    pub fn update_lsp_status(
692        &self,
693        server_name: LanguageServerName,
694        status: LanguageServerBinaryStatus,
695    ) {
696        self.lsp_binary_status_tx.send(server_name, status);
697    }
698
699    pub fn create_pending_language_server(
700        self: &Arc<Self>,
701        stderr_capture: Arc<Mutex<Option<String>>>,
702        language: Arc<Language>,
703        adapter: Arc<CachedLspAdapter>,
704        root_path: Arc<Path>,
705        delegate: Arc<dyn LspAdapterDelegate>,
706        cx: &mut AppContext,
707    ) -> Option<PendingLanguageServer> {
708        let server_id = self.state.write().next_language_server_id();
709        log::info!(
710            "starting language server {:?}, path: {root_path:?}, id: {server_id}",
711            adapter.name.0
712        );
713
714        let download_dir = self
715            .language_server_download_dir
716            .clone()
717            .ok_or_else(|| anyhow!("language server download directory has not been assigned before starting server"))
718            .log_err()?;
719        let language = language.clone();
720        let container_dir: Arc<Path> = Arc::from(download_dir.join(adapter.name.0.as_ref()));
721        let root_path = root_path.clone();
722        let login_shell_env_loaded = self.login_shell_env_loaded.clone();
723        let this = Arc::downgrade(self);
724
725        let task = cx.spawn({
726            let container_dir = container_dir.clone();
727            move |mut cx| async move {
728                // If we want to install a binary globally, we need to wait for
729                // the login shell to be set on our process.
730                login_shell_env_loaded.await;
731
732                let binary_result = adapter
733                    .clone()
734                    .get_language_server_command(
735                        language.clone(),
736                        container_dir,
737                        delegate.clone(),
738                        &mut cx,
739                    )
740                    .await;
741
742                delegate.update_status(adapter.name.clone(), LanguageServerBinaryStatus::None);
743
744                let binary = binary_result?;
745                let options = adapter
746                    .adapter
747                    .clone()
748                    .initialization_options(&delegate)
749                    .await?;
750
751                if let Some(task) = adapter.will_start_server(&delegate, &mut cx) {
752                    task.await?;
753                }
754
755                #[cfg(any(test, feature = "test-support"))]
756                if true {
757                    let capabilities = adapter
758                        .as_fake()
759                        .map(|fake_adapter| fake_adapter.capabilities.clone())
760                        .unwrap_or_else(|| lsp::ServerCapabilities {
761                            completion_provider: Some(Default::default()),
762                            ..Default::default()
763                        });
764
765                    let (server, mut fake_server) = lsp::FakeLanguageServer::new(
766                        server_id,
767                        binary,
768                        adapter.name.0.to_string(),
769                        capabilities,
770                        cx.clone(),
771                    );
772
773                    if let Some(fake_adapter) = adapter.as_fake() {
774                        if let Some(initializer) = &fake_adapter.initializer {
775                            initializer(&mut fake_server);
776                        }
777                    }
778
779                    cx.background_executor()
780                        .spawn(async move {
781                            if fake_server
782                                .try_receive_notification::<lsp::notification::Initialized>()
783                                .await
784                                .is_some()
785                            {
786                                if let Some(this) = this.upgrade() {
787                                    if let Some(txs) = this
788                                        .state
789                                        .write()
790                                        .fake_server_txs
791                                        .get_mut(language.name().as_ref())
792                                    {
793                                        for tx in txs {
794                                            tx.unbounded_send(fake_server.clone()).ok();
795                                        }
796                                    }
797                                }
798                            }
799                        })
800                        .detach();
801
802                    return Ok((server, options));
803                }
804
805                drop(this);
806                Ok((
807                    lsp::LanguageServer::new(
808                        stderr_capture,
809                        server_id,
810                        binary,
811                        &root_path,
812                        adapter.code_action_kinds(),
813                        cx,
814                    )?,
815                    options,
816                ))
817            }
818        });
819
820        Some(PendingLanguageServer {
821            server_id,
822            task,
823            container_dir: Some(container_dir),
824        })
825    }
826
827    pub fn language_server_binary_statuses(
828        &self,
829    ) -> mpsc::UnboundedReceiver<(LanguageServerName, LanguageServerBinaryStatus)> {
830        self.lsp_binary_status_tx.subscribe()
831    }
832
833    pub fn delete_server_container(
834        &self,
835        adapter: Arc<CachedLspAdapter>,
836        cx: &mut AppContext,
837    ) -> Task<()> {
838        log::info!("deleting server container");
839
840        let download_dir = self
841            .language_server_download_dir
842            .clone()
843            .expect("language server download directory has not been assigned before deleting server container");
844
845        cx.spawn(|_| async move {
846            let container_dir = download_dir.join(adapter.name.0.as_ref());
847            smol::fs::remove_dir_all(container_dir)
848                .await
849                .context("server container removal")
850                .log_err();
851        })
852    }
853
854    pub fn next_language_server_id(&self) -> LanguageServerId {
855        self.state.write().next_language_server_id()
856    }
857}
858
859impl LanguageRegistryState {
860    fn next_language_server_id(&mut self) -> LanguageServerId {
861        LanguageServerId(post_inc(&mut self.next_language_server_id))
862    }
863
864    fn add(&mut self, language: Arc<Language>) {
865        if let Some(theme) = self.theme.as_ref() {
866            language.set_theme(theme.syntax());
867        }
868        self.language_settings.languages.insert(
869            language.name(),
870            LanguageSettingsContent {
871                tab_size: language.config.tab_size,
872                hard_tabs: language.config.hard_tabs,
873                soft_wrap: language.config.soft_wrap,
874                ..Default::default()
875            }
876            .clone(),
877        );
878        self.languages.push(language);
879        self.version += 1;
880        *self.subscription.0.borrow_mut() = ();
881    }
882
883    fn reload(&mut self) {
884        self.languages.clear();
885        self.version += 1;
886        self.reload_count += 1;
887        for language in &mut self.available_languages {
888            language.loaded = false;
889        }
890        *self.subscription.0.borrow_mut() = ();
891    }
892
893    fn remove_languages(
894        &mut self,
895        languages_to_remove: &[Arc<str>],
896        grammars_to_remove: &[Arc<str>],
897    ) {
898        if languages_to_remove.is_empty() && grammars_to_remove.is_empty() {
899            return;
900        }
901
902        self.languages
903            .retain(|language| !languages_to_remove.contains(&language.name()));
904        self.available_languages
905            .retain(|language| !languages_to_remove.contains(&language.name));
906        self.grammars
907            .retain(|name, _| !grammars_to_remove.contains(&name));
908        self.version += 1;
909        self.reload_count += 1;
910        *self.subscription.0.borrow_mut() = ();
911    }
912
913    /// Mark the given language as having been loaded, so that the
914    /// language registry won't try to load it again.
915    fn mark_language_loaded(&mut self, id: LanguageId) {
916        for language in &mut self.available_languages {
917            if language.id == id {
918                language.loaded = true;
919                break;
920            }
921        }
922    }
923}
924
925impl LspBinaryStatusSender {
926    fn subscribe(
927        &self,
928    ) -> mpsc::UnboundedReceiver<(LanguageServerName, LanguageServerBinaryStatus)> {
929        let (tx, rx) = mpsc::unbounded();
930        self.txs.lock().push(tx);
931        rx
932    }
933
934    fn send(&self, name: LanguageServerName, status: LanguageServerBinaryStatus) {
935        let mut txs = self.txs.lock();
936        txs.retain(|tx| tx.unbounded_send((name.clone(), status.clone())).is_ok());
937    }
938}