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