language.rs

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