language.rs

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