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 {name}: {e}",
 883                                        )));
 884                                    }
 885                                }
 886                            }
 887                        };
 888                    })
 889                    .detach();
 890
 891                entry.insert(vec![tx]);
 892            }
 893        }
 894
 895        drop(state);
 896        rx
 897    }
 898
 899    fn get_or_load_language(
 900        self: &Arc<Self>,
 901        callback: impl Fn(
 902            &LanguageName,
 903            &LanguageMatcher,
 904            LanguageMatchPrecedence,
 905        ) -> Option<LanguageMatchPrecedence>,
 906    ) -> oneshot::Receiver<Result<Arc<Language>>> {
 907        let Some(language) = self.find_matching_language(callback) else {
 908            let (tx, rx) = oneshot::channel();
 909            let _ = tx.send(Err(anyhow!(LanguageNotFound)));
 910            return rx;
 911        };
 912
 913        self.load_language(&language)
 914    }
 915
 916    fn get_or_load_grammar(
 917        self: &Arc<Self>,
 918        name: Arc<str>,
 919    ) -> impl Future<Output = Result<tree_sitter::Language>> {
 920        let (tx, rx) = oneshot::channel();
 921        let mut state = self.state.write();
 922
 923        if let Some(grammar) = state.grammars.get_mut(name.as_ref()) {
 924            match grammar {
 925                AvailableGrammar::LoadFailed(error) => {
 926                    tx.send(Err(error.clone())).ok();
 927                }
 928                AvailableGrammar::Native(grammar) | AvailableGrammar::Loaded(_, grammar) => {
 929                    tx.send(Ok(grammar.clone())).ok();
 930                }
 931                AvailableGrammar::Loading(_, txs) => {
 932                    txs.push(tx);
 933                }
 934                AvailableGrammar::Unloaded(wasm_path) => {
 935                    let this = self.clone();
 936                    let wasm_path = wasm_path.clone();
 937                    *grammar = AvailableGrammar::Loading(wasm_path.clone(), vec![tx]);
 938                    self.executor
 939                        .spawn(async move {
 940                            let grammar_result = maybe!({
 941                                let wasm_bytes = std::fs::read(&wasm_path)?;
 942                                let grammar_name = wasm_path
 943                                    .file_stem()
 944                                    .and_then(OsStr::to_str)
 945                                    .context("invalid grammar filename")?;
 946                                anyhow::Ok(with_parser(|parser| {
 947                                    let mut store = parser.take_wasm_store().unwrap();
 948                                    let grammar = store.load_language(grammar_name, &wasm_bytes);
 949                                    parser.set_wasm_store(store).unwrap();
 950                                    grammar
 951                                })?)
 952                            })
 953                            .map_err(Arc::new);
 954
 955                            let value = match &grammar_result {
 956                                Ok(grammar) => AvailableGrammar::Loaded(wasm_path, grammar.clone()),
 957                                Err(error) => AvailableGrammar::LoadFailed(error.clone()),
 958                            };
 959
 960                            let old_value = this.state.write().grammars.insert(name, value);
 961                            if let Some(AvailableGrammar::Loading(_, txs)) = old_value {
 962                                for tx in txs {
 963                                    tx.send(grammar_result.clone()).ok();
 964                                }
 965                            }
 966                        })
 967                        .detach();
 968                }
 969            }
 970        } else {
 971            tx.send(Err(Arc::new(anyhow!("no such grammar {name}"))))
 972                .ok();
 973        }
 974
 975        async move { rx.await?.map_err(|e| anyhow!(e)) }
 976    }
 977
 978    pub fn to_vec(&self) -> Vec<Arc<Language>> {
 979        self.state.read().languages.to_vec()
 980    }
 981
 982    pub fn lsp_adapters(&self, language_name: &LanguageName) -> Vec<Arc<CachedLspAdapter>> {
 983        self.state
 984            .read()
 985            .lsp_adapters
 986            .get(language_name)
 987            .cloned()
 988            .unwrap_or_default()
 989    }
 990
 991    pub fn all_lsp_adapters(&self) -> Vec<Arc<CachedLspAdapter>> {
 992        self.state
 993            .read()
 994            .all_lsp_adapters
 995            .values()
 996            .cloned()
 997            .collect()
 998    }
 999
1000    pub fn adapter_for_name(&self, name: &LanguageServerName) -> Option<Arc<CachedLspAdapter>> {
1001        self.state.read().all_lsp_adapters.get(name).cloned()
1002    }
1003
1004    pub fn update_lsp_status(&self, server_name: LanguageServerName, status: BinaryStatus) {
1005        self.lsp_binary_status_tx.send(server_name.0, status);
1006    }
1007
1008    pub fn next_language_server_id(&self) -> LanguageServerId {
1009        self.state.write().next_language_server_id()
1010    }
1011
1012    pub fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
1013        self.language_server_download_dir
1014            .as_ref()
1015            .map(|dir| Arc::from(dir.join(name.0.as_ref())))
1016    }
1017
1018    #[cfg(any(test, feature = "test-support"))]
1019    pub fn create_fake_language_server(
1020        &self,
1021        server_id: LanguageServerId,
1022        name: &LanguageServerName,
1023        binary: lsp::LanguageServerBinary,
1024        cx: &mut gpui::AsyncApp,
1025    ) -> Option<lsp::LanguageServer> {
1026        use gpui::AppContext as _;
1027
1028        let mut state = self.state.write();
1029        let fake_entry = state.fake_server_entries.get_mut(&name)?;
1030        let (server, mut fake_server) = lsp::FakeLanguageServer::new(
1031            server_id,
1032            binary,
1033            name.0.to_string(),
1034            fake_entry.capabilities.clone(),
1035            cx,
1036        );
1037        fake_entry._server = Some(fake_server.clone());
1038
1039        if let Some(initializer) = &fake_entry.initializer {
1040            initializer(&mut fake_server);
1041        }
1042
1043        let tx = fake_entry.tx.clone();
1044        cx.background_spawn(async move {
1045            if fake_server
1046                .try_receive_notification::<lsp::notification::Initialized>()
1047                .await
1048                .is_some()
1049            {
1050                tx.unbounded_send(fake_server.clone()).ok();
1051            }
1052        })
1053        .detach();
1054
1055        Some(server)
1056    }
1057
1058    pub fn language_server_binary_statuses(
1059        &self,
1060    ) -> mpsc::UnboundedReceiver<(SharedString, BinaryStatus)> {
1061        self.lsp_binary_status_tx.subscribe()
1062    }
1063
1064    pub async fn delete_server_container(&self, name: LanguageServerName) {
1065        log::info!("deleting server container");
1066        let Some(dir) = self.language_server_download_dir(&name) else {
1067            return;
1068        };
1069
1070        smol::fs::remove_dir_all(dir)
1071            .await
1072            .context("server container removal")
1073            .log_err();
1074    }
1075}
1076
1077impl LanguageRegistryState {
1078    fn next_language_server_id(&mut self) -> LanguageServerId {
1079        LanguageServerId(post_inc(&mut self.next_language_server_id))
1080    }
1081
1082    fn add(&mut self, language: Arc<Language>) {
1083        if let Some(theme) = self.theme.as_ref() {
1084            language.set_theme(theme.syntax());
1085        }
1086        self.language_settings.languages.insert(
1087            language.name(),
1088            LanguageSettingsContent {
1089                tab_size: language.config.tab_size,
1090                hard_tabs: language.config.hard_tabs,
1091                soft_wrap: language.config.soft_wrap,
1092                auto_indent_on_paste: language.config.auto_indent_on_paste,
1093                ..Default::default()
1094            }
1095            .clone(),
1096        );
1097        self.languages.push(language);
1098        self.version += 1;
1099        *self.subscription.0.borrow_mut() = ();
1100    }
1101
1102    fn reload(&mut self) {
1103        self.languages.clear();
1104        self.version += 1;
1105        self.reload_count += 1;
1106        for language in &mut self.available_languages {
1107            language.loaded = false;
1108        }
1109        *self.subscription.0.borrow_mut() = ();
1110    }
1111
1112    /// Reorders the list of language servers for the given language.
1113    ///
1114    /// Uses the provided list of ordered [`CachedLspAdapters`] as the desired order.
1115    ///
1116    /// Any existing language servers not present in `ordered_lsp_adapters` will be
1117    /// appended to the end.
1118    fn reorder_language_servers(
1119        &mut self,
1120        language_name: &LanguageName,
1121        ordered_lsp_adapters: Vec<Arc<CachedLspAdapter>>,
1122    ) {
1123        let Some(lsp_adapters) = self.lsp_adapters.get_mut(language_name) else {
1124            return;
1125        };
1126
1127        let ordered_lsp_adapter_ids = ordered_lsp_adapters
1128            .iter()
1129            .map(|lsp_adapter| lsp_adapter.name.clone())
1130            .collect::<HashSet<_>>();
1131
1132        let mut new_lsp_adapters = ordered_lsp_adapters;
1133        for adapter in lsp_adapters.iter() {
1134            if !ordered_lsp_adapter_ids.contains(&adapter.name) {
1135                new_lsp_adapters.push(adapter.clone());
1136            }
1137        }
1138
1139        *lsp_adapters = new_lsp_adapters;
1140    }
1141
1142    fn remove_languages(
1143        &mut self,
1144        languages_to_remove: &[LanguageName],
1145        grammars_to_remove: &[Arc<str>],
1146    ) {
1147        if languages_to_remove.is_empty() && grammars_to_remove.is_empty() {
1148            return;
1149        }
1150
1151        self.languages
1152            .retain(|language| !languages_to_remove.contains(&language.name()));
1153        self.available_languages
1154            .retain(|language| !languages_to_remove.contains(&language.name));
1155        self.grammars
1156            .retain(|name, _| !grammars_to_remove.contains(name));
1157        self.version += 1;
1158        self.reload_count += 1;
1159        *self.subscription.0.borrow_mut() = ();
1160    }
1161
1162    /// Mark the given language as having been loaded, so that the
1163    /// language registry won't try to load it again.
1164    fn mark_language_loaded(&mut self, id: LanguageId) {
1165        for language in &mut self.available_languages {
1166            if language.id == id {
1167                language.loaded = true;
1168                break;
1169            }
1170        }
1171    }
1172}
1173
1174impl BinaryStatusSender {
1175    fn subscribe(&self) -> mpsc::UnboundedReceiver<(SharedString, BinaryStatus)> {
1176        let (tx, rx) = mpsc::unbounded();
1177        self.txs.lock().push(tx);
1178        rx
1179    }
1180
1181    fn send(&self, name: SharedString, status: BinaryStatus) {
1182        let mut txs = self.txs.lock();
1183        txs.retain(|tx| tx.unbounded_send((name.clone(), status.clone())).is_ok());
1184    }
1185}