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