language_registry.rs

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