language_registry.rs

   1use crate::{
   2    CachedLspAdapter, File, Language, LanguageConfig, LanguageId, LanguageMatcher,
   3    LanguageServerName, LspAdapter, PLAIN_TEXT, ToolchainLister,
   4    language_settings::{
   5        AllLanguageSettingsContent, LanguageSettingsContent, all_language_settings,
   6    },
   7    task_context::ContextProvider,
   8    with_parser,
   9};
  10use anyhow::{Context as _, Result, anyhow};
  11use collections::{FxHashMap, HashMap, HashSet, hash_map};
  12
  13use futures::{
  14    Future,
  15    channel::{mpsc, oneshot},
  16};
  17use globset::GlobSet;
  18use gpui::{App, BackgroundExecutor, SharedString};
  19use itertools::FoldWhile::{Continue, Done};
  20use itertools::Itertools;
  21use lsp::LanguageServerId;
  22use parking_lot::{Mutex, RwLock};
  23use postage::watch;
  24use schemars::JsonSchema;
  25use serde::{Deserialize, Serialize};
  26use smallvec::SmallVec;
  27use std::{
  28    borrow::{Borrow, Cow},
  29    cell::LazyCell,
  30    ffi::OsStr,
  31    ops::Not,
  32    path::{Path, PathBuf},
  33    sync::Arc,
  34};
  35use sum_tree::Bias;
  36use text::{Point, Rope};
  37use theme::Theme;
  38use unicase::UniCase;
  39use util::{ResultExt, maybe, post_inc};
  40
  41#[derive(
  42    Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, JsonSchema,
  43)]
  44pub struct LanguageName(SharedString);
  45
  46impl LanguageName {
  47    pub fn new(s: &str) -> Self {
  48        Self(SharedString::new(s))
  49    }
  50
  51    pub fn from_proto(s: String) -> Self {
  52        Self(SharedString::from(s))
  53    }
  54    pub fn to_proto(self) -> String {
  55        self.0.to_string()
  56    }
  57    pub fn lsp_id(&self) -> String {
  58        match self.0.as_ref() {
  59            "Plain Text" => "plaintext".to_string(),
  60            language_name => language_name.to_lowercase(),
  61        }
  62    }
  63}
  64
  65impl From<LanguageName> for SharedString {
  66    fn from(value: LanguageName) -> Self {
  67        value.0
  68    }
  69}
  70
  71impl AsRef<str> for LanguageName {
  72    fn as_ref(&self) -> &str {
  73        self.0.as_ref()
  74    }
  75}
  76
  77impl Borrow<str> for LanguageName {
  78    fn borrow(&self) -> &str {
  79        self.0.as_ref()
  80    }
  81}
  82
  83impl std::fmt::Display for LanguageName {
  84    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
  85        write!(f, "{}", self.0)
  86    }
  87}
  88
  89impl<'a> From<&'a str> for LanguageName {
  90    fn from(str: &'a str) -> LanguageName {
  91        LanguageName(SharedString::new(str))
  92    }
  93}
  94
  95impl From<LanguageName> for String {
  96    fn from(value: LanguageName) -> Self {
  97        let value: &str = &value.0;
  98        Self::from(value)
  99    }
 100}
 101
 102pub struct LanguageRegistry {
 103    state: RwLock<LanguageRegistryState>,
 104    language_server_download_dir: Option<Arc<Path>>,
 105    executor: BackgroundExecutor,
 106    lsp_binary_status_tx: BinaryStatusSender,
 107    dap_binary_status_tx: BinaryStatusSender,
 108}
 109
 110struct LanguageRegistryState {
 111    next_language_server_id: usize,
 112    languages: Vec<Arc<Language>>,
 113    language_settings: AllLanguageSettingsContent,
 114    available_languages: Vec<AvailableLanguage>,
 115    grammars: HashMap<Arc<str>, AvailableGrammar>,
 116    lsp_adapters: HashMap<LanguageName, Vec<Arc<CachedLspAdapter>>>,
 117    all_lsp_adapters: HashMap<LanguageServerName, Arc<CachedLspAdapter>>,
 118    available_lsp_adapters:
 119        HashMap<LanguageServerName, Arc<dyn Fn() -> Arc<CachedLspAdapter> + 'static + Send + Sync>>,
 120    loading_languages: HashMap<LanguageId, Vec<oneshot::Sender<Result<Arc<Language>>>>>,
 121    subscription: (watch::Sender<()>, watch::Receiver<()>),
 122    theme: Option<Arc<Theme>>,
 123    version: usize,
 124    reload_count: usize,
 125
 126    #[cfg(any(test, feature = "test-support"))]
 127    fake_server_entries: HashMap<LanguageServerName, FakeLanguageServerEntry>,
 128}
 129
 130#[cfg(any(test, feature = "test-support"))]
 131pub struct FakeLanguageServerEntry {
 132    pub capabilities: lsp::ServerCapabilities,
 133    pub initializer: Option<Box<dyn 'static + Send + Sync + Fn(&mut lsp::FakeLanguageServer)>>,
 134    pub tx: futures::channel::mpsc::UnboundedSender<lsp::FakeLanguageServer>,
 135    pub _server: Option<lsp::FakeLanguageServer>,
 136}
 137
 138#[derive(Clone, Debug, PartialEq, Eq)]
 139pub enum BinaryStatus {
 140    None,
 141    CheckingForUpdate,
 142    Downloading,
 143    Failed { error: String },
 144}
 145
 146#[derive(Clone)]
 147pub struct AvailableLanguage {
 148    id: LanguageId,
 149    name: LanguageName,
 150    grammar: Option<Arc<str>>,
 151    matcher: LanguageMatcher,
 152    hidden: bool,
 153    load: Arc<dyn Fn() -> Result<LoadedLanguage> + 'static + Send + Sync>,
 154    loaded: bool,
 155}
 156
 157impl AvailableLanguage {
 158    pub fn name(&self) -> LanguageName {
 159        self.name.clone()
 160    }
 161
 162    pub fn matcher(&self) -> &LanguageMatcher {
 163        &self.matcher
 164    }
 165    pub fn hidden(&self) -> bool {
 166        self.hidden
 167    }
 168}
 169
 170#[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
 171enum LanguageMatchPrecedence {
 172    #[default]
 173    Undetermined,
 174    PathOrContent,
 175    UserConfigured,
 176}
 177
 178impl LanguageMatchPrecedence {
 179    fn best_possible_match(&self) -> bool {
 180        *self == LanguageMatchPrecedence::UserConfigured
 181    }
 182}
 183
 184enum AvailableGrammar {
 185    Native(tree_sitter::Language),
 186    Loaded(#[allow(unused)] PathBuf, tree_sitter::Language),
 187    Loading(
 188        #[allow(unused)] PathBuf,
 189        Vec<oneshot::Sender<Result<tree_sitter::Language, Arc<anyhow::Error>>>>,
 190    ),
 191    Unloaded(PathBuf),
 192    LoadFailed(Arc<anyhow::Error>),
 193}
 194
 195#[derive(Debug)]
 196pub struct LanguageNotFound;
 197
 198impl std::fmt::Display for LanguageNotFound {
 199    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 200        write!(f, "language not found")
 201    }
 202}
 203
 204pub const QUERY_FILENAME_PREFIXES: &[(
 205    &str,
 206    fn(&mut LanguageQueries) -> &mut Option<Cow<'static, str>>,
 207)] = &[
 208    ("highlights", |q| &mut q.highlights),
 209    ("brackets", |q| &mut q.brackets),
 210    ("outline", |q| &mut q.outline),
 211    ("indents", |q| &mut q.indents),
 212    ("embedding", |q| &mut q.embedding),
 213    ("injections", |q| &mut q.injections),
 214    ("overrides", |q| &mut q.overrides),
 215    ("redactions", |q| &mut q.redactions),
 216    ("runnables", |q| &mut q.runnables),
 217    ("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}
 234
 235#[derive(Clone, Default)]
 236struct BinaryStatusSender {
 237    txs: Arc<Mutex<Vec<mpsc::UnboundedSender<(SharedString, BinaryStatus)>>>>,
 238}
 239
 240pub struct LoadedLanguage {
 241    pub config: LanguageConfig,
 242    pub queries: LanguageQueries,
 243    pub context_provider: Option<Arc<dyn ContextProvider>>,
 244    pub toolchain_provider: Option<Arc<dyn ToolchainLister>>,
 245}
 246
 247impl LanguageRegistry {
 248    pub fn new(executor: BackgroundExecutor) -> Self {
 249        let this = Self {
 250            state: RwLock::new(LanguageRegistryState {
 251                next_language_server_id: 0,
 252                languages: Vec::new(),
 253                available_languages: Vec::new(),
 254                grammars: Default::default(),
 255                language_settings: Default::default(),
 256                loading_languages: Default::default(),
 257                lsp_adapters: Default::default(),
 258                all_lsp_adapters: Default::default(),
 259                available_lsp_adapters: HashMap::default(),
 260                subscription: watch::channel(),
 261                theme: Default::default(),
 262                version: 0,
 263                reload_count: 0,
 264
 265                #[cfg(any(test, feature = "test-support"))]
 266                fake_server_entries: Default::default(),
 267            }),
 268            language_server_download_dir: None,
 269            lsp_binary_status_tx: Default::default(),
 270            dap_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 update_dap_status(&self, server_name: LanguageServerName, status: BinaryStatus) {
 988        self.dap_binary_status_tx.send(server_name.0, status);
 989    }
 990
 991    pub fn next_language_server_id(&self) -> LanguageServerId {
 992        self.state.write().next_language_server_id()
 993    }
 994
 995    pub fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
 996        self.language_server_download_dir
 997            .as_ref()
 998            .map(|dir| Arc::from(dir.join(name.0.as_ref())))
 999    }
1000
1001    #[cfg(any(test, feature = "test-support"))]
1002    pub fn create_fake_language_server(
1003        &self,
1004        server_id: LanguageServerId,
1005        name: &LanguageServerName,
1006        binary: lsp::LanguageServerBinary,
1007        cx: &mut gpui::AsyncApp,
1008    ) -> Option<lsp::LanguageServer> {
1009        use gpui::AppContext as _;
1010
1011        let mut state = self.state.write();
1012        let fake_entry = state.fake_server_entries.get_mut(&name)?;
1013        let (server, mut fake_server) = lsp::FakeLanguageServer::new(
1014            server_id,
1015            binary,
1016            name.0.to_string(),
1017            fake_entry.capabilities.clone(),
1018            cx,
1019        );
1020        fake_entry._server = Some(fake_server.clone());
1021
1022        if let Some(initializer) = &fake_entry.initializer {
1023            initializer(&mut fake_server);
1024        }
1025
1026        let tx = fake_entry.tx.clone();
1027        cx.background_spawn(async move {
1028            if fake_server
1029                .try_receive_notification::<lsp::notification::Initialized>()
1030                .await
1031                .is_some()
1032            {
1033                tx.unbounded_send(fake_server.clone()).ok();
1034            }
1035        })
1036        .detach();
1037
1038        Some(server)
1039    }
1040
1041    pub fn language_server_binary_statuses(
1042        &self,
1043    ) -> mpsc::UnboundedReceiver<(SharedString, BinaryStatus)> {
1044        self.lsp_binary_status_tx.subscribe()
1045    }
1046
1047    pub fn dap_server_binary_statuses(
1048        &self,
1049    ) -> mpsc::UnboundedReceiver<(SharedString, BinaryStatus)> {
1050        self.dap_binary_status_tx.subscribe()
1051    }
1052
1053    pub async fn delete_server_container(&self, name: LanguageServerName) {
1054        log::info!("deleting server container");
1055        let Some(dir) = self.language_server_download_dir(&name) else {
1056            return;
1057        };
1058
1059        smol::fs::remove_dir_all(dir)
1060            .await
1061            .context("server container removal")
1062            .log_err();
1063    }
1064}
1065
1066impl LanguageRegistryState {
1067    fn next_language_server_id(&mut self) -> LanguageServerId {
1068        LanguageServerId(post_inc(&mut self.next_language_server_id))
1069    }
1070
1071    fn add(&mut self, language: Arc<Language>) {
1072        if let Some(theme) = self.theme.as_ref() {
1073            language.set_theme(theme.syntax());
1074        }
1075        self.language_settings.languages.insert(
1076            language.name(),
1077            LanguageSettingsContent {
1078                tab_size: language.config.tab_size,
1079                hard_tabs: language.config.hard_tabs,
1080                soft_wrap: language.config.soft_wrap,
1081                auto_indent_on_paste: language.config.auto_indent_on_paste,
1082                ..Default::default()
1083            }
1084            .clone(),
1085        );
1086        self.languages.push(language);
1087        self.version += 1;
1088        *self.subscription.0.borrow_mut() = ();
1089    }
1090
1091    fn reload(&mut self) {
1092        self.languages.clear();
1093        self.version += 1;
1094        self.reload_count += 1;
1095        for language in &mut self.available_languages {
1096            language.loaded = false;
1097        }
1098        *self.subscription.0.borrow_mut() = ();
1099    }
1100
1101    /// Reorders the list of language servers for the given language.
1102    ///
1103    /// Uses the provided list of ordered [`CachedLspAdapters`] as the desired order.
1104    ///
1105    /// Any existing language servers not present in `ordered_lsp_adapters` will be
1106    /// appended to the end.
1107    fn reorder_language_servers(
1108        &mut self,
1109        language_name: &LanguageName,
1110        ordered_lsp_adapters: Vec<Arc<CachedLspAdapter>>,
1111    ) {
1112        let Some(lsp_adapters) = self.lsp_adapters.get_mut(language_name) else {
1113            return;
1114        };
1115
1116        let ordered_lsp_adapter_ids = ordered_lsp_adapters
1117            .iter()
1118            .map(|lsp_adapter| lsp_adapter.name.clone())
1119            .collect::<HashSet<_>>();
1120
1121        let mut new_lsp_adapters = ordered_lsp_adapters;
1122        for adapter in lsp_adapters.iter() {
1123            if !ordered_lsp_adapter_ids.contains(&adapter.name) {
1124                new_lsp_adapters.push(adapter.clone());
1125            }
1126        }
1127
1128        *lsp_adapters = new_lsp_adapters;
1129    }
1130
1131    fn remove_languages(
1132        &mut self,
1133        languages_to_remove: &[LanguageName],
1134        grammars_to_remove: &[Arc<str>],
1135    ) {
1136        if languages_to_remove.is_empty() && grammars_to_remove.is_empty() {
1137            return;
1138        }
1139
1140        self.languages
1141            .retain(|language| !languages_to_remove.contains(&language.name()));
1142        self.available_languages
1143            .retain(|language| !languages_to_remove.contains(&language.name));
1144        self.grammars
1145            .retain(|name, _| !grammars_to_remove.contains(name));
1146        self.version += 1;
1147        self.reload_count += 1;
1148        *self.subscription.0.borrow_mut() = ();
1149    }
1150
1151    /// Mark the given language as having been loaded, so that the
1152    /// language registry won't try to load it again.
1153    fn mark_language_loaded(&mut self, id: LanguageId) {
1154        for language in &mut self.available_languages {
1155            if language.id == id {
1156                language.loaded = true;
1157                break;
1158            }
1159        }
1160    }
1161}
1162
1163impl BinaryStatusSender {
1164    fn subscribe(&self) -> mpsc::UnboundedReceiver<(SharedString, BinaryStatus)> {
1165        let (tx, rx) = mpsc::unbounded();
1166        self.txs.lock().push(tx);
1167        rx
1168    }
1169
1170    fn send(&self, name: SharedString, status: BinaryStatus) {
1171        let mut txs = self.txs.lock();
1172        txs.retain(|tx| tx.unbounded_send((name.clone(), status.clone())).is_ok());
1173    }
1174}