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