language.rs

   1//! The `language` crate provides a large chunk of Zed's language-related
   2//! features (the other big contributors being project and lsp crates that revolve around LSP features).
   3//! Namely, this crate:
   4//! - Provides [`Language`], [`Grammar`] and [`LanguageRegistry`] types that
   5//! use Tree-sitter to provide syntax highlighting to the editor; note though that `language` doesn't perform the highlighting by itself. It only maps ranges in a buffer to colors. Treesitter is also used for buffer outlines (lists of symbols in a buffer)
   6//! - Exposes [`LanguageConfig`] that describes how constructs (like brackets or line comments) should be handled by the editor for a source file of a particular language.
   7//!
   8//! Notably we do *not* assign a single language to a single file; in real world a single file can consist of multiple programming languages - HTML is a good example of that - and `language` crate tends to reflect that status quo in it's API.
   9mod buffer;
  10mod diagnostic_set;
  11mod highlight_map;
  12pub mod language_settings;
  13mod outline;
  14pub mod proto;
  15mod syntax_map;
  16
  17#[cfg(test)]
  18mod buffer_tests;
  19pub mod markdown;
  20
  21use anyhow::{anyhow, Context, Result};
  22use async_trait::async_trait;
  23use collections::{HashMap, HashSet};
  24use futures::{
  25    channel::{mpsc, oneshot},
  26    future::Shared,
  27    FutureExt, TryFutureExt as _,
  28};
  29use gpui::{AppContext, AsyncAppContext, BackgroundExecutor, Task};
  30pub use highlight_map::HighlightMap;
  31use lazy_static::lazy_static;
  32use lsp::{CodeActionKind, LanguageServerBinary};
  33use parking_lot::{Mutex, RwLock};
  34use postage::watch;
  35use regex::Regex;
  36use serde::{de, Deserialize, Deserializer};
  37use serde_json::Value;
  38use std::{
  39    any::Any,
  40    borrow::Cow,
  41    cell::RefCell,
  42    fmt::Debug,
  43    hash::Hash,
  44    mem,
  45    ops::{Not, Range},
  46    path::{Path, PathBuf},
  47    str,
  48    sync::{
  49        atomic::{AtomicU64, AtomicUsize, Ordering::SeqCst},
  50        Arc,
  51    },
  52};
  53use syntax_map::SyntaxSnapshot;
  54use theme::{SyntaxTheme, Theme};
  55use tree_sitter::{self, wasmtime, Query, WasmStore};
  56use unicase::UniCase;
  57use util::{http::HttpClient, paths::PathExt};
  58use util::{post_inc, ResultExt, TryFutureExt as _, UnwrapFuture};
  59
  60pub use buffer::Operation;
  61pub use buffer::*;
  62pub use diagnostic_set::DiagnosticEntry;
  63pub use lsp::LanguageServerId;
  64pub use outline::{Outline, OutlineItem};
  65pub use syntax_map::{OwnedSyntaxLayer, SyntaxLayer};
  66pub use text::LineEnding;
  67pub use tree_sitter::{Parser, Tree};
  68
  69/// Initializes the `language` crate.
  70///
  71/// This should be called before making use of items from the create.
  72pub fn init(cx: &mut AppContext) {
  73    language_settings::init(cx);
  74}
  75
  76#[derive(Clone, Default)]
  77struct LspBinaryStatusSender {
  78    txs: Arc<Mutex<Vec<mpsc::UnboundedSender<(Arc<Language>, LanguageServerBinaryStatus)>>>>,
  79}
  80
  81impl LspBinaryStatusSender {
  82    fn subscribe(&self) -> mpsc::UnboundedReceiver<(Arc<Language>, LanguageServerBinaryStatus)> {
  83        let (tx, rx) = mpsc::unbounded();
  84        self.txs.lock().push(tx);
  85        rx
  86    }
  87
  88    fn send(&self, language: Arc<Language>, status: LanguageServerBinaryStatus) {
  89        let mut txs = self.txs.lock();
  90        txs.retain(|tx| {
  91            tx.unbounded_send((language.clone(), status.clone()))
  92                .is_ok()
  93        });
  94    }
  95}
  96
  97thread_local! {
  98    static PARSER: RefCell<Parser> = {
  99        let mut parser = Parser::new();
 100        parser.set_wasm_store(WasmStore::new(WASM_ENGINE.clone()).unwrap()).unwrap();
 101        RefCell::new(parser)
 102    };
 103}
 104
 105lazy_static! {
 106    pub(crate) static ref NEXT_GRAMMAR_ID: AtomicUsize = Default::default();
 107    /// A shared grammar for plain text, exposed for reuse by downstream crates.
 108    #[doc(hidden)]
 109    pub static ref WASM_ENGINE: wasmtime::Engine = wasmtime::Engine::default();
 110    pub static ref PLAIN_TEXT: Arc<Language> = Arc::new(Language::new(
 111        LanguageConfig {
 112            name: "Plain Text".into(),
 113            ..Default::default()
 114        },
 115        None,
 116    ));
 117}
 118
 119/// Types that represent a position in a buffer, and can be converted into
 120/// an LSP position, to send to a language server.
 121pub trait ToLspPosition {
 122    /// Converts the value into an LSP position.
 123    fn to_lsp_position(self) -> lsp::Position;
 124}
 125
 126/// A name of a language server.
 127#[derive(Clone, Debug, PartialEq, Eq, Hash)]
 128pub struct LanguageServerName(pub Arc<str>);
 129
 130/// Represents a Language Server, with certain cached sync properties.
 131/// Uses [`LspAdapter`] under the hood, but calls all 'static' methods
 132/// once at startup, and caches the results.
 133pub struct CachedLspAdapter {
 134    pub name: LanguageServerName,
 135    pub short_name: &'static str,
 136    pub disk_based_diagnostic_sources: Vec<String>,
 137    pub disk_based_diagnostics_progress_token: Option<String>,
 138    pub language_ids: HashMap<String, String>,
 139    pub adapter: Arc<dyn LspAdapter>,
 140    pub reinstall_attempt_count: AtomicU64,
 141}
 142
 143impl CachedLspAdapter {
 144    pub async fn new(adapter: Arc<dyn LspAdapter>) -> Arc<Self> {
 145        let name = adapter.name();
 146        let short_name = adapter.short_name();
 147        let disk_based_diagnostic_sources = adapter.disk_based_diagnostic_sources();
 148        let disk_based_diagnostics_progress_token = adapter.disk_based_diagnostics_progress_token();
 149        let language_ids = adapter.language_ids();
 150
 151        Arc::new(CachedLspAdapter {
 152            name,
 153            short_name,
 154            disk_based_diagnostic_sources,
 155            disk_based_diagnostics_progress_token,
 156            language_ids,
 157            adapter,
 158            reinstall_attempt_count: AtomicU64::new(0),
 159        })
 160    }
 161
 162    pub async fn fetch_latest_server_version(
 163        &self,
 164        delegate: &dyn LspAdapterDelegate,
 165    ) -> Result<Box<dyn 'static + Send + Any>> {
 166        self.adapter.fetch_latest_server_version(delegate).await
 167    }
 168
 169    pub fn will_fetch_server(
 170        &self,
 171        delegate: &Arc<dyn LspAdapterDelegate>,
 172        cx: &mut AsyncAppContext,
 173    ) -> Option<Task<Result<()>>> {
 174        self.adapter.will_fetch_server(delegate, cx)
 175    }
 176
 177    pub fn will_start_server(
 178        &self,
 179        delegate: &Arc<dyn LspAdapterDelegate>,
 180        cx: &mut AsyncAppContext,
 181    ) -> Option<Task<Result<()>>> {
 182        self.adapter.will_start_server(delegate, cx)
 183    }
 184
 185    pub async fn fetch_server_binary(
 186        &self,
 187        version: Box<dyn 'static + Send + Any>,
 188        container_dir: PathBuf,
 189        delegate: &dyn LspAdapterDelegate,
 190    ) -> Result<LanguageServerBinary> {
 191        self.adapter
 192            .fetch_server_binary(version, container_dir, delegate)
 193            .await
 194    }
 195
 196    pub async fn cached_server_binary(
 197        &self,
 198        container_dir: PathBuf,
 199        delegate: &dyn LspAdapterDelegate,
 200    ) -> Option<LanguageServerBinary> {
 201        self.adapter
 202            .cached_server_binary(container_dir, delegate)
 203            .await
 204    }
 205
 206    pub fn can_be_reinstalled(&self) -> bool {
 207        self.adapter.can_be_reinstalled()
 208    }
 209
 210    pub async fn installation_test_binary(
 211        &self,
 212        container_dir: PathBuf,
 213    ) -> Option<LanguageServerBinary> {
 214        self.adapter.installation_test_binary(container_dir).await
 215    }
 216
 217    pub fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
 218        self.adapter.code_action_kinds()
 219    }
 220
 221    pub fn workspace_configuration(&self, workspace_root: &Path, cx: &mut AppContext) -> Value {
 222        self.adapter.workspace_configuration(workspace_root, cx)
 223    }
 224
 225    pub fn process_diagnostics(&self, params: &mut lsp::PublishDiagnosticsParams) {
 226        self.adapter.process_diagnostics(params)
 227    }
 228
 229    pub async fn process_completion(&self, completion_item: &mut lsp::CompletionItem) {
 230        self.adapter.process_completion(completion_item).await
 231    }
 232
 233    pub async fn label_for_completion(
 234        &self,
 235        completion_item: &lsp::CompletionItem,
 236        language: &Arc<Language>,
 237    ) -> Option<CodeLabel> {
 238        self.adapter
 239            .label_for_completion(completion_item, language)
 240            .await
 241    }
 242
 243    pub async fn label_for_symbol(
 244        &self,
 245        name: &str,
 246        kind: lsp::SymbolKind,
 247        language: &Arc<Language>,
 248    ) -> Option<CodeLabel> {
 249        self.adapter.label_for_symbol(name, kind, language).await
 250    }
 251
 252    pub fn prettier_plugins(&self) -> &[&'static str] {
 253        self.adapter.prettier_plugins()
 254    }
 255}
 256
 257/// [`LspAdapterDelegate`] allows [`LspAdapter]` implementations to interface with the application
 258// e.g. to display a notification or fetch data from the web.
 259pub trait LspAdapterDelegate: Send + Sync {
 260    fn show_notification(&self, message: &str, cx: &mut AppContext);
 261    fn http_client(&self) -> Arc<dyn HttpClient>;
 262}
 263
 264#[async_trait]
 265pub trait LspAdapter: 'static + Send + Sync {
 266    fn name(&self) -> LanguageServerName;
 267
 268    fn short_name(&self) -> &'static str;
 269
 270    async fn fetch_latest_server_version(
 271        &self,
 272        delegate: &dyn LspAdapterDelegate,
 273    ) -> Result<Box<dyn 'static + Send + Any>>;
 274
 275    fn will_fetch_server(
 276        &self,
 277        _: &Arc<dyn LspAdapterDelegate>,
 278        _: &mut AsyncAppContext,
 279    ) -> Option<Task<Result<()>>> {
 280        None
 281    }
 282
 283    fn will_start_server(
 284        &self,
 285        _: &Arc<dyn LspAdapterDelegate>,
 286        _: &mut AsyncAppContext,
 287    ) -> Option<Task<Result<()>>> {
 288        None
 289    }
 290
 291    async fn fetch_server_binary(
 292        &self,
 293        version: Box<dyn 'static + Send + Any>,
 294        container_dir: PathBuf,
 295        delegate: &dyn LspAdapterDelegate,
 296    ) -> Result<LanguageServerBinary>;
 297
 298    async fn cached_server_binary(
 299        &self,
 300        container_dir: PathBuf,
 301        delegate: &dyn LspAdapterDelegate,
 302    ) -> Option<LanguageServerBinary>;
 303
 304    /// Returns `true` if a language server can be reinstalled.
 305    ///
 306    /// If language server initialization fails, a reinstallation will be attempted unless the value returned from this method is `false`.
 307    ///
 308    /// Implementations that rely on software already installed on user's system
 309    /// should have [`can_be_reinstalled`](Self::can_be_reinstalled) return `false`.
 310    fn can_be_reinstalled(&self) -> bool {
 311        true
 312    }
 313
 314    async fn installation_test_binary(
 315        &self,
 316        container_dir: PathBuf,
 317    ) -> Option<LanguageServerBinary>;
 318
 319    fn process_diagnostics(&self, _: &mut lsp::PublishDiagnosticsParams) {}
 320
 321    /// A callback called for each [`lsp::CompletionItem`] obtained from LSP server.
 322    /// Some LspAdapter implementations might want to modify the obtained item to
 323    /// change how it's displayed.
 324    async fn process_completion(&self, _: &mut lsp::CompletionItem) {}
 325
 326    async fn label_for_completion(
 327        &self,
 328        _: &lsp::CompletionItem,
 329        _: &Arc<Language>,
 330    ) -> Option<CodeLabel> {
 331        None
 332    }
 333
 334    async fn label_for_symbol(
 335        &self,
 336        _: &str,
 337        _: lsp::SymbolKind,
 338        _: &Arc<Language>,
 339    ) -> Option<CodeLabel> {
 340        None
 341    }
 342
 343    /// Returns initialization options that are going to be sent to a LSP server as a part of [`lsp::InitializeParams`]
 344    fn initialization_options(&self) -> Option<Value> {
 345        None
 346    }
 347
 348    fn workspace_configuration(&self, _workspace_root: &Path, _cx: &mut AppContext) -> Value {
 349        serde_json::json!({})
 350    }
 351
 352    /// Returns a list of code actions supported by a given LspAdapter
 353    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
 354        Some(vec![
 355            CodeActionKind::EMPTY,
 356            CodeActionKind::QUICKFIX,
 357            CodeActionKind::REFACTOR,
 358            CodeActionKind::REFACTOR_EXTRACT,
 359            CodeActionKind::SOURCE,
 360        ])
 361    }
 362
 363    fn disk_based_diagnostic_sources(&self) -> Vec<String> {
 364        Default::default()
 365    }
 366
 367    fn disk_based_diagnostics_progress_token(&self) -> Option<String> {
 368        None
 369    }
 370
 371    fn language_ids(&self) -> HashMap<String, String> {
 372        Default::default()
 373    }
 374
 375    fn prettier_plugins(&self) -> &[&'static str] {
 376        &[]
 377    }
 378}
 379
 380#[derive(Clone, Debug, PartialEq, Eq)]
 381pub struct CodeLabel {
 382    /// The text to display.
 383    pub text: String,
 384    /// Syntax highlighting runs.
 385    pub runs: Vec<(Range<usize>, HighlightId)>,
 386    /// The portion of the text that should be used in fuzzy filtering.
 387    pub filter_range: Range<usize>,
 388}
 389
 390#[derive(Clone, Deserialize)]
 391pub struct LanguageConfig {
 392    /// Human-readable name of the language.
 393    pub name: Arc<str>,
 394    // The name of the grammar in a WASM bundle (experimental).
 395    pub grammar_name: Option<Arc<str>>,
 396    /// Given a list of `LanguageConfig`'s, the language of a file can be determined based on the path extension matching any of the `path_suffixes`.
 397    pub path_suffixes: Vec<String>,
 398    /// List of bracket types in a language.
 399    pub brackets: BracketPairConfig,
 400    /// A regex pattern that determines whether the language should be assigned to a file or not.
 401    #[serde(default, deserialize_with = "deserialize_regex")]
 402    pub first_line_pattern: Option<Regex>,
 403    /// If set to true, auto indentation uses last non empty line to determine
 404    /// the indentation level for a new line.
 405    #[serde(default = "auto_indent_using_last_non_empty_line_default")]
 406    pub auto_indent_using_last_non_empty_line: bool,
 407    /// A regex that is used to determine whether the indentation level should be
 408    /// increased in the following line.
 409    #[serde(default, deserialize_with = "deserialize_regex")]
 410    pub increase_indent_pattern: Option<Regex>,
 411    /// A regex that is used to determine whether the indentation level should be
 412    /// decreased in the following line.
 413    #[serde(default, deserialize_with = "deserialize_regex")]
 414    pub decrease_indent_pattern: Option<Regex>,
 415    /// A list of characters that trigger the automatic insertion of a closing
 416    /// bracket when they immediately precede the point where an opening
 417    /// bracket is inserted.
 418    #[serde(default)]
 419    pub autoclose_before: String,
 420    /// A placeholder used internally by Semantic Index.
 421    #[serde(default)]
 422    pub collapsed_placeholder: String,
 423    /// A line comment string that is inserted in e.g. `toggle comments` action.
 424    /// A language can have multiple flavours of line comments. All of the provided line comments are
 425    /// used for comment continuations on the next line, but only the first one is used for Editor::ToggleComments.
 426    #[serde(default)]
 427    pub line_comments: Vec<Arc<str>>,
 428    /// Starting and closing characters of a block comment.
 429    #[serde(default)]
 430    pub block_comment: Option<(Arc<str>, Arc<str>)>,
 431    /// A list of language servers that are allowed to run on subranges of a given language.
 432    #[serde(default)]
 433    pub scope_opt_in_language_servers: Vec<String>,
 434    #[serde(default)]
 435    pub overrides: HashMap<String, LanguageConfigOverride>,
 436    /// A list of characters that Zed should treat as word characters for the
 437    /// purpose of features that operate on word boundaries, like 'move to next word end'
 438    /// or a whole-word search in buffer search.
 439    #[serde(default)]
 440    pub word_characters: HashSet<char>,
 441    /// The name of a Prettier parser that should be used for this language.
 442    #[serde(default)]
 443    pub prettier_parser_name: Option<String>,
 444}
 445
 446/// Tree-sitter language queries for a given language.
 447#[derive(Debug, Default)]
 448pub struct LanguageQueries {
 449    pub highlights: Option<Cow<'static, str>>,
 450    pub brackets: Option<Cow<'static, str>>,
 451    pub indents: Option<Cow<'static, str>>,
 452    pub outline: Option<Cow<'static, str>>,
 453    pub embedding: Option<Cow<'static, str>>,
 454    pub injections: Option<Cow<'static, str>>,
 455    pub overrides: Option<Cow<'static, str>>,
 456}
 457
 458/// Represents a language for the given range. Some languages (e.g. HTML)
 459/// interleave several languages together, thus a single buffer might actually contain
 460/// several nested scopes.
 461#[derive(Clone, Debug)]
 462pub struct LanguageScope {
 463    language: Arc<Language>,
 464    override_id: Option<u32>,
 465}
 466
 467#[derive(Clone, Deserialize, Default, Debug)]
 468pub struct LanguageConfigOverride {
 469    #[serde(default)]
 470    pub line_comments: Override<Vec<Arc<str>>>,
 471    #[serde(default)]
 472    pub block_comment: Override<(Arc<str>, Arc<str>)>,
 473    #[serde(skip_deserializing)]
 474    pub disabled_bracket_ixs: Vec<u16>,
 475    #[serde(default)]
 476    pub word_characters: Override<HashSet<char>>,
 477    #[serde(default)]
 478    pub opt_into_language_servers: Vec<String>,
 479}
 480
 481#[derive(Clone, Deserialize, Debug)]
 482#[serde(untagged)]
 483pub enum Override<T> {
 484    Remove { remove: bool },
 485    Set(T),
 486}
 487
 488impl<T> Default for Override<T> {
 489    fn default() -> Self {
 490        Override::Remove { remove: false }
 491    }
 492}
 493
 494impl<T> Override<T> {
 495    fn as_option<'a>(this: Option<&'a Self>, original: Option<&'a T>) -> Option<&'a T> {
 496        match this {
 497            Some(Self::Set(value)) => Some(value),
 498            Some(Self::Remove { remove: true }) => None,
 499            Some(Self::Remove { remove: false }) | None => original,
 500        }
 501    }
 502}
 503
 504impl Default for LanguageConfig {
 505    fn default() -> Self {
 506        Self {
 507            name: "".into(),
 508            grammar_name: None,
 509            path_suffixes: Default::default(),
 510            brackets: Default::default(),
 511            auto_indent_using_last_non_empty_line: auto_indent_using_last_non_empty_line_default(),
 512            first_line_pattern: Default::default(),
 513            increase_indent_pattern: Default::default(),
 514            decrease_indent_pattern: Default::default(),
 515            autoclose_before: Default::default(),
 516            line_comments: Default::default(),
 517            block_comment: Default::default(),
 518            scope_opt_in_language_servers: Default::default(),
 519            overrides: Default::default(),
 520            word_characters: Default::default(),
 521            prettier_parser_name: None,
 522            collapsed_placeholder: Default::default(),
 523        }
 524    }
 525}
 526
 527fn auto_indent_using_last_non_empty_line_default() -> bool {
 528    true
 529}
 530
 531fn deserialize_regex<'de, D: Deserializer<'de>>(d: D) -> Result<Option<Regex>, D::Error> {
 532    let source = Option::<String>::deserialize(d)?;
 533    if let Some(source) = source {
 534        Ok(Some(regex::Regex::new(&source).map_err(de::Error::custom)?))
 535    } else {
 536        Ok(None)
 537    }
 538}
 539
 540#[doc(hidden)]
 541#[cfg(any(test, feature = "test-support"))]
 542pub struct FakeLspAdapter {
 543    pub name: &'static str,
 544    pub initialization_options: Option<Value>,
 545    pub capabilities: lsp::ServerCapabilities,
 546    pub initializer: Option<Box<dyn 'static + Send + Sync + Fn(&mut lsp::FakeLanguageServer)>>,
 547    pub disk_based_diagnostics_progress_token: Option<String>,
 548    pub disk_based_diagnostics_sources: Vec<String>,
 549    pub prettier_plugins: Vec<&'static str>,
 550}
 551
 552/// Configuration of handling bracket pairs for a given language.
 553///
 554/// This struct includes settings for defining which pairs of characters are considered brackets and
 555/// also specifies any language-specific scopes where these pairs should be ignored for bracket matching purposes.
 556#[derive(Clone, Debug, Default)]
 557pub struct BracketPairConfig {
 558    /// A list of character pairs that should be treated as brackets in the context of a given language.
 559    pub pairs: Vec<BracketPair>,
 560    /// A list of tree-sitter scopes for which a given bracket should not be active.
 561    /// N-th entry in `[Self::disabled_scopes_by_bracket_ix]` contains a list of disabled scopes for an n-th entry in `[Self::pairs]`
 562    pub disabled_scopes_by_bracket_ix: Vec<Vec<String>>,
 563}
 564
 565impl<'de> Deserialize<'de> for BracketPairConfig {
 566    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
 567    where
 568        D: Deserializer<'de>,
 569    {
 570        #[derive(Deserialize)]
 571        pub struct Entry {
 572            #[serde(flatten)]
 573            pub bracket_pair: BracketPair,
 574            #[serde(default)]
 575            pub not_in: Vec<String>,
 576        }
 577
 578        let result = Vec::<Entry>::deserialize(deserializer)?;
 579        let mut brackets = Vec::with_capacity(result.len());
 580        let mut disabled_scopes_by_bracket_ix = Vec::with_capacity(result.len());
 581        for entry in result {
 582            brackets.push(entry.bracket_pair);
 583            disabled_scopes_by_bracket_ix.push(entry.not_in);
 584        }
 585
 586        Ok(BracketPairConfig {
 587            pairs: brackets,
 588            disabled_scopes_by_bracket_ix,
 589        })
 590    }
 591}
 592
 593/// Describes a single bracket pair and how an editor should react to e.g. inserting
 594/// an opening bracket or to a newline character insertion in between `start` and `end` characters.
 595#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
 596pub struct BracketPair {
 597    /// Starting substring for a bracket.
 598    pub start: String,
 599    /// Ending substring for a bracket.
 600    pub end: String,
 601    /// True if `end` should be automatically inserted right after `start` characters.
 602    pub close: bool,
 603    /// True if an extra newline should be inserted while the cursor is in the middle
 604    /// of that bracket pair.
 605    pub newline: bool,
 606}
 607
 608pub struct Language {
 609    pub(crate) config: LanguageConfig,
 610    pub(crate) grammar: Option<Arc<Grammar>>,
 611    pub(crate) adapters: Vec<Arc<CachedLspAdapter>>,
 612
 613    #[cfg(any(test, feature = "test-support"))]
 614    fake_adapter: Option<(
 615        mpsc::UnboundedSender<lsp::FakeLanguageServer>,
 616        Arc<FakeLspAdapter>,
 617    )>,
 618}
 619
 620pub struct Grammar {
 621    id: usize,
 622    pub ts_language: tree_sitter::Language,
 623    pub(crate) error_query: Query,
 624    pub(crate) highlights_query: Option<Query>,
 625    pub(crate) brackets_config: Option<BracketConfig>,
 626    pub(crate) indents_config: Option<IndentConfig>,
 627    pub outline_config: Option<OutlineConfig>,
 628    pub embedding_config: Option<EmbeddingConfig>,
 629    pub(crate) injection_config: Option<InjectionConfig>,
 630    pub(crate) override_config: Option<OverrideConfig>,
 631    pub(crate) highlight_map: Mutex<HighlightMap>,
 632}
 633
 634struct IndentConfig {
 635    query: Query,
 636    indent_capture_ix: u32,
 637    start_capture_ix: Option<u32>,
 638    end_capture_ix: Option<u32>,
 639    outdent_capture_ix: Option<u32>,
 640}
 641
 642pub struct OutlineConfig {
 643    pub query: Query,
 644    pub item_capture_ix: u32,
 645    pub name_capture_ix: u32,
 646    pub context_capture_ix: Option<u32>,
 647    pub extra_context_capture_ix: Option<u32>,
 648}
 649
 650#[derive(Debug)]
 651pub struct EmbeddingConfig {
 652    pub query: Query,
 653    pub item_capture_ix: u32,
 654    pub name_capture_ix: Option<u32>,
 655    pub context_capture_ix: Option<u32>,
 656    pub collapse_capture_ix: Option<u32>,
 657    pub keep_capture_ix: Option<u32>,
 658}
 659
 660struct InjectionConfig {
 661    query: Query,
 662    content_capture_ix: u32,
 663    language_capture_ix: Option<u32>,
 664    patterns: Vec<InjectionPatternConfig>,
 665}
 666
 667struct OverrideConfig {
 668    query: Query,
 669    values: HashMap<u32, (String, LanguageConfigOverride)>,
 670}
 671
 672#[derive(Default, Clone)]
 673struct InjectionPatternConfig {
 674    language: Option<Box<str>>,
 675    combined: bool,
 676}
 677
 678struct BracketConfig {
 679    query: Query,
 680    open_capture_ix: u32,
 681    close_capture_ix: u32,
 682}
 683
 684#[derive(Clone)]
 685pub enum LanguageServerBinaryStatus {
 686    CheckingForUpdate,
 687    Downloading,
 688    Downloaded,
 689    Cached,
 690    Failed { error: String },
 691}
 692
 693type AvailableLanguageId = usize;
 694
 695#[derive(Clone)]
 696struct AvailableLanguage {
 697    id: AvailableLanguageId,
 698    config: LanguageConfig,
 699    grammar: AvailableGrammar,
 700    lsp_adapters: Vec<Arc<dyn LspAdapter>>,
 701    loaded: bool,
 702}
 703
 704#[derive(Clone)]
 705enum AvailableGrammar {
 706    Native {
 707        grammar: tree_sitter::Language,
 708        asset_dir: &'static str,
 709        get_queries: fn(&str) -> LanguageQueries,
 710    },
 711    Wasm {
 712        path: Arc<Path>,
 713        get_queries: fn(&Path) -> LanguageQueries,
 714    },
 715}
 716
 717pub struct LanguageRegistry {
 718    state: RwLock<LanguageRegistryState>,
 719    language_server_download_dir: Option<Arc<Path>>,
 720    login_shell_env_loaded: Shared<Task<()>>,
 721    #[allow(clippy::type_complexity)]
 722    lsp_binary_paths: Mutex<
 723        HashMap<LanguageServerName, Shared<Task<Result<LanguageServerBinary, Arc<anyhow::Error>>>>>,
 724    >,
 725    executor: Option<BackgroundExecutor>,
 726    lsp_binary_status_tx: LspBinaryStatusSender,
 727}
 728
 729struct LanguageRegistryState {
 730    next_language_server_id: usize,
 731    languages: Vec<Arc<Language>>,
 732    available_languages: Vec<AvailableLanguage>,
 733    next_available_language_id: AvailableLanguageId,
 734    loading_languages: HashMap<AvailableLanguageId, Vec<oneshot::Sender<Result<Arc<Language>>>>>,
 735    subscription: (watch::Sender<()>, watch::Receiver<()>),
 736    theme: Option<Arc<Theme>>,
 737    version: usize,
 738    reload_count: usize,
 739}
 740
 741pub struct PendingLanguageServer {
 742    pub server_id: LanguageServerId,
 743    pub task: Task<Result<lsp::LanguageServer>>,
 744    pub container_dir: Option<Arc<Path>>,
 745}
 746
 747impl LanguageRegistry {
 748    pub fn new(login_shell_env_loaded: Task<()>) -> Self {
 749        Self {
 750            state: RwLock::new(LanguageRegistryState {
 751                next_language_server_id: 0,
 752                languages: vec![PLAIN_TEXT.clone()],
 753                available_languages: Default::default(),
 754                next_available_language_id: 0,
 755                loading_languages: Default::default(),
 756                subscription: watch::channel(),
 757                theme: Default::default(),
 758                version: 0,
 759                reload_count: 0,
 760            }),
 761            language_server_download_dir: None,
 762            login_shell_env_loaded: login_shell_env_loaded.shared(),
 763            lsp_binary_paths: Default::default(),
 764            executor: None,
 765            lsp_binary_status_tx: Default::default(),
 766        }
 767    }
 768
 769    #[cfg(any(test, feature = "test-support"))]
 770    pub fn test() -> Self {
 771        Self::new(Task::ready(()))
 772    }
 773
 774    pub fn set_executor(&mut self, executor: BackgroundExecutor) {
 775        self.executor = Some(executor);
 776    }
 777
 778    /// Clear out all of the loaded languages and reload them from scratch.
 779    pub fn reload(&self) {
 780        self.state.write().reload();
 781    }
 782
 783    pub fn register(
 784        &self,
 785        asset_dir: &'static str,
 786        config: LanguageConfig,
 787        grammar: tree_sitter::Language,
 788        lsp_adapters: Vec<Arc<dyn LspAdapter>>,
 789        get_queries: fn(&str) -> LanguageQueries,
 790    ) {
 791        let state = &mut *self.state.write();
 792        state.available_languages.push(AvailableLanguage {
 793            id: post_inc(&mut state.next_available_language_id),
 794            config,
 795            grammar: AvailableGrammar::Native {
 796                grammar,
 797                get_queries,
 798                asset_dir,
 799            },
 800            lsp_adapters,
 801            loaded: false,
 802        });
 803    }
 804
 805    pub fn register_wasm(
 806        &self,
 807        path: Arc<Path>,
 808        config: LanguageConfig,
 809        get_queries: fn(&Path) -> LanguageQueries,
 810    ) {
 811        let state = &mut *self.state.write();
 812        state.available_languages.push(AvailableLanguage {
 813            id: post_inc(&mut state.next_available_language_id),
 814            config,
 815            grammar: AvailableGrammar::Wasm { path, get_queries },
 816            lsp_adapters: Vec::new(),
 817            loaded: false,
 818        });
 819    }
 820
 821    pub fn language_names(&self) -> Vec<String> {
 822        let state = self.state.read();
 823        let mut result = state
 824            .available_languages
 825            .iter()
 826            .filter_map(|l| l.loaded.not().then_some(l.config.name.to_string()))
 827            .chain(state.languages.iter().map(|l| l.config.name.to_string()))
 828            .collect::<Vec<_>>();
 829        result.sort_unstable_by_key(|language_name| language_name.to_lowercase());
 830        result
 831    }
 832
 833    pub fn add(&self, language: Arc<Language>) {
 834        self.state.write().add(language);
 835    }
 836
 837    pub fn subscribe(&self) -> watch::Receiver<()> {
 838        self.state.read().subscription.1.clone()
 839    }
 840
 841    /// The number of times that the registry has been changed,
 842    /// by adding languages or reloading.
 843    pub fn version(&self) -> usize {
 844        self.state.read().version
 845    }
 846
 847    /// The number of times that the registry has been reloaded.
 848    pub fn reload_count(&self) -> usize {
 849        self.state.read().reload_count
 850    }
 851
 852    pub fn set_theme(&self, theme: Arc<Theme>) {
 853        let mut state = self.state.write();
 854        state.theme = Some(theme.clone());
 855        for language in &state.languages {
 856            language.set_theme(theme.syntax());
 857        }
 858    }
 859
 860    pub fn set_language_server_download_dir(&mut self, path: impl Into<Arc<Path>>) {
 861        self.language_server_download_dir = Some(path.into());
 862    }
 863
 864    pub fn language_for_name(
 865        self: &Arc<Self>,
 866        name: &str,
 867    ) -> UnwrapFuture<oneshot::Receiver<Result<Arc<Language>>>> {
 868        let name = UniCase::new(name);
 869        self.get_or_load_language(|config| UniCase::new(config.name.as_ref()) == name)
 870    }
 871
 872    pub fn language_for_name_or_extension(
 873        self: &Arc<Self>,
 874        string: &str,
 875    ) -> UnwrapFuture<oneshot::Receiver<Result<Arc<Language>>>> {
 876        let string = UniCase::new(string);
 877        self.get_or_load_language(|config| {
 878            UniCase::new(config.name.as_ref()) == string
 879                || config
 880                    .path_suffixes
 881                    .iter()
 882                    .any(|suffix| UniCase::new(suffix) == string)
 883        })
 884    }
 885
 886    pub fn language_for_file(
 887        self: &Arc<Self>,
 888        path: impl AsRef<Path>,
 889        content: Option<&Rope>,
 890    ) -> UnwrapFuture<oneshot::Receiver<Result<Arc<Language>>>> {
 891        let path = path.as_ref();
 892        let filename = path.file_name().and_then(|name| name.to_str());
 893        let extension = path.extension_or_hidden_file_name();
 894        let path_suffixes = [extension, filename];
 895        self.get_or_load_language(|config| {
 896            let path_matches = config
 897                .path_suffixes
 898                .iter()
 899                .any(|suffix| path_suffixes.contains(&Some(suffix.as_str())));
 900            let content_matches = content.zip(config.first_line_pattern.as_ref()).map_or(
 901                false,
 902                |(content, pattern)| {
 903                    let end = content.clip_point(Point::new(0, 256), Bias::Left);
 904                    let end = content.point_to_offset(end);
 905                    let text = content.chunks_in_range(0..end).collect::<String>();
 906                    pattern.is_match(&text)
 907                },
 908            );
 909            path_matches || content_matches
 910        })
 911    }
 912
 913    fn get_or_load_language(
 914        self: &Arc<Self>,
 915        callback: impl Fn(&LanguageConfig) -> bool,
 916    ) -> UnwrapFuture<oneshot::Receiver<Result<Arc<Language>>>> {
 917        let (tx, rx) = oneshot::channel();
 918
 919        let mut state = self.state.write();
 920        if let Some(language) = state
 921            .languages
 922            .iter()
 923            .find(|language| callback(&language.config))
 924        {
 925            let _ = tx.send(Ok(language.clone()));
 926        } else if let Some(executor) = self.executor.clone() {
 927            if let Some(language) = state
 928                .available_languages
 929                .iter()
 930                .find(|l| !l.loaded && callback(&l.config))
 931                .cloned()
 932            {
 933                let txs = state
 934                    .loading_languages
 935                    .entry(language.id)
 936                    .or_insert_with(|| {
 937                        let this = self.clone();
 938                        executor
 939                            .spawn(async move {
 940                                let id = language.id;
 941                                let name = language.config.name.clone();
 942                                let language = async {
 943                                    let (grammar, queries) = match language.grammar {
 944                                        AvailableGrammar::Native {
 945                                            grammar,
 946                                            asset_dir,
 947                                            get_queries,
 948                                        } => (grammar, (get_queries)(asset_dir)),
 949                                        AvailableGrammar::Wasm { path, get_queries } => {
 950                                            let grammar_name =
 951                                                &language.config.grammar_name.as_ref().ok_or_else(
 952                                                    || anyhow!("missing grammar name"),
 953                                                )?;
 954                                            let mut wasm_path = path.join(grammar_name.as_ref());
 955                                            wasm_path.set_extension("wasm");
 956                                            let wasm_bytes = std::fs::read(&wasm_path)?;
 957                                            let grammar = PARSER.with(|parser| {
 958                                                let mut parser = parser.borrow_mut();
 959                                                let mut store = parser.take_wasm_store().unwrap();
 960                                                let grammar =
 961                                                    store.load_language(&grammar_name, &wasm_bytes);
 962                                                parser.set_wasm_store(store).unwrap();
 963                                                grammar
 964                                            })?;
 965                                            (grammar, get_queries(path.as_ref()))
 966                                        }
 967                                    };
 968                                    Language::new(language.config, Some(grammar))
 969                                        .with_lsp_adapters(language.lsp_adapters)
 970                                        .await
 971                                        .with_queries(queries)
 972                                }
 973                                .await;
 974
 975                                match language {
 976                                    Ok(language) => {
 977                                        let language = Arc::new(language);
 978                                        let mut state = this.state.write();
 979
 980                                        state.add(language.clone());
 981                                        state.mark_language_loaded(id);
 982                                        if let Some(mut txs) = state.loading_languages.remove(&id) {
 983                                            for tx in txs.drain(..) {
 984                                                let _ = tx.send(Ok(language.clone()));
 985                                            }
 986                                        }
 987                                    }
 988                                    Err(e) => {
 989                                        log::error!("failed to load language {name}:\n{:?}", e);
 990                                        let mut state = this.state.write();
 991                                        state.mark_language_loaded(id);
 992                                        if let Some(mut txs) = state.loading_languages.remove(&id) {
 993                                            for tx in txs.drain(..) {
 994                                                let _ = tx.send(Err(anyhow!(
 995                                                    "failed to load language {}: {}",
 996                                                    name,
 997                                                    e
 998                                                )));
 999                                            }
1000                                        }
1001                                    }
1002                                };
1003                            })
1004                            .detach();
1005
1006                        Vec::new()
1007                    });
1008                txs.push(tx);
1009            } else {
1010                let _ = tx.send(Err(anyhow!("language not found")));
1011            }
1012        } else {
1013            let _ = tx.send(Err(anyhow!("executor does not exist")));
1014        }
1015
1016        rx.unwrap()
1017    }
1018
1019    pub fn to_vec(&self) -> Vec<Arc<Language>> {
1020        self.state.read().languages.iter().cloned().collect()
1021    }
1022
1023    pub fn create_pending_language_server(
1024        self: &Arc<Self>,
1025        stderr_capture: Arc<Mutex<Option<String>>>,
1026        language: Arc<Language>,
1027        adapter: Arc<CachedLspAdapter>,
1028        root_path: Arc<Path>,
1029        delegate: Arc<dyn LspAdapterDelegate>,
1030        cx: &mut AppContext,
1031    ) -> Option<PendingLanguageServer> {
1032        let server_id = self.state.write().next_language_server_id();
1033        log::info!(
1034            "starting language server {:?}, path: {root_path:?}, id: {server_id}",
1035            adapter.name.0
1036        );
1037
1038        #[cfg(any(test, feature = "test-support"))]
1039        if language.fake_adapter.is_some() {
1040            let task = cx.spawn(|cx| async move {
1041                let (servers_tx, fake_adapter) = language.fake_adapter.as_ref().unwrap();
1042                let (server, mut fake_server) = lsp::FakeLanguageServer::new(
1043                    fake_adapter.name.to_string(),
1044                    fake_adapter.capabilities.clone(),
1045                    cx.clone(),
1046                );
1047
1048                if let Some(initializer) = &fake_adapter.initializer {
1049                    initializer(&mut fake_server);
1050                }
1051
1052                let servers_tx = servers_tx.clone();
1053                cx.background_executor()
1054                    .spawn(async move {
1055                        if fake_server
1056                            .try_receive_notification::<lsp::notification::Initialized>()
1057                            .await
1058                            .is_some()
1059                        {
1060                            servers_tx.unbounded_send(fake_server).ok();
1061                        }
1062                    })
1063                    .detach();
1064
1065                Ok(server)
1066            });
1067
1068            return Some(PendingLanguageServer {
1069                server_id,
1070                task,
1071                container_dir: None,
1072            });
1073        }
1074
1075        let download_dir = self
1076            .language_server_download_dir
1077            .clone()
1078            .ok_or_else(|| anyhow!("language server download directory has not been assigned before starting server"))
1079            .log_err()?;
1080        let this = self.clone();
1081        let language = language.clone();
1082        let container_dir: Arc<Path> = Arc::from(download_dir.join(adapter.name.0.as_ref()));
1083        let root_path = root_path.clone();
1084        let adapter = adapter.clone();
1085        let login_shell_env_loaded = self.login_shell_env_loaded.clone();
1086        let lsp_binary_statuses = self.lsp_binary_status_tx.clone();
1087
1088        let task = {
1089            let container_dir = container_dir.clone();
1090            cx.spawn(move |mut cx| async move {
1091                login_shell_env_loaded.await;
1092
1093                let entry = this
1094                    .lsp_binary_paths
1095                    .lock()
1096                    .entry(adapter.name.clone())
1097                    .or_insert_with(|| {
1098                        let adapter = adapter.clone();
1099                        let language = language.clone();
1100                        let delegate = delegate.clone();
1101                        cx.spawn(|cx| {
1102                            get_binary(
1103                                adapter,
1104                                language,
1105                                delegate,
1106                                container_dir,
1107                                lsp_binary_statuses,
1108                                cx,
1109                            )
1110                            .map_err(Arc::new)
1111                        })
1112                        .shared()
1113                    })
1114                    .clone();
1115
1116                let binary = match entry.await {
1117                    Ok(binary) => binary,
1118                    Err(err) => anyhow::bail!("{err}"),
1119                };
1120
1121                if let Some(task) = adapter.will_start_server(&delegate, &mut cx) {
1122                    task.await?;
1123                }
1124
1125                lsp::LanguageServer::new(
1126                    stderr_capture,
1127                    server_id,
1128                    binary,
1129                    &root_path,
1130                    adapter.code_action_kinds(),
1131                    cx,
1132                )
1133            })
1134        };
1135
1136        Some(PendingLanguageServer {
1137            server_id,
1138            task,
1139            container_dir: Some(container_dir),
1140        })
1141    }
1142
1143    pub fn language_server_binary_statuses(
1144        &self,
1145    ) -> mpsc::UnboundedReceiver<(Arc<Language>, LanguageServerBinaryStatus)> {
1146        self.lsp_binary_status_tx.subscribe()
1147    }
1148
1149    pub fn delete_server_container(
1150        &self,
1151        adapter: Arc<CachedLspAdapter>,
1152        cx: &mut AppContext,
1153    ) -> Task<()> {
1154        log::info!("deleting server container");
1155
1156        let mut lock = self.lsp_binary_paths.lock();
1157        lock.remove(&adapter.name);
1158
1159        let download_dir = self
1160            .language_server_download_dir
1161            .clone()
1162            .expect("language server download directory has not been assigned before deleting server container");
1163
1164        cx.spawn(|_| async move {
1165            let container_dir = download_dir.join(adapter.name.0.as_ref());
1166            smol::fs::remove_dir_all(container_dir)
1167                .await
1168                .context("server container removal")
1169                .log_err();
1170        })
1171    }
1172
1173    pub fn next_language_server_id(&self) -> LanguageServerId {
1174        self.state.write().next_language_server_id()
1175    }
1176}
1177
1178impl LanguageRegistryState {
1179    fn next_language_server_id(&mut self) -> LanguageServerId {
1180        LanguageServerId(post_inc(&mut self.next_language_server_id))
1181    }
1182
1183    fn add(&mut self, language: Arc<Language>) {
1184        if let Some(theme) = self.theme.as_ref() {
1185            language.set_theme(theme.syntax());
1186        }
1187        self.languages.push(language);
1188        self.version += 1;
1189        *self.subscription.0.borrow_mut() = ();
1190    }
1191
1192    fn reload(&mut self) {
1193        self.languages.clear();
1194        self.version += 1;
1195        self.reload_count += 1;
1196        for language in &mut self.available_languages {
1197            language.loaded = false;
1198        }
1199        *self.subscription.0.borrow_mut() = ();
1200    }
1201
1202    /// Mark the given language a having been loaded, so that the
1203    /// language registry won't try to load it again.
1204    fn mark_language_loaded(&mut self, id: AvailableLanguageId) {
1205        for language in &mut self.available_languages {
1206            if language.id == id {
1207                language.loaded = true;
1208                break;
1209            }
1210        }
1211    }
1212}
1213
1214#[cfg(any(test, feature = "test-support"))]
1215impl Default for LanguageRegistry {
1216    fn default() -> Self {
1217        Self::test()
1218    }
1219}
1220
1221async fn get_binary(
1222    adapter: Arc<CachedLspAdapter>,
1223    language: Arc<Language>,
1224    delegate: Arc<dyn LspAdapterDelegate>,
1225    container_dir: Arc<Path>,
1226    statuses: LspBinaryStatusSender,
1227    mut cx: AsyncAppContext,
1228) -> Result<LanguageServerBinary> {
1229    if !container_dir.exists() {
1230        smol::fs::create_dir_all(&container_dir)
1231            .await
1232            .context("failed to create container directory")?;
1233    }
1234
1235    if let Some(task) = adapter.will_fetch_server(&delegate, &mut cx) {
1236        task.await?;
1237    }
1238
1239    let binary = fetch_latest_binary(
1240        adapter.clone(),
1241        language.clone(),
1242        delegate.as_ref(),
1243        &container_dir,
1244        statuses.clone(),
1245    )
1246    .await;
1247
1248    if let Err(error) = binary.as_ref() {
1249        if let Some(binary) = adapter
1250            .cached_server_binary(container_dir.to_path_buf(), delegate.as_ref())
1251            .await
1252        {
1253            statuses.send(language.clone(), LanguageServerBinaryStatus::Cached);
1254            return Ok(binary);
1255        } else {
1256            statuses.send(
1257                language.clone(),
1258                LanguageServerBinaryStatus::Failed {
1259                    error: format!("{:?}", error),
1260                },
1261            );
1262        }
1263    }
1264
1265    binary
1266}
1267
1268async fn fetch_latest_binary(
1269    adapter: Arc<CachedLspAdapter>,
1270    language: Arc<Language>,
1271    delegate: &dyn LspAdapterDelegate,
1272    container_dir: &Path,
1273    lsp_binary_statuses_tx: LspBinaryStatusSender,
1274) -> Result<LanguageServerBinary> {
1275    let container_dir: Arc<Path> = container_dir.into();
1276    lsp_binary_statuses_tx.send(
1277        language.clone(),
1278        LanguageServerBinaryStatus::CheckingForUpdate,
1279    );
1280
1281    let version_info = adapter.fetch_latest_server_version(delegate).await?;
1282    lsp_binary_statuses_tx.send(language.clone(), LanguageServerBinaryStatus::Downloading);
1283
1284    let binary = adapter
1285        .fetch_server_binary(version_info, container_dir.to_path_buf(), delegate)
1286        .await?;
1287    lsp_binary_statuses_tx.send(language.clone(), LanguageServerBinaryStatus::Downloaded);
1288
1289    Ok(binary)
1290}
1291
1292impl Language {
1293    pub fn new(config: LanguageConfig, ts_language: Option<tree_sitter::Language>) -> Self {
1294        Self {
1295            config,
1296            grammar: ts_language.map(|ts_language| {
1297                Arc::new(Grammar {
1298                    id: NEXT_GRAMMAR_ID.fetch_add(1, SeqCst),
1299                    highlights_query: None,
1300                    brackets_config: None,
1301                    outline_config: None,
1302                    embedding_config: None,
1303                    indents_config: None,
1304                    injection_config: None,
1305                    override_config: None,
1306                    error_query: Query::new(&ts_language, "(ERROR) @error").unwrap(),
1307                    ts_language,
1308                    highlight_map: Default::default(),
1309                })
1310            }),
1311            adapters: Vec::new(),
1312
1313            #[cfg(any(test, feature = "test-support"))]
1314            fake_adapter: None,
1315        }
1316    }
1317
1318    pub fn lsp_adapters(&self) -> &[Arc<CachedLspAdapter>] {
1319        &self.adapters
1320    }
1321
1322    pub fn id(&self) -> Option<usize> {
1323        self.grammar.as_ref().map(|g| g.id)
1324    }
1325
1326    pub fn with_queries(mut self, queries: LanguageQueries) -> Result<Self> {
1327        if let Some(query) = queries.highlights {
1328            self = self
1329                .with_highlights_query(query.as_ref())
1330                .context("Error loading highlights query")?;
1331        }
1332        if let Some(query) = queries.brackets {
1333            self = self
1334                .with_brackets_query(query.as_ref())
1335                .context("Error loading brackets query")?;
1336        }
1337        if let Some(query) = queries.indents {
1338            self = self
1339                .with_indents_query(query.as_ref())
1340                .context("Error loading indents query")?;
1341        }
1342        if let Some(query) = queries.outline {
1343            self = self
1344                .with_outline_query(query.as_ref())
1345                .context("Error loading outline query")?;
1346        }
1347        if let Some(query) = queries.embedding {
1348            self = self
1349                .with_embedding_query(query.as_ref())
1350                .context("Error loading embedding query")?;
1351        }
1352        if let Some(query) = queries.injections {
1353            self = self
1354                .with_injection_query(query.as_ref())
1355                .context("Error loading injection query")?;
1356        }
1357        if let Some(query) = queries.overrides {
1358            self = self
1359                .with_override_query(query.as_ref())
1360                .context("Error loading override query")?;
1361        }
1362        Ok(self)
1363    }
1364
1365    pub fn with_highlights_query(mut self, source: &str) -> Result<Self> {
1366        let grammar = self.grammar_mut();
1367        grammar.highlights_query = Some(Query::new(&grammar.ts_language, source)?);
1368        Ok(self)
1369    }
1370
1371    pub fn with_outline_query(mut self, source: &str) -> Result<Self> {
1372        let grammar = self.grammar_mut();
1373        let query = Query::new(&grammar.ts_language, source)?;
1374        let mut item_capture_ix = None;
1375        let mut name_capture_ix = None;
1376        let mut context_capture_ix = None;
1377        let mut extra_context_capture_ix = None;
1378        get_capture_indices(
1379            &query,
1380            &mut [
1381                ("item", &mut item_capture_ix),
1382                ("name", &mut name_capture_ix),
1383                ("context", &mut context_capture_ix),
1384                ("context.extra", &mut extra_context_capture_ix),
1385            ],
1386        );
1387        if let Some((item_capture_ix, name_capture_ix)) = item_capture_ix.zip(name_capture_ix) {
1388            grammar.outline_config = Some(OutlineConfig {
1389                query,
1390                item_capture_ix,
1391                name_capture_ix,
1392                context_capture_ix,
1393                extra_context_capture_ix,
1394            });
1395        }
1396        Ok(self)
1397    }
1398
1399    pub fn with_embedding_query(mut self, source: &str) -> Result<Self> {
1400        let grammar = self.grammar_mut();
1401        let query = Query::new(&grammar.ts_language, source)?;
1402        let mut item_capture_ix = None;
1403        let mut name_capture_ix = None;
1404        let mut context_capture_ix = None;
1405        let mut collapse_capture_ix = None;
1406        let mut keep_capture_ix = None;
1407        get_capture_indices(
1408            &query,
1409            &mut [
1410                ("item", &mut item_capture_ix),
1411                ("name", &mut name_capture_ix),
1412                ("context", &mut context_capture_ix),
1413                ("keep", &mut keep_capture_ix),
1414                ("collapse", &mut collapse_capture_ix),
1415            ],
1416        );
1417        if let Some(item_capture_ix) = item_capture_ix {
1418            grammar.embedding_config = Some(EmbeddingConfig {
1419                query,
1420                item_capture_ix,
1421                name_capture_ix,
1422                context_capture_ix,
1423                collapse_capture_ix,
1424                keep_capture_ix,
1425            });
1426        }
1427        Ok(self)
1428    }
1429
1430    pub fn with_brackets_query(mut self, source: &str) -> Result<Self> {
1431        let grammar = self.grammar_mut();
1432        let query = Query::new(&grammar.ts_language, source)?;
1433        let mut open_capture_ix = None;
1434        let mut close_capture_ix = None;
1435        get_capture_indices(
1436            &query,
1437            &mut [
1438                ("open", &mut open_capture_ix),
1439                ("close", &mut close_capture_ix),
1440            ],
1441        );
1442        if let Some((open_capture_ix, close_capture_ix)) = open_capture_ix.zip(close_capture_ix) {
1443            grammar.brackets_config = Some(BracketConfig {
1444                query,
1445                open_capture_ix,
1446                close_capture_ix,
1447            });
1448        }
1449        Ok(self)
1450    }
1451
1452    pub fn with_indents_query(mut self, source: &str) -> Result<Self> {
1453        let grammar = self.grammar_mut();
1454        let query = Query::new(&grammar.ts_language, source)?;
1455        let mut indent_capture_ix = None;
1456        let mut start_capture_ix = None;
1457        let mut end_capture_ix = None;
1458        let mut outdent_capture_ix = None;
1459        get_capture_indices(
1460            &query,
1461            &mut [
1462                ("indent", &mut indent_capture_ix),
1463                ("start", &mut start_capture_ix),
1464                ("end", &mut end_capture_ix),
1465                ("outdent", &mut outdent_capture_ix),
1466            ],
1467        );
1468        if let Some(indent_capture_ix) = indent_capture_ix {
1469            grammar.indents_config = Some(IndentConfig {
1470                query,
1471                indent_capture_ix,
1472                start_capture_ix,
1473                end_capture_ix,
1474                outdent_capture_ix,
1475            });
1476        }
1477        Ok(self)
1478    }
1479
1480    pub fn with_injection_query(mut self, source: &str) -> Result<Self> {
1481        let grammar = self.grammar_mut();
1482        let query = Query::new(&grammar.ts_language, source)?;
1483        let mut language_capture_ix = None;
1484        let mut content_capture_ix = None;
1485        get_capture_indices(
1486            &query,
1487            &mut [
1488                ("language", &mut language_capture_ix),
1489                ("content", &mut content_capture_ix),
1490            ],
1491        );
1492        let patterns = (0..query.pattern_count())
1493            .map(|ix| {
1494                let mut config = InjectionPatternConfig::default();
1495                for setting in query.property_settings(ix) {
1496                    match setting.key.as_ref() {
1497                        "language" => {
1498                            config.language = setting.value.clone();
1499                        }
1500                        "combined" => {
1501                            config.combined = true;
1502                        }
1503                        _ => {}
1504                    }
1505                }
1506                config
1507            })
1508            .collect();
1509        if let Some(content_capture_ix) = content_capture_ix {
1510            grammar.injection_config = Some(InjectionConfig {
1511                query,
1512                language_capture_ix,
1513                content_capture_ix,
1514                patterns,
1515            });
1516        }
1517        Ok(self)
1518    }
1519
1520    pub fn with_override_query(mut self, source: &str) -> anyhow::Result<Self> {
1521        let query = Query::new(&self.grammar_mut().ts_language, source)?;
1522
1523        let mut override_configs_by_id = HashMap::default();
1524        for (ix, name) in query.capture_names().iter().enumerate() {
1525            if !name.starts_with('_') {
1526                let value = self.config.overrides.remove(*name).unwrap_or_default();
1527                for server_name in &value.opt_into_language_servers {
1528                    if !self
1529                        .config
1530                        .scope_opt_in_language_servers
1531                        .contains(server_name)
1532                    {
1533                        util::debug_panic!("Server {server_name:?} has been opted-in by scope {name:?} but has not been marked as an opt-in server");
1534                    }
1535                }
1536
1537                override_configs_by_id.insert(ix as u32, (name.to_string(), value));
1538            }
1539        }
1540
1541        if !self.config.overrides.is_empty() {
1542            let keys = self.config.overrides.keys().collect::<Vec<_>>();
1543            Err(anyhow!(
1544                "language {:?} has overrides in config not in query: {keys:?}",
1545                self.config.name
1546            ))?;
1547        }
1548
1549        for disabled_scope_name in self
1550            .config
1551            .brackets
1552            .disabled_scopes_by_bracket_ix
1553            .iter()
1554            .flatten()
1555        {
1556            if !override_configs_by_id
1557                .values()
1558                .any(|(scope_name, _)| scope_name == disabled_scope_name)
1559            {
1560                Err(anyhow!(
1561                    "language {:?} has overrides in config not in query: {disabled_scope_name:?}",
1562                    self.config.name
1563                ))?;
1564            }
1565        }
1566
1567        for (name, override_config) in override_configs_by_id.values_mut() {
1568            override_config.disabled_bracket_ixs = self
1569                .config
1570                .brackets
1571                .disabled_scopes_by_bracket_ix
1572                .iter()
1573                .enumerate()
1574                .filter_map(|(ix, disabled_scope_names)| {
1575                    if disabled_scope_names.contains(name) {
1576                        Some(ix as u16)
1577                    } else {
1578                        None
1579                    }
1580                })
1581                .collect();
1582        }
1583
1584        self.config.brackets.disabled_scopes_by_bracket_ix.clear();
1585        self.grammar_mut().override_config = Some(OverrideConfig {
1586            query,
1587            values: override_configs_by_id,
1588        });
1589        Ok(self)
1590    }
1591
1592    fn grammar_mut(&mut self) -> &mut Grammar {
1593        Arc::get_mut(self.grammar.as_mut().unwrap()).unwrap()
1594    }
1595
1596    pub async fn with_lsp_adapters(mut self, lsp_adapters: Vec<Arc<dyn LspAdapter>>) -> Self {
1597        for adapter in lsp_adapters {
1598            self.adapters.push(CachedLspAdapter::new(adapter).await);
1599        }
1600        self
1601    }
1602
1603    #[cfg(any(test, feature = "test-support"))]
1604    pub async fn set_fake_lsp_adapter(
1605        &mut self,
1606        fake_lsp_adapter: Arc<FakeLspAdapter>,
1607    ) -> mpsc::UnboundedReceiver<lsp::FakeLanguageServer> {
1608        let (servers_tx, servers_rx) = mpsc::unbounded();
1609        self.fake_adapter = Some((servers_tx, fake_lsp_adapter.clone()));
1610        let adapter = CachedLspAdapter::new(Arc::new(fake_lsp_adapter)).await;
1611        self.adapters = vec![adapter];
1612        servers_rx
1613    }
1614
1615    pub fn name(&self) -> Arc<str> {
1616        self.config.name.clone()
1617    }
1618
1619    pub async fn disk_based_diagnostic_sources(&self) -> &[String] {
1620        match self.adapters.first().as_ref() {
1621            Some(adapter) => &adapter.disk_based_diagnostic_sources,
1622            None => &[],
1623        }
1624    }
1625
1626    pub async fn disk_based_diagnostics_progress_token(&self) -> Option<&str> {
1627        for adapter in &self.adapters {
1628            let token = adapter.disk_based_diagnostics_progress_token.as_deref();
1629            if token.is_some() {
1630                return token;
1631            }
1632        }
1633
1634        None
1635    }
1636
1637    pub async fn process_completion(self: &Arc<Self>, completion: &mut lsp::CompletionItem) {
1638        for adapter in &self.adapters {
1639            adapter.process_completion(completion).await;
1640        }
1641    }
1642
1643    pub async fn label_for_completion(
1644        self: &Arc<Self>,
1645        completion: &lsp::CompletionItem,
1646    ) -> Option<CodeLabel> {
1647        self.adapters
1648            .first()
1649            .as_ref()?
1650            .label_for_completion(completion, self)
1651            .await
1652    }
1653
1654    pub async fn label_for_symbol(
1655        self: &Arc<Self>,
1656        name: &str,
1657        kind: lsp::SymbolKind,
1658    ) -> Option<CodeLabel> {
1659        self.adapters
1660            .first()
1661            .as_ref()?
1662            .label_for_symbol(name, kind, self)
1663            .await
1664    }
1665
1666    pub fn highlight_text<'a>(
1667        self: &'a Arc<Self>,
1668        text: &'a Rope,
1669        range: Range<usize>,
1670    ) -> Vec<(Range<usize>, HighlightId)> {
1671        let mut result = Vec::new();
1672        if let Some(grammar) = &self.grammar {
1673            let tree = grammar.parse_text(text, None);
1674            let captures =
1675                SyntaxSnapshot::single_tree_captures(range.clone(), text, &tree, self, |grammar| {
1676                    grammar.highlights_query.as_ref()
1677                });
1678            let highlight_maps = vec![grammar.highlight_map()];
1679            let mut offset = 0;
1680            for chunk in BufferChunks::new(text, range, Some((captures, highlight_maps)), vec![]) {
1681                let end_offset = offset + chunk.text.len();
1682                if let Some(highlight_id) = chunk.syntax_highlight_id {
1683                    if !highlight_id.is_default() {
1684                        result.push((offset..end_offset, highlight_id));
1685                    }
1686                }
1687                offset = end_offset;
1688            }
1689        }
1690        result
1691    }
1692
1693    pub fn path_suffixes(&self) -> &[String] {
1694        &self.config.path_suffixes
1695    }
1696
1697    pub fn should_autoclose_before(&self, c: char) -> bool {
1698        c.is_whitespace() || self.config.autoclose_before.contains(c)
1699    }
1700
1701    pub fn set_theme(&self, theme: &SyntaxTheme) {
1702        if let Some(grammar) = self.grammar.as_ref() {
1703            if let Some(highlights_query) = &grammar.highlights_query {
1704                *grammar.highlight_map.lock() =
1705                    HighlightMap::new(highlights_query.capture_names(), theme);
1706            }
1707        }
1708    }
1709
1710    pub fn grammar(&self) -> Option<&Arc<Grammar>> {
1711        self.grammar.as_ref()
1712    }
1713
1714    pub fn default_scope(self: &Arc<Self>) -> LanguageScope {
1715        LanguageScope {
1716            language: self.clone(),
1717            override_id: None,
1718        }
1719    }
1720
1721    pub fn prettier_parser_name(&self) -> Option<&str> {
1722        self.config.prettier_parser_name.as_deref()
1723    }
1724}
1725
1726impl LanguageScope {
1727    pub fn collapsed_placeholder(&self) -> &str {
1728        self.language.config.collapsed_placeholder.as_ref()
1729    }
1730
1731    /// Returns line prefix that is inserted in e.g. line continuations or
1732    /// in `toggle comments` action.
1733    pub fn line_comment_prefixes(&self) -> Option<&Vec<Arc<str>>> {
1734        Override::as_option(
1735            self.config_override().map(|o| &o.line_comments),
1736            Some(&self.language.config.line_comments),
1737        )
1738    }
1739
1740    pub fn block_comment_delimiters(&self) -> Option<(&Arc<str>, &Arc<str>)> {
1741        Override::as_option(
1742            self.config_override().map(|o| &o.block_comment),
1743            self.language.config.block_comment.as_ref(),
1744        )
1745        .map(|e| (&e.0, &e.1))
1746    }
1747
1748    /// Returns a list of language-specific word characters.
1749    ///
1750    /// By default, Zed treats alphanumeric characters (and '_') as word characters for
1751    /// the purpose of actions like 'move to next word end` or whole-word search.
1752    /// It additionally accounts for language's additional word characters.
1753    pub fn word_characters(&self) -> Option<&HashSet<char>> {
1754        Override::as_option(
1755            self.config_override().map(|o| &o.word_characters),
1756            Some(&self.language.config.word_characters),
1757        )
1758    }
1759
1760    /// Returns a list of bracket pairs for a given language with an additional
1761    /// piece of information about whether the particular bracket pair is currently active for a given language.
1762    pub fn brackets(&self) -> impl Iterator<Item = (&BracketPair, bool)> {
1763        let mut disabled_ids = self
1764            .config_override()
1765            .map_or(&[] as _, |o| o.disabled_bracket_ixs.as_slice());
1766        self.language
1767            .config
1768            .brackets
1769            .pairs
1770            .iter()
1771            .enumerate()
1772            .map(move |(ix, bracket)| {
1773                let mut is_enabled = true;
1774                if let Some(next_disabled_ix) = disabled_ids.first() {
1775                    if ix == *next_disabled_ix as usize {
1776                        disabled_ids = &disabled_ids[1..];
1777                        is_enabled = false;
1778                    }
1779                }
1780                (bracket, is_enabled)
1781            })
1782    }
1783
1784    pub fn should_autoclose_before(&self, c: char) -> bool {
1785        c.is_whitespace() || self.language.config.autoclose_before.contains(c)
1786    }
1787
1788    pub fn language_allowed(&self, name: &LanguageServerName) -> bool {
1789        let config = &self.language.config;
1790        let opt_in_servers = &config.scope_opt_in_language_servers;
1791        if opt_in_servers.iter().any(|o| *o == *name.0) {
1792            if let Some(over) = self.config_override() {
1793                over.opt_into_language_servers.iter().any(|o| *o == *name.0)
1794            } else {
1795                false
1796            }
1797        } else {
1798            true
1799        }
1800    }
1801
1802    fn config_override(&self) -> Option<&LanguageConfigOverride> {
1803        let id = self.override_id?;
1804        let grammar = self.language.grammar.as_ref()?;
1805        let override_config = grammar.override_config.as_ref()?;
1806        override_config.values.get(&id).map(|e| &e.1)
1807    }
1808}
1809
1810impl Hash for Language {
1811    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1812        self.id().hash(state)
1813    }
1814}
1815
1816impl PartialEq for Language {
1817    fn eq(&self, other: &Self) -> bool {
1818        self.id().eq(&other.id())
1819    }
1820}
1821
1822impl Eq for Language {}
1823
1824impl Debug for Language {
1825    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1826        f.debug_struct("Language")
1827            .field("name", &self.config.name)
1828            .finish()
1829    }
1830}
1831
1832impl Grammar {
1833    pub fn id(&self) -> usize {
1834        self.id
1835    }
1836
1837    fn parse_text(&self, text: &Rope, old_tree: Option<Tree>) -> Tree {
1838        PARSER.with(|parser| {
1839            let mut parser = parser.borrow_mut();
1840            parser
1841                .set_language(&self.ts_language)
1842                .expect("incompatible grammar");
1843            let mut chunks = text.chunks_in_range(0..text.len());
1844            parser
1845                .parse_with(
1846                    &mut move |offset, _| {
1847                        chunks.seek(offset);
1848                        chunks.next().unwrap_or("").as_bytes()
1849                    },
1850                    old_tree.as_ref(),
1851                )
1852                .unwrap()
1853        })
1854    }
1855
1856    pub fn highlight_map(&self) -> HighlightMap {
1857        self.highlight_map.lock().clone()
1858    }
1859
1860    pub fn highlight_id_for_name(&self, name: &str) -> Option<HighlightId> {
1861        let capture_id = self
1862            .highlights_query
1863            .as_ref()?
1864            .capture_index_for_name(name)?;
1865        Some(self.highlight_map.lock().get(capture_id))
1866    }
1867}
1868
1869impl CodeLabel {
1870    pub fn plain(text: String, filter_text: Option<&str>) -> Self {
1871        let mut result = Self {
1872            runs: Vec::new(),
1873            filter_range: 0..text.len(),
1874            text,
1875        };
1876        if let Some(filter_text) = filter_text {
1877            if let Some(ix) = result.text.find(filter_text) {
1878                result.filter_range = ix..ix + filter_text.len();
1879            }
1880        }
1881        result
1882    }
1883}
1884
1885#[cfg(any(test, feature = "test-support"))]
1886impl Default for FakeLspAdapter {
1887    fn default() -> Self {
1888        Self {
1889            name: "the-fake-language-server",
1890            capabilities: lsp::LanguageServer::full_capabilities(),
1891            initializer: None,
1892            disk_based_diagnostics_progress_token: None,
1893            initialization_options: None,
1894            disk_based_diagnostics_sources: Vec::new(),
1895            prettier_plugins: Vec::new(),
1896        }
1897    }
1898}
1899
1900#[cfg(any(test, feature = "test-support"))]
1901#[async_trait]
1902impl LspAdapter for Arc<FakeLspAdapter> {
1903    fn name(&self) -> LanguageServerName {
1904        LanguageServerName(self.name.into())
1905    }
1906
1907    fn short_name(&self) -> &'static str {
1908        "FakeLspAdapter"
1909    }
1910
1911    async fn fetch_latest_server_version(
1912        &self,
1913        _: &dyn LspAdapterDelegate,
1914    ) -> Result<Box<dyn 'static + Send + Any>> {
1915        unreachable!();
1916    }
1917
1918    async fn fetch_server_binary(
1919        &self,
1920        _: Box<dyn 'static + Send + Any>,
1921        _: PathBuf,
1922        _: &dyn LspAdapterDelegate,
1923    ) -> Result<LanguageServerBinary> {
1924        unreachable!();
1925    }
1926
1927    async fn cached_server_binary(
1928        &self,
1929        _: PathBuf,
1930        _: &dyn LspAdapterDelegate,
1931    ) -> Option<LanguageServerBinary> {
1932        unreachable!();
1933    }
1934
1935    async fn installation_test_binary(&self, _: PathBuf) -> Option<LanguageServerBinary> {
1936        unreachable!();
1937    }
1938
1939    fn process_diagnostics(&self, _: &mut lsp::PublishDiagnosticsParams) {}
1940
1941    fn disk_based_diagnostic_sources(&self) -> Vec<String> {
1942        self.disk_based_diagnostics_sources.clone()
1943    }
1944
1945    fn disk_based_diagnostics_progress_token(&self) -> Option<String> {
1946        self.disk_based_diagnostics_progress_token.clone()
1947    }
1948
1949    fn initialization_options(&self) -> Option<Value> {
1950        self.initialization_options.clone()
1951    }
1952
1953    fn prettier_plugins(&self) -> &[&'static str] {
1954        &self.prettier_plugins
1955    }
1956}
1957
1958fn get_capture_indices(query: &Query, captures: &mut [(&str, &mut Option<u32>)]) {
1959    for (ix, name) in query.capture_names().iter().enumerate() {
1960        for (capture_name, index) in captures.iter_mut() {
1961            if capture_name == name {
1962                **index = Some(ix as u32);
1963                break;
1964            }
1965        }
1966    }
1967}
1968
1969pub fn point_to_lsp(point: PointUtf16) -> lsp::Position {
1970    lsp::Position::new(point.row, point.column)
1971}
1972
1973pub fn point_from_lsp(point: lsp::Position) -> Unclipped<PointUtf16> {
1974    Unclipped(PointUtf16::new(point.line, point.character))
1975}
1976
1977pub fn range_to_lsp(range: Range<PointUtf16>) -> lsp::Range {
1978    lsp::Range {
1979        start: point_to_lsp(range.start),
1980        end: point_to_lsp(range.end),
1981    }
1982}
1983
1984pub fn range_from_lsp(range: lsp::Range) -> Range<Unclipped<PointUtf16>> {
1985    let mut start = point_from_lsp(range.start);
1986    let mut end = point_from_lsp(range.end);
1987    if start > end {
1988        mem::swap(&mut start, &mut end);
1989    }
1990    start..end
1991}
1992
1993#[cfg(test)]
1994mod tests {
1995    use super::*;
1996    use gpui::TestAppContext;
1997
1998    #[gpui::test(iterations = 10)]
1999    async fn test_first_line_pattern(cx: &mut TestAppContext) {
2000        let mut languages = LanguageRegistry::test();
2001
2002        languages.set_executor(cx.executor());
2003        let languages = Arc::new(languages);
2004        languages.register(
2005            "/javascript",
2006            LanguageConfig {
2007                name: "JavaScript".into(),
2008                path_suffixes: vec!["js".into()],
2009                first_line_pattern: Some(Regex::new(r"\bnode\b").unwrap()),
2010                ..Default::default()
2011            },
2012            tree_sitter_typescript::language_tsx(),
2013            vec![],
2014            |_| Default::default(),
2015        );
2016
2017        languages
2018            .language_for_file("the/script", None)
2019            .await
2020            .unwrap_err();
2021        languages
2022            .language_for_file("the/script", Some(&"nothing".into()))
2023            .await
2024            .unwrap_err();
2025        assert_eq!(
2026            languages
2027                .language_for_file("the/script", Some(&"#!/bin/env node".into()))
2028                .await
2029                .unwrap()
2030                .name()
2031                .as_ref(),
2032            "JavaScript"
2033        );
2034    }
2035
2036    #[gpui::test(iterations = 10)]
2037    async fn test_language_loading(cx: &mut TestAppContext) {
2038        let mut languages = LanguageRegistry::test();
2039        languages.set_executor(cx.executor());
2040        let languages = Arc::new(languages);
2041        languages.register(
2042            "/JSON",
2043            LanguageConfig {
2044                name: "JSON".into(),
2045                path_suffixes: vec!["json".into()],
2046                ..Default::default()
2047            },
2048            tree_sitter_json::language(),
2049            vec![],
2050            |_| Default::default(),
2051        );
2052        languages.register(
2053            "/rust",
2054            LanguageConfig {
2055                name: "Rust".into(),
2056                path_suffixes: vec!["rs".into()],
2057                ..Default::default()
2058            },
2059            tree_sitter_rust::language(),
2060            vec![],
2061            |_| Default::default(),
2062        );
2063        assert_eq!(
2064            languages.language_names(),
2065            &[
2066                "JSON".to_string(),
2067                "Plain Text".to_string(),
2068                "Rust".to_string(),
2069            ]
2070        );
2071
2072        let rust1 = languages.language_for_name("Rust");
2073        let rust2 = languages.language_for_name("Rust");
2074
2075        // Ensure language is still listed even if it's being loaded.
2076        assert_eq!(
2077            languages.language_names(),
2078            &[
2079                "JSON".to_string(),
2080                "Plain Text".to_string(),
2081                "Rust".to_string(),
2082            ]
2083        );
2084
2085        let (rust1, rust2) = futures::join!(rust1, rust2);
2086        assert!(Arc::ptr_eq(&rust1.unwrap(), &rust2.unwrap()));
2087
2088        // Ensure language is still listed even after loading it.
2089        assert_eq!(
2090            languages.language_names(),
2091            &[
2092                "JSON".to_string(),
2093                "Plain Text".to_string(),
2094                "Rust".to_string(),
2095            ]
2096        );
2097
2098        // Loading an unknown language returns an error.
2099        assert!(languages.language_for_name("Unknown").await.is_err());
2100    }
2101}