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