language.rs

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