language_registry.rs

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