lsp_store.rs

   1use crate::{
   2    buffer_store::{BufferStore, BufferStoreEvent},
   3    deserialize_code_actions,
   4    environment::ProjectEnvironment,
   5    lsp_command::{self, *},
   6    lsp_ext_command,
   7    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   8    project_settings::{LspSettings, ProjectSettings},
   9    relativize_path, resolve_path,
  10    worktree_store::{WorktreeStore, WorktreeStoreEvent},
  11    yarn::YarnPathStore,
  12    CodeAction, Completion, CoreCompletion, Hover, InlayHint, Item as _, ProjectPath,
  13    ProjectTransaction, ResolveState, Symbol,
  14};
  15use anyhow::{anyhow, Context as _, Result};
  16use async_trait::async_trait;
  17use client::{proto, TypedEnvelope};
  18use collections::{btree_map, BTreeMap, HashMap, HashSet};
  19use futures::{
  20    future::{join_all, Shared},
  21    select,
  22    stream::FuturesUnordered,
  23    AsyncWriteExt, Future, FutureExt, StreamExt,
  24};
  25use globset::{Glob, GlobSet, GlobSetBuilder};
  26use gpui::{
  27    AppContext, AsyncAppContext, Context, Entity, EventEmitter, Model, ModelContext, PromptLevel,
  28    Task, WeakModel,
  29};
  30use http_client::{BlockedHttpClient, HttpClient};
  31use language::{
  32    language_settings::{
  33        all_language_settings, language_settings, AllLanguageSettings, FormatOnSave, Formatter,
  34        LanguageSettings, SelectedFormatter,
  35    },
  36    markdown, point_to_lsp, prepare_completion_documentation,
  37    proto::{deserialize_anchor, deserialize_version, serialize_anchor, serialize_version},
  38    range_from_lsp, Bias, Buffer, BufferSnapshot, CachedLspAdapter, CodeLabel, Diagnostic,
  39    DiagnosticEntry, DiagnosticSet, Diff, Documentation, File as _, Language, LanguageConfig,
  40    LanguageMatcher, LanguageName, LanguageRegistry, LanguageServerName, LocalFile, LspAdapter,
  41    LspAdapterDelegate, Patch, PendingLanguageServer, PointUtf16, TextBufferSnapshot, ToOffset,
  42    ToPointUtf16, Transaction, Unclipped,
  43};
  44use lsp::{
  45    CodeActionKind, CompletionContext, DiagnosticSeverity, DiagnosticTag,
  46    DidChangeWatchedFilesRegistrationOptions, Edit, FileSystemWatcher, InsertTextFormat,
  47    LanguageServer, LanguageServerBinary, LanguageServerId, LspRequestFuture, MessageActionItem,
  48    MessageType, OneOf, ServerHealthStatus, ServerStatus, SymbolKind, TextEdit, Url,
  49    WorkDoneProgressCancelParams, WorkspaceFolder,
  50};
  51use parking_lot::{Mutex, RwLock};
  52use postage::watch;
  53use rand::prelude::*;
  54
  55use rpc::{proto::SSH_PROJECT_ID, AnyProtoClient};
  56use serde::Serialize;
  57use settings::{Settings, SettingsLocation, SettingsStore};
  58use sha2::{Digest, Sha256};
  59use similar::{ChangeTag, TextDiff};
  60use smol::channel::Sender;
  61use snippet::Snippet;
  62use std::{
  63    any::Any,
  64    cmp::Ordering,
  65    convert::TryInto,
  66    ffi::OsStr,
  67    iter, mem,
  68    ops::{ControlFlow, Range},
  69    path::{self, Path, PathBuf},
  70    process::Stdio,
  71    str,
  72    sync::{atomic::Ordering::SeqCst, Arc},
  73    time::{Duration, Instant},
  74};
  75use text::{Anchor, BufferId, LineEnding};
  76use util::{
  77    debug_panic, defer, maybe, merge_json_value_into, post_inc, ResultExt, TryFutureExt as _,
  78};
  79
  80pub use fs::*;
  81pub use language::Location;
  82#[cfg(any(test, feature = "test-support"))]
  83pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  84pub use worktree::{
  85    Entry, EntryKind, File, LocalWorktree, PathChange, ProjectEntryId, RepositoryEntry,
  86    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  87    FS_WATCH_LATENCY,
  88};
  89
  90const MAX_SERVER_REINSTALL_ATTEMPT_COUNT: u64 = 4;
  91const SERVER_REINSTALL_DEBOUNCE_TIMEOUT: Duration = Duration::from_secs(1);
  92const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  93pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  94
  95#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  96pub enum FormatTrigger {
  97    Save,
  98    Manual,
  99}
 100
 101// Currently, formatting operations are represented differently depending on
 102// whether they come from a language server or an external command.
 103#[derive(Debug)]
 104pub enum FormatOperation {
 105    Lsp(Vec<(Range<Anchor>, String)>),
 106    External(Diff),
 107    Prettier(Diff),
 108}
 109
 110impl FormatTrigger {
 111    fn from_proto(value: i32) -> FormatTrigger {
 112        match value {
 113            0 => FormatTrigger::Save,
 114            1 => FormatTrigger::Manual,
 115            _ => FormatTrigger::Save,
 116        }
 117    }
 118}
 119
 120pub struct LocalLspStore {
 121    http_client: Option<Arc<dyn HttpClient>>,
 122    environment: Model<ProjectEnvironment>,
 123    fs: Arc<dyn Fs>,
 124    yarn: Model<YarnPathStore>,
 125    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
 126    buffers_being_formatted: HashSet<BufferId>,
 127    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
 128    language_server_watched_paths: HashMap<LanguageServerId, Model<LanguageServerWatchedPaths>>,
 129    language_server_watcher_registrations:
 130        HashMap<LanguageServerId, HashMap<String, Vec<FileSystemWatcher>>>,
 131    supplementary_language_servers:
 132        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
 133    prettier_store: Model<PrettierStore>,
 134    current_lsp_settings: HashMap<LanguageServerName, LspSettings>,
 135    last_formatting_failure: Option<String>,
 136    _subscription: gpui::Subscription,
 137}
 138
 139impl LocalLspStore {
 140    fn shutdown_language_servers(
 141        &mut self,
 142        _cx: &mut ModelContext<LspStore>,
 143    ) -> impl Future<Output = ()> {
 144        let shutdown_futures = self
 145            .language_servers
 146            .drain()
 147            .map(|(_, server_state)| async {
 148                use LanguageServerState::*;
 149                match server_state {
 150                    Running { server, .. } => server.shutdown()?.await,
 151                    Starting(task) => task.await?.shutdown()?.await,
 152                }
 153            })
 154            .collect::<Vec<_>>();
 155
 156        async move {
 157            futures::future::join_all(shutdown_futures).await;
 158        }
 159    }
 160    async fn format_locally(
 161        lsp_store: WeakModel<LspStore>,
 162        mut buffers_with_paths: Vec<(Model<Buffer>, Option<PathBuf>)>,
 163        push_to_history: bool,
 164        trigger: FormatTrigger,
 165        mut cx: AsyncAppContext,
 166    ) -> anyhow::Result<ProjectTransaction> {
 167        // Do not allow multiple concurrent formatting requests for the
 168        // same buffer.
 169        lsp_store.update(&mut cx, |this, cx| {
 170            let this = this.as_local_mut().unwrap();
 171            buffers_with_paths.retain(|(buffer, _)| {
 172                this.buffers_being_formatted
 173                    .insert(buffer.read(cx).remote_id())
 174            });
 175        })?;
 176
 177        let _cleanup = defer({
 178            let this = lsp_store.clone();
 179            let mut cx = cx.clone();
 180            let buffers = &buffers_with_paths;
 181            move || {
 182                this.update(&mut cx, |this, cx| {
 183                    let this = this.as_local_mut().unwrap();
 184                    for (buffer, _) in buffers {
 185                        this.buffers_being_formatted
 186                            .remove(&buffer.read(cx).remote_id());
 187                    }
 188                })
 189                .ok();
 190            }
 191        });
 192
 193        let mut project_transaction = ProjectTransaction::default();
 194        for (buffer, buffer_abs_path) in &buffers_with_paths {
 195            let (primary_adapter_and_server, adapters_and_servers) =
 196                lsp_store.update(&mut cx, |lsp_store, cx| {
 197                    let buffer = buffer.read(cx);
 198
 199                    let adapters_and_servers = lsp_store
 200                        .language_servers_for_buffer(buffer, cx)
 201                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 202                        .collect::<Vec<_>>();
 203
 204                    let primary_adapter = lsp_store
 205                        .primary_language_server_for_buffer(buffer, cx)
 206                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()));
 207
 208                    (primary_adapter, adapters_and_servers)
 209                })?;
 210
 211            let settings = buffer.update(&mut cx, |buffer, cx| {
 212                language_settings(buffer.language(), buffer.file(), cx).clone()
 213            })?;
 214
 215            let remove_trailing_whitespace = settings.remove_trailing_whitespace_on_save;
 216            let ensure_final_newline = settings.ensure_final_newline_on_save;
 217
 218            // First, format buffer's whitespace according to the settings.
 219            let trailing_whitespace_diff = if remove_trailing_whitespace {
 220                Some(
 221                    buffer
 222                        .update(&mut cx, |b, cx| b.remove_trailing_whitespace(cx))?
 223                        .await,
 224                )
 225            } else {
 226                None
 227            };
 228            let whitespace_transaction_id = buffer.update(&mut cx, |buffer, cx| {
 229                buffer.finalize_last_transaction();
 230                buffer.start_transaction();
 231                if let Some(diff) = trailing_whitespace_diff {
 232                    buffer.apply_diff(diff, cx);
 233                }
 234                if ensure_final_newline {
 235                    buffer.ensure_final_newline(cx);
 236                }
 237                buffer.end_transaction(cx)
 238            })?;
 239
 240            // Apply the `code_actions_on_format` before we run the formatter.
 241            let code_actions = deserialize_code_actions(&settings.code_actions_on_format);
 242            #[allow(clippy::nonminimal_bool)]
 243            if !code_actions.is_empty()
 244                && !(trigger == FormatTrigger::Save && settings.format_on_save == FormatOnSave::Off)
 245            {
 246                LspStore::execute_code_actions_on_servers(
 247                    &lsp_store,
 248                    &adapters_and_servers,
 249                    code_actions,
 250                    buffer,
 251                    push_to_history,
 252                    &mut project_transaction,
 253                    &mut cx,
 254                )
 255                .await?;
 256            }
 257
 258            // Apply language-specific formatting using either the primary language server
 259            // or external command.
 260            // Except for code actions, which are applied with all connected language servers.
 261            let primary_language_server =
 262                primary_adapter_and_server.map(|(_adapter, server)| server.clone());
 263            let server_and_buffer = primary_language_server
 264                .as_ref()
 265                .zip(buffer_abs_path.as_ref());
 266
 267            let prettier_settings = buffer.read_with(&cx, |buffer, cx| {
 268                language_settings(buffer.language(), buffer.file(), cx)
 269                    .prettier
 270                    .clone()
 271            })?;
 272
 273            let mut format_operations: Vec<FormatOperation> = vec![];
 274            {
 275                match trigger {
 276                    FormatTrigger::Save => {
 277                        match &settings.format_on_save {
 278                            FormatOnSave::Off => {
 279                                // nothing
 280                            }
 281                            FormatOnSave::On => {
 282                                match &settings.formatter {
 283                                    SelectedFormatter::Auto => {
 284                                        // do the auto-format: prefer prettier, fallback to primary language server
 285                                        let diff = {
 286                                            if prettier_settings.allowed {
 287                                                Self::perform_format(
 288                                                    &Formatter::Prettier,
 289                                                    server_and_buffer,
 290                                                    lsp_store.clone(),
 291                                                    buffer,
 292                                                    buffer_abs_path,
 293                                                    &settings,
 294                                                    &adapters_and_servers,
 295                                                    push_to_history,
 296                                                    &mut project_transaction,
 297                                                    &mut cx,
 298                                                )
 299                                                .await
 300                                            } else {
 301                                                Self::perform_format(
 302                                                    &Formatter::LanguageServer { name: None },
 303                                                    server_and_buffer,
 304                                                    lsp_store.clone(),
 305                                                    buffer,
 306                                                    buffer_abs_path,
 307                                                    &settings,
 308                                                    &adapters_and_servers,
 309                                                    push_to_history,
 310                                                    &mut project_transaction,
 311                                                    &mut cx,
 312                                                )
 313                                                .await
 314                                            }
 315                                        }
 316                                        .log_err()
 317                                        .flatten();
 318                                        if let Some(op) = diff {
 319                                            format_operations.push(op);
 320                                        }
 321                                    }
 322                                    SelectedFormatter::List(formatters) => {
 323                                        for formatter in formatters.as_ref() {
 324                                            let diff = Self::perform_format(
 325                                                formatter,
 326                                                server_and_buffer,
 327                                                lsp_store.clone(),
 328                                                buffer,
 329                                                buffer_abs_path,
 330                                                &settings,
 331                                                &adapters_and_servers,
 332                                                push_to_history,
 333                                                &mut project_transaction,
 334                                                &mut cx,
 335                                            )
 336                                            .await
 337                                            .log_err()
 338                                            .flatten();
 339                                            if let Some(op) = diff {
 340                                                format_operations.push(op);
 341                                            }
 342
 343                                            // format with formatter
 344                                        }
 345                                    }
 346                                }
 347                            }
 348                            FormatOnSave::List(formatters) => {
 349                                for formatter in formatters.as_ref() {
 350                                    let diff = Self::perform_format(
 351                                        formatter,
 352                                        server_and_buffer,
 353                                        lsp_store.clone(),
 354                                        buffer,
 355                                        buffer_abs_path,
 356                                        &settings,
 357                                        &adapters_and_servers,
 358                                        push_to_history,
 359                                        &mut project_transaction,
 360                                        &mut cx,
 361                                    )
 362                                    .await
 363                                    .log_err()
 364                                    .flatten();
 365                                    if let Some(op) = diff {
 366                                        format_operations.push(op);
 367                                    }
 368                                }
 369                            }
 370                        }
 371                    }
 372                    FormatTrigger::Manual => {
 373                        match &settings.formatter {
 374                            SelectedFormatter::Auto => {
 375                                // do the auto-format: prefer prettier, fallback to primary language server
 376                                let diff = {
 377                                    if prettier_settings.allowed {
 378                                        Self::perform_format(
 379                                            &Formatter::Prettier,
 380                                            server_and_buffer,
 381                                            lsp_store.clone(),
 382                                            buffer,
 383                                            buffer_abs_path,
 384                                            &settings,
 385                                            &adapters_and_servers,
 386                                            push_to_history,
 387                                            &mut project_transaction,
 388                                            &mut cx,
 389                                        )
 390                                        .await
 391                                    } else {
 392                                        Self::perform_format(
 393                                            &Formatter::LanguageServer { name: None },
 394                                            server_and_buffer,
 395                                            lsp_store.clone(),
 396                                            buffer,
 397                                            buffer_abs_path,
 398                                            &settings,
 399                                            &adapters_and_servers,
 400                                            push_to_history,
 401                                            &mut project_transaction,
 402                                            &mut cx,
 403                                        )
 404                                        .await
 405                                    }
 406                                }
 407                                .log_err()
 408                                .flatten();
 409
 410                                if let Some(op) = diff {
 411                                    format_operations.push(op)
 412                                }
 413                            }
 414                            SelectedFormatter::List(formatters) => {
 415                                for formatter in formatters.as_ref() {
 416                                    // format with formatter
 417                                    let diff = Self::perform_format(
 418                                        formatter,
 419                                        server_and_buffer,
 420                                        lsp_store.clone(),
 421                                        buffer,
 422                                        buffer_abs_path,
 423                                        &settings,
 424                                        &adapters_and_servers,
 425                                        push_to_history,
 426                                        &mut project_transaction,
 427                                        &mut cx,
 428                                    )
 429                                    .await
 430                                    .log_err()
 431                                    .flatten();
 432                                    if let Some(op) = diff {
 433                                        format_operations.push(op);
 434                                    }
 435                                }
 436                            }
 437                        }
 438                    }
 439                }
 440            }
 441
 442            buffer.update(&mut cx, |b, cx| {
 443                // If the buffer had its whitespace formatted and was edited while the language-specific
 444                // formatting was being computed, avoid applying the language-specific formatting, because
 445                // it can't be grouped with the whitespace formatting in the undo history.
 446                if let Some(transaction_id) = whitespace_transaction_id {
 447                    if b.peek_undo_stack()
 448                        .map_or(true, |e| e.transaction_id() != transaction_id)
 449                    {
 450                        format_operations.clear();
 451                    }
 452                }
 453
 454                // Apply any language-specific formatting, and group the two formatting operations
 455                // in the buffer's undo history.
 456                for operation in format_operations {
 457                    match operation {
 458                        FormatOperation::Lsp(edits) => {
 459                            b.edit(edits, None, cx);
 460                        }
 461                        FormatOperation::External(diff) => {
 462                            b.apply_diff(diff, cx);
 463                        }
 464                        FormatOperation::Prettier(diff) => {
 465                            b.apply_diff(diff, cx);
 466                        }
 467                    }
 468
 469                    if let Some(transaction_id) = whitespace_transaction_id {
 470                        b.group_until_transaction(transaction_id);
 471                    } else if let Some(transaction) = project_transaction.0.get(buffer) {
 472                        b.group_until_transaction(transaction.id)
 473                    }
 474                }
 475
 476                if let Some(transaction) = b.finalize_last_transaction().cloned() {
 477                    if !push_to_history {
 478                        b.forget_transaction(transaction.id);
 479                    }
 480                    project_transaction.0.insert(buffer.clone(), transaction);
 481                }
 482            })?;
 483        }
 484
 485        Ok(project_transaction)
 486    }
 487
 488    #[allow(clippy::too_many_arguments)]
 489    async fn perform_format(
 490        formatter: &Formatter,
 491        primary_server_and_buffer: Option<(&Arc<LanguageServer>, &PathBuf)>,
 492        lsp_store: WeakModel<LspStore>,
 493        buffer: &Model<Buffer>,
 494        buffer_abs_path: &Option<PathBuf>,
 495        settings: &LanguageSettings,
 496        adapters_and_servers: &[(Arc<CachedLspAdapter>, Arc<LanguageServer>)],
 497        push_to_history: bool,
 498        transaction: &mut ProjectTransaction,
 499        cx: &mut AsyncAppContext,
 500    ) -> Result<Option<FormatOperation>, anyhow::Error> {
 501        let result = match formatter {
 502            Formatter::LanguageServer { name } => {
 503                if let Some((language_server, buffer_abs_path)) = primary_server_and_buffer {
 504                    let language_server = if let Some(name) = name {
 505                        adapters_and_servers
 506                            .iter()
 507                            .find_map(|(adapter, server)| {
 508                                adapter.name.0.as_ref().eq(name.as_str()).then_some(server)
 509                            })
 510                            .unwrap_or(language_server)
 511                    } else {
 512                        language_server
 513                    };
 514
 515                    Some(FormatOperation::Lsp(
 516                        LspStore::format_via_lsp(
 517                            &lsp_store,
 518                            buffer,
 519                            buffer_abs_path,
 520                            language_server,
 521                            settings,
 522                            cx,
 523                        )
 524                        .await
 525                        .context("failed to format via language server")?,
 526                    ))
 527                } else {
 528                    None
 529                }
 530            }
 531            Formatter::Prettier => {
 532                let prettier = lsp_store.update(cx, |lsp_store, _cx| {
 533                    lsp_store.prettier_store().unwrap().downgrade()
 534                })?;
 535                prettier_store::format_with_prettier(&prettier, buffer, cx)
 536                    .await
 537                    .transpose()
 538                    .ok()
 539                    .flatten()
 540            }
 541            Formatter::External { command, arguments } => {
 542                let buffer_abs_path = buffer_abs_path.as_ref().map(|path| path.as_path());
 543                Self::format_via_external_command(buffer, buffer_abs_path, command, arguments, cx)
 544                    .await
 545                    .context(format!(
 546                        "failed to format via external command {:?}",
 547                        command
 548                    ))?
 549                    .map(FormatOperation::External)
 550            }
 551            Formatter::CodeActions(code_actions) => {
 552                let code_actions = deserialize_code_actions(code_actions);
 553                if !code_actions.is_empty() {
 554                    LspStore::execute_code_actions_on_servers(
 555                        &lsp_store,
 556                        adapters_and_servers,
 557                        code_actions,
 558                        buffer,
 559                        push_to_history,
 560                        transaction,
 561                        cx,
 562                    )
 563                    .await?;
 564                }
 565                None
 566            }
 567        };
 568        anyhow::Ok(result)
 569    }
 570
 571    async fn format_via_external_command(
 572        buffer: &Model<Buffer>,
 573        buffer_abs_path: Option<&Path>,
 574        command: &str,
 575        arguments: &[String],
 576        cx: &mut AsyncAppContext,
 577    ) -> Result<Option<Diff>> {
 578        let working_dir_path = buffer.update(cx, |buffer, cx| {
 579            let file = File::from_dyn(buffer.file())?;
 580            let worktree = file.worktree.read(cx);
 581            let mut worktree_path = worktree.abs_path().to_path_buf();
 582            if worktree.root_entry()?.is_file() {
 583                worktree_path.pop();
 584            }
 585            Some(worktree_path)
 586        })?;
 587
 588        let mut child = smol::process::Command::new(command);
 589        #[cfg(target_os = "windows")]
 590        {
 591            use smol::process::windows::CommandExt;
 592            child.creation_flags(windows::Win32::System::Threading::CREATE_NO_WINDOW.0);
 593        }
 594
 595        if let Some(working_dir_path) = working_dir_path {
 596            child.current_dir(working_dir_path);
 597        }
 598
 599        let mut child = child
 600            .args(arguments.iter().map(|arg| {
 601                if let Some(buffer_abs_path) = buffer_abs_path {
 602                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 603                } else {
 604                    arg.replace("{buffer_path}", "Untitled")
 605                }
 606            }))
 607            .stdin(smol::process::Stdio::piped())
 608            .stdout(smol::process::Stdio::piped())
 609            .stderr(smol::process::Stdio::piped())
 610            .spawn()?;
 611
 612        let stdin = child
 613            .stdin
 614            .as_mut()
 615            .ok_or_else(|| anyhow!("failed to acquire stdin"))?;
 616        let text = buffer.update(cx, |buffer, _| buffer.as_rope().clone())?;
 617        for chunk in text.chunks() {
 618            stdin.write_all(chunk.as_bytes()).await?;
 619        }
 620        stdin.flush().await?;
 621
 622        let output = child.output().await?;
 623        if !output.status.success() {
 624            return Err(anyhow!(
 625                "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 626                output.status.code(),
 627                String::from_utf8_lossy(&output.stdout),
 628                String::from_utf8_lossy(&output.stderr),
 629            ));
 630        }
 631
 632        let stdout = String::from_utf8(output.stdout)?;
 633        Ok(Some(
 634            buffer
 635                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 636                .await,
 637        ))
 638    }
 639}
 640
 641pub struct RemoteLspStore {
 642    upstream_client: AnyProtoClient,
 643    upstream_project_id: u64,
 644}
 645
 646impl RemoteLspStore {}
 647
 648pub struct SshLspStore {
 649    upstream_client: AnyProtoClient,
 650    current_lsp_settings: HashMap<LanguageServerName, LspSettings>,
 651}
 652
 653#[allow(clippy::large_enum_variant)]
 654pub enum LspStoreMode {
 655    Local(LocalLspStore),   // ssh host and collab host
 656    Remote(RemoteLspStore), // collab guest
 657    Ssh(SshLspStore),       // ssh client
 658}
 659
 660impl LspStoreMode {
 661    fn is_local(&self) -> bool {
 662        matches!(self, LspStoreMode::Local(_))
 663    }
 664
 665    fn is_ssh(&self) -> bool {
 666        matches!(self, LspStoreMode::Ssh(_))
 667    }
 668
 669    fn is_remote(&self) -> bool {
 670        matches!(self, LspStoreMode::Remote(_))
 671    }
 672}
 673
 674pub struct LspStore {
 675    mode: LspStoreMode,
 676    downstream_client: Option<(AnyProtoClient, u64)>,
 677    nonce: u128,
 678    buffer_store: Model<BufferStore>,
 679    worktree_store: Model<WorktreeStore>,
 680    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
 681    pub languages: Arc<LanguageRegistry>,
 682    language_server_ids: HashMap<(WorktreeId, LanguageServerName), LanguageServerId>,
 683    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 684    active_entry: Option<ProjectEntryId>,
 685    _maintain_workspace_config: Task<Result<()>>,
 686    _maintain_buffer_languages: Task<()>,
 687    next_diagnostic_group_id: usize,
 688    diagnostic_summaries:
 689        HashMap<WorktreeId, HashMap<Arc<Path>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 690    diagnostics: HashMap<
 691        WorktreeId,
 692        HashMap<
 693            Arc<Path>,
 694            Vec<(
 695                LanguageServerId,
 696                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 697            )>,
 698        >,
 699    >,
 700}
 701
 702pub enum LspStoreEvent {
 703    LanguageServerAdded(LanguageServerId),
 704    LanguageServerRemoved(LanguageServerId),
 705    LanguageServerUpdate {
 706        language_server_id: LanguageServerId,
 707        message: proto::update_language_server::Variant,
 708    },
 709    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 710    LanguageServerPrompt(LanguageServerPromptRequest),
 711    LanguageDetected {
 712        buffer: Model<Buffer>,
 713        new_language: Option<Arc<Language>>,
 714    },
 715    Notification(String),
 716    RefreshInlayHints,
 717    DiagnosticsUpdated {
 718        language_server_id: LanguageServerId,
 719        path: ProjectPath,
 720    },
 721    DiskBasedDiagnosticsStarted {
 722        language_server_id: LanguageServerId,
 723    },
 724    DiskBasedDiagnosticsFinished {
 725        language_server_id: LanguageServerId,
 726    },
 727    SnippetEdit {
 728        buffer_id: BufferId,
 729        edits: Vec<(lsp::Range, Snippet)>,
 730        most_recent_edit: clock::Lamport,
 731    },
 732}
 733
 734#[derive(Clone, Debug, Serialize)]
 735pub struct LanguageServerStatus {
 736    pub name: String,
 737    pub pending_work: BTreeMap<String, LanguageServerProgress>,
 738    pub has_pending_diagnostic_updates: bool,
 739    progress_tokens: HashSet<String>,
 740}
 741
 742#[derive(Clone, Debug)]
 743struct CoreSymbol {
 744    pub language_server_name: LanguageServerName,
 745    pub source_worktree_id: WorktreeId,
 746    pub path: ProjectPath,
 747    pub name: String,
 748    pub kind: lsp::SymbolKind,
 749    pub range: Range<Unclipped<PointUtf16>>,
 750    pub signature: [u8; 32],
 751}
 752
 753impl LspStore {
 754    pub fn init(client: &AnyProtoClient) {
 755        client.add_model_request_handler(Self::handle_multi_lsp_query);
 756        client.add_model_request_handler(Self::handle_restart_language_servers);
 757        client.add_model_message_handler(Self::handle_start_language_server);
 758        client.add_model_message_handler(Self::handle_update_language_server);
 759        client.add_model_message_handler(Self::handle_update_diagnostic_summary);
 760        client.add_model_request_handler(Self::handle_format_buffers);
 761        client.add_model_request_handler(Self::handle_resolve_completion_documentation);
 762        client.add_model_request_handler(Self::handle_apply_code_action);
 763        client.add_model_request_handler(Self::handle_inlay_hints);
 764        client.add_model_request_handler(Self::handle_get_project_symbols);
 765        client.add_model_request_handler(Self::handle_resolve_inlay_hint);
 766        client.add_model_request_handler(Self::handle_open_buffer_for_symbol);
 767        client.add_model_request_handler(Self::handle_refresh_inlay_hints);
 768        client.add_model_request_handler(Self::handle_on_type_formatting);
 769        client.add_model_request_handler(Self::handle_apply_additional_edits_for_completion);
 770        client.add_model_request_handler(Self::handle_lsp_command::<GetCodeActions>);
 771        client.add_model_request_handler(Self::handle_lsp_command::<GetCompletions>);
 772        client.add_model_request_handler(Self::handle_lsp_command::<GetHover>);
 773        client.add_model_request_handler(Self::handle_lsp_command::<GetDefinition>);
 774        client.add_model_request_handler(Self::handle_lsp_command::<GetDeclaration>);
 775        client.add_model_request_handler(Self::handle_lsp_command::<GetTypeDefinition>);
 776        client.add_model_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 777        client.add_model_request_handler(Self::handle_lsp_command::<GetReferences>);
 778        client.add_model_request_handler(Self::handle_lsp_command::<PrepareRename>);
 779        client.add_model_request_handler(Self::handle_lsp_command::<PerformRename>);
 780        client.add_model_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 781        client.add_model_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 782    }
 783
 784    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 785        match &self.mode {
 786            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 787            _ => None,
 788        }
 789    }
 790
 791    pub fn as_ssh(&self) -> Option<&SshLspStore> {
 792        match &self.mode {
 793            LspStoreMode::Ssh(ssh_lsp_store) => Some(ssh_lsp_store),
 794            _ => None,
 795        }
 796    }
 797
 798    pub fn as_local(&self) -> Option<&LocalLspStore> {
 799        match &self.mode {
 800            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 801            _ => None,
 802        }
 803    }
 804
 805    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 806        match &mut self.mode {
 807            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 808            _ => None,
 809        }
 810    }
 811
 812    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 813        match &self.mode {
 814            LspStoreMode::Ssh(SshLspStore {
 815                upstream_client, ..
 816            }) => Some((upstream_client.clone(), SSH_PROJECT_ID)),
 817            LspStoreMode::Remote(RemoteLspStore {
 818                upstream_client,
 819                upstream_project_id,
 820                ..
 821            }) => Some((upstream_client.clone(), *upstream_project_id)),
 822            LspStoreMode::Local(_) => None,
 823        }
 824    }
 825
 826    pub fn swap_current_lsp_settings(
 827        &mut self,
 828        new_settings: HashMap<LanguageServerName, LspSettings>,
 829    ) -> Option<HashMap<LanguageServerName, LspSettings>> {
 830        match &mut self.mode {
 831            LspStoreMode::Ssh(SshLspStore {
 832                current_lsp_settings,
 833                ..
 834            })
 835            | LspStoreMode::Local(LocalLspStore {
 836                current_lsp_settings,
 837                ..
 838            }) => {
 839                let ret = mem::take(current_lsp_settings);
 840                *current_lsp_settings = new_settings;
 841                Some(ret)
 842            }
 843            LspStoreMode::Remote(_) => None,
 844        }
 845    }
 846
 847    #[allow(clippy::too_many_arguments)]
 848    pub fn new_local(
 849        buffer_store: Model<BufferStore>,
 850        worktree_store: Model<WorktreeStore>,
 851        prettier_store: Model<PrettierStore>,
 852        environment: Model<ProjectEnvironment>,
 853        languages: Arc<LanguageRegistry>,
 854        http_client: Option<Arc<dyn HttpClient>>,
 855        fs: Arc<dyn Fs>,
 856        cx: &mut ModelContext<Self>,
 857    ) -> Self {
 858        let yarn = YarnPathStore::new(fs.clone(), cx);
 859        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 860            .detach();
 861        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 862            .detach();
 863        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 864            .detach();
 865        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 866            .detach();
 867
 868        Self {
 869            mode: LspStoreMode::Local(LocalLspStore {
 870                supplementary_language_servers: Default::default(),
 871                language_servers: Default::default(),
 872                last_workspace_edits_by_language_server: Default::default(),
 873                language_server_watched_paths: Default::default(),
 874                language_server_watcher_registrations: Default::default(),
 875                current_lsp_settings: ProjectSettings::get_global(cx).lsp.clone(),
 876                buffers_being_formatted: Default::default(),
 877                last_formatting_failure: None,
 878                prettier_store,
 879                environment,
 880                http_client,
 881                fs,
 882                yarn,
 883                _subscription: cx.on_app_quit(|this, cx| {
 884                    this.as_local_mut().unwrap().shutdown_language_servers(cx)
 885                }),
 886            }),
 887            downstream_client: None,
 888            buffer_store,
 889            worktree_store,
 890            languages: languages.clone(),
 891            language_server_ids: Default::default(),
 892            language_server_statuses: Default::default(),
 893            nonce: StdRng::from_entropy().gen(),
 894            buffer_snapshots: Default::default(),
 895            next_diagnostic_group_id: Default::default(),
 896            diagnostic_summaries: Default::default(),
 897            diagnostics: Default::default(),
 898            active_entry: None,
 899
 900            _maintain_workspace_config: Self::maintain_workspace_config(cx),
 901            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 902        }
 903    }
 904
 905    fn send_lsp_proto_request<R: LspCommand>(
 906        &self,
 907        buffer: Model<Buffer>,
 908        client: AnyProtoClient,
 909        upstream_project_id: u64,
 910        request: R,
 911        cx: &mut ModelContext<'_, LspStore>,
 912    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 913        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 914        cx.spawn(move |this, cx| async move {
 915            let response = client.request(message).await?;
 916            let this = this.upgrade().context("project dropped")?;
 917            request
 918                .response_from_proto(response, this, buffer, cx)
 919                .await
 920        })
 921    }
 922
 923    pub fn new_ssh(
 924        buffer_store: Model<BufferStore>,
 925        worktree_store: Model<WorktreeStore>,
 926        languages: Arc<LanguageRegistry>,
 927        upstream_client: AnyProtoClient,
 928        cx: &mut ModelContext<Self>,
 929    ) -> Self {
 930        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 931            .detach();
 932        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 933            .detach();
 934        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 935            .detach();
 936
 937        Self {
 938            mode: LspStoreMode::Ssh(SshLspStore {
 939                upstream_client,
 940                current_lsp_settings: Default::default(),
 941            }),
 942            downstream_client: None,
 943            buffer_store,
 944            worktree_store,
 945            languages: languages.clone(),
 946            language_server_ids: Default::default(),
 947            language_server_statuses: Default::default(),
 948            nonce: StdRng::from_entropy().gen(),
 949            buffer_snapshots: Default::default(),
 950            next_diagnostic_group_id: Default::default(),
 951            diagnostic_summaries: Default::default(),
 952
 953            diagnostics: Default::default(),
 954            active_entry: None,
 955            _maintain_workspace_config: Self::maintain_workspace_config(cx),
 956            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 957        }
 958    }
 959
 960    pub fn new_remote(
 961        buffer_store: Model<BufferStore>,
 962        worktree_store: Model<WorktreeStore>,
 963        languages: Arc<LanguageRegistry>,
 964        upstream_client: AnyProtoClient,
 965        project_id: u64,
 966        cx: &mut ModelContext<Self>,
 967    ) -> Self {
 968        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 969            .detach();
 970        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 971            .detach();
 972
 973        Self {
 974            mode: LspStoreMode::Remote(RemoteLspStore {
 975                upstream_client,
 976                upstream_project_id: project_id,
 977            }),
 978            downstream_client: None,
 979            buffer_store,
 980            worktree_store,
 981            languages: languages.clone(),
 982            language_server_ids: Default::default(),
 983            language_server_statuses: Default::default(),
 984            nonce: StdRng::from_entropy().gen(),
 985            buffer_snapshots: Default::default(),
 986            next_diagnostic_group_id: Default::default(),
 987            diagnostic_summaries: Default::default(),
 988            diagnostics: Default::default(),
 989            active_entry: None,
 990            _maintain_workspace_config: Self::maintain_workspace_config(cx),
 991            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 992        }
 993    }
 994
 995    fn worktree_for_id(
 996        &self,
 997        worktree_id: WorktreeId,
 998        cx: &ModelContext<Self>,
 999    ) -> Result<Model<Worktree>> {
1000        self.worktree_store
1001            .read(cx)
1002            .worktree_for_id(worktree_id, cx)
1003            .ok_or_else(|| anyhow!("worktree not found"))
1004    }
1005
1006    fn on_buffer_store_event(
1007        &mut self,
1008        _: Model<BufferStore>,
1009        event: &BufferStoreEvent,
1010        cx: &mut ModelContext<Self>,
1011    ) {
1012        match event {
1013            BufferStoreEvent::BufferAdded(buffer) => {
1014                self.register_buffer(buffer, cx).log_err();
1015            }
1016            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
1017                if let Some(old_file) = File::from_dyn(old_file.as_ref()) {
1018                    self.unregister_buffer_from_language_servers(buffer, old_file, cx);
1019                }
1020
1021                self.register_buffer_with_language_servers(buffer, cx);
1022            }
1023            BufferStoreEvent::BufferDropped(_) => {}
1024        }
1025    }
1026
1027    fn on_worktree_store_event(
1028        &mut self,
1029        _: Model<WorktreeStore>,
1030        event: &WorktreeStoreEvent,
1031        cx: &mut ModelContext<Self>,
1032    ) {
1033        match event {
1034            WorktreeStoreEvent::WorktreeAdded(worktree) => {
1035                if !worktree.read(cx).is_local() {
1036                    return;
1037                }
1038                cx.subscribe(worktree, |this, worktree, event, cx| match event {
1039                    worktree::Event::UpdatedEntries(changes) => {
1040                        this.update_local_worktree_language_servers(&worktree, changes, cx);
1041                    }
1042                    worktree::Event::UpdatedGitRepositories(_)
1043                    | worktree::Event::DeletedEntry(_) => {}
1044                })
1045                .detach()
1046            }
1047            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
1048            WorktreeStoreEvent::WorktreeOrderChanged => {}
1049            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
1050                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
1051            }
1052        }
1053    }
1054
1055    fn on_prettier_store_event(
1056        &mut self,
1057        _: Model<PrettierStore>,
1058        event: &PrettierStoreEvent,
1059        cx: &mut ModelContext<Self>,
1060    ) {
1061        match event {
1062            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
1063                self.unregister_supplementary_language_server(*prettier_server_id, cx);
1064            }
1065            PrettierStoreEvent::LanguageServerAdded {
1066                new_server_id,
1067                name,
1068                prettier_server,
1069            } => {
1070                self.register_supplementary_language_server(
1071                    *new_server_id,
1072                    name.clone(),
1073                    prettier_server.clone(),
1074                    cx,
1075                );
1076            }
1077        }
1078    }
1079
1080    // todo!
1081    pub fn prettier_store(&self) -> Option<Model<PrettierStore>> {
1082        self.as_local().map(|local| local.prettier_store.clone())
1083    }
1084
1085    fn on_buffer_event(
1086        &mut self,
1087        buffer: Model<Buffer>,
1088        event: &language::BufferEvent,
1089        cx: &mut ModelContext<Self>,
1090    ) {
1091        match event {
1092            language::BufferEvent::Edited { .. } => {
1093                self.on_buffer_edited(buffer, cx);
1094            }
1095
1096            language::BufferEvent::Saved => {
1097                self.on_buffer_saved(buffer, cx);
1098            }
1099
1100            _ => {}
1101        }
1102    }
1103
1104    fn register_buffer(
1105        &mut self,
1106        buffer: &Model<Buffer>,
1107        cx: &mut ModelContext<Self>,
1108    ) -> Result<()> {
1109        buffer.update(cx, |buffer, _| {
1110            buffer.set_language_registry(self.languages.clone())
1111        });
1112
1113        cx.subscribe(buffer, |this, buffer, event, cx| {
1114            this.on_buffer_event(buffer, event, cx);
1115        })
1116        .detach();
1117
1118        self.register_buffer_with_language_servers(buffer, cx);
1119        cx.observe_release(buffer, |this, buffer, cx| {
1120            if let Some(file) = File::from_dyn(buffer.file()) {
1121                if file.is_local() {
1122                    let uri = lsp::Url::from_file_path(file.abs_path(cx)).unwrap();
1123                    for server in this.language_servers_for_buffer(buffer, cx) {
1124                        server
1125                            .1
1126                            .notify::<lsp::notification::DidCloseTextDocument>(
1127                                lsp::DidCloseTextDocumentParams {
1128                                    text_document: lsp::TextDocumentIdentifier::new(uri.clone()),
1129                                },
1130                            )
1131                            .log_err();
1132                    }
1133                }
1134            }
1135        })
1136        .detach();
1137
1138        Ok(())
1139    }
1140
1141    fn maintain_buffer_languages(
1142        languages: Arc<LanguageRegistry>,
1143        cx: &mut ModelContext<Self>,
1144    ) -> Task<()> {
1145        let mut subscription = languages.subscribe();
1146        let mut prev_reload_count = languages.reload_count();
1147        cx.spawn(move |this, mut cx| async move {
1148            while let Some(()) = subscription.next().await {
1149                if let Some(this) = this.upgrade() {
1150                    // If the language registry has been reloaded, then remove and
1151                    // re-assign the languages on all open buffers.
1152                    let reload_count = languages.reload_count();
1153                    if reload_count > prev_reload_count {
1154                        prev_reload_count = reload_count;
1155                        this.update(&mut cx, |this, cx| {
1156                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
1157                                for buffer in buffer_store.buffers() {
1158                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
1159                                    {
1160                                        this.unregister_buffer_from_language_servers(
1161                                            &buffer, &f, cx,
1162                                        );
1163                                        buffer
1164                                            .update(cx, |buffer, cx| buffer.set_language(None, cx));
1165                                    }
1166                                }
1167                            });
1168                        })
1169                        .ok();
1170                    }
1171
1172                    this.update(&mut cx, |this, cx| {
1173                        let mut plain_text_buffers = Vec::new();
1174                        let mut buffers_with_unknown_injections = Vec::new();
1175                        for handle in this.buffer_store.read(cx).buffers() {
1176                            let buffer = handle.read(cx);
1177                            if buffer.language().is_none()
1178                                || buffer.language() == Some(&*language::PLAIN_TEXT)
1179                            {
1180                                plain_text_buffers.push(handle);
1181                            } else if buffer.contains_unknown_injections() {
1182                                buffers_with_unknown_injections.push(handle);
1183                            }
1184                        }
1185                        for buffer in plain_text_buffers {
1186                            this.register_buffer_with_language_servers(&buffer, cx);
1187                        }
1188
1189                        for buffer in buffers_with_unknown_injections {
1190                            buffer.update(cx, |buffer, cx| buffer.reparse(cx));
1191                        }
1192                    })
1193                    .ok();
1194                }
1195            }
1196        })
1197    }
1198
1199    fn detect_language_for_buffer(
1200        &mut self,
1201        buffer_handle: &Model<Buffer>,
1202        cx: &mut ModelContext<Self>,
1203    ) -> Option<language::AvailableLanguage> {
1204        // If the buffer has a language, set it and start the language server if we haven't already.
1205        let buffer = buffer_handle.read(cx);
1206        let file = buffer.file()?;
1207
1208        let content = buffer.as_rope();
1209        let available_language = self.languages.language_for_file(file, Some(content), cx);
1210        if let Some(available_language) = &available_language {
1211            if let Some(Ok(Ok(new_language))) = self
1212                .languages
1213                .load_language(available_language)
1214                .now_or_never()
1215            {
1216                self.set_language_for_buffer(buffer_handle, new_language, cx);
1217            }
1218        } else {
1219            cx.emit(LspStoreEvent::LanguageDetected {
1220                buffer: buffer_handle.clone(),
1221                new_language: None,
1222            });
1223        }
1224
1225        available_language
1226    }
1227
1228    pub fn set_language_for_buffer(
1229        &mut self,
1230        buffer: &Model<Buffer>,
1231        new_language: Arc<Language>,
1232        cx: &mut ModelContext<Self>,
1233    ) {
1234        buffer.update(cx, |buffer, cx| {
1235            if buffer.language().map_or(true, |old_language| {
1236                !Arc::ptr_eq(old_language, &new_language)
1237            }) {
1238                buffer.set_language(Some(new_language.clone()), cx);
1239            }
1240        });
1241
1242        let buffer_file = buffer.read(cx).file().cloned();
1243        let settings = language_settings(Some(&new_language), buffer_file.as_ref(), cx).clone();
1244        let buffer_file = File::from_dyn(buffer_file.as_ref());
1245
1246        let worktree_id = if let Some(file) = buffer_file {
1247            let worktree = file.worktree.clone();
1248            self.start_language_servers(&worktree, new_language.name(), cx);
1249
1250            Some(worktree.read(cx).id())
1251        } else {
1252            None
1253        };
1254
1255        if let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings) {
1256            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
1257            if let Some(prettier_store) = prettier_store {
1258                prettier_store.update(cx, |prettier_store, cx| {
1259                    prettier_store.install_default_prettier(
1260                        worktree_id,
1261                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
1262                        cx,
1263                    )
1264                })
1265            }
1266        }
1267
1268        cx.emit(LspStoreEvent::LanguageDetected {
1269            buffer: buffer.clone(),
1270            new_language: Some(new_language),
1271        })
1272    }
1273
1274    pub fn buffer_store(&self) -> Model<BufferStore> {
1275        self.buffer_store.clone()
1276    }
1277
1278    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
1279        self.active_entry = active_entry;
1280    }
1281
1282    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
1283        if let Some((client, downstream_project_id)) = self.downstream_client.clone() {
1284            if let Some(summaries) = self.diagnostic_summaries.get(&worktree.id()) {
1285                for (path, summaries) in summaries {
1286                    for (&server_id, summary) in summaries {
1287                        client
1288                            .send(proto::UpdateDiagnosticSummary {
1289                                project_id: downstream_project_id,
1290                                worktree_id: worktree.id().to_proto(),
1291                                summary: Some(summary.to_proto(server_id, path)),
1292                            })
1293                            .log_err();
1294                    }
1295                }
1296            }
1297        }
1298    }
1299
1300    pub fn request_lsp<R: LspCommand>(
1301        &self,
1302        buffer_handle: Model<Buffer>,
1303        server: LanguageServerToQuery,
1304        request: R,
1305        cx: &mut ModelContext<Self>,
1306    ) -> Task<Result<R::Response>>
1307    where
1308        <R::LspRequest as lsp::request::Request>::Result: Send,
1309        <R::LspRequest as lsp::request::Request>::Params: Send,
1310    {
1311        let buffer = buffer_handle.read(cx);
1312
1313        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
1314            return self.send_lsp_proto_request(
1315                buffer_handle,
1316                upstream_client,
1317                upstream_project_id,
1318                request,
1319                cx,
1320            );
1321        }
1322
1323        let language_server = match server {
1324            LanguageServerToQuery::Primary => {
1325                match self.primary_language_server_for_buffer(buffer, cx) {
1326                    Some((_, server)) => Some(Arc::clone(server)),
1327                    None => return Task::ready(Ok(Default::default())),
1328                }
1329            }
1330            LanguageServerToQuery::Other(id) => self
1331                .language_server_for_buffer(buffer, id, cx)
1332                .map(|(_, server)| Arc::clone(server)),
1333        };
1334        let file = File::from_dyn(buffer.file()).and_then(File::as_local);
1335        if let (Some(file), Some(language_server)) = (file, language_server) {
1336            let lsp_params = request.to_lsp(&file.abs_path(cx), buffer, &language_server, cx);
1337            let status = request.status();
1338            return cx.spawn(move |this, cx| async move {
1339                if !request.check_capabilities(language_server.adapter_server_capabilities()) {
1340                    return Ok(Default::default());
1341                }
1342
1343                let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
1344
1345                let id = lsp_request.id();
1346                let _cleanup = if status.is_some() {
1347                    cx.update(|cx| {
1348                        this.update(cx, |this, cx| {
1349                            this.on_lsp_work_start(
1350                                language_server.server_id(),
1351                                id.to_string(),
1352                                LanguageServerProgress {
1353                                    is_disk_based_diagnostics_progress: false,
1354                                    is_cancellable: false,
1355                                    title: None,
1356                                    message: status.clone(),
1357                                    percentage: None,
1358                                    last_update_at: cx.background_executor().now(),
1359                                },
1360                                cx,
1361                            );
1362                        })
1363                    })
1364                    .log_err();
1365
1366                    Some(defer(|| {
1367                        cx.update(|cx| {
1368                            this.update(cx, |this, cx| {
1369                                this.on_lsp_work_end(
1370                                    language_server.server_id(),
1371                                    id.to_string(),
1372                                    cx,
1373                                );
1374                            })
1375                        })
1376                        .log_err();
1377                    }))
1378                } else {
1379                    None
1380                };
1381
1382                let result = lsp_request.await;
1383
1384                let response = result.map_err(|err| {
1385                    log::warn!(
1386                        "Generic lsp request to {} failed: {}",
1387                        language_server.name(),
1388                        err
1389                    );
1390                    err
1391                })?;
1392
1393                request
1394                    .response_from_lsp(
1395                        response,
1396                        this.upgrade().ok_or_else(|| anyhow!("no app context"))?,
1397                        buffer_handle,
1398                        language_server.server_id(),
1399                        cx.clone(),
1400                    )
1401                    .await
1402            });
1403        }
1404
1405        Task::ready(Ok(Default::default()))
1406    }
1407
1408    fn on_settings_changed(&mut self, cx: &mut ModelContext<Self>) {
1409        let mut language_servers_to_start = Vec::new();
1410        let mut language_formatters_to_check = Vec::new();
1411        for buffer in self.buffer_store.read(cx).buffers() {
1412            let buffer = buffer.read(cx);
1413            let buffer_file = File::from_dyn(buffer.file());
1414            let buffer_language = buffer.language();
1415            let settings = language_settings(buffer_language, buffer.file(), cx);
1416            if let Some(language) = buffer_language {
1417                if settings.enable_language_server {
1418                    if let Some(file) = buffer_file {
1419                        language_servers_to_start.push((file.worktree.clone(), language.name()));
1420                    }
1421                }
1422                language_formatters_to_check
1423                    .push((buffer_file.map(|f| f.worktree_id(cx)), settings.clone()));
1424            }
1425        }
1426
1427        let mut language_servers_to_stop = Vec::new();
1428        let mut language_servers_to_restart = Vec::new();
1429        let languages = self.languages.to_vec();
1430
1431        let new_lsp_settings = ProjectSettings::get_global(cx).lsp.clone();
1432        let Some(current_lsp_settings) = self.swap_current_lsp_settings(new_lsp_settings.clone())
1433        else {
1434            return;
1435        };
1436        for (worktree_id, started_lsp_name) in self.started_language_servers() {
1437            let language = languages.iter().find_map(|l| {
1438                let adapter = self
1439                    .languages
1440                    .lsp_adapters(&l.name())
1441                    .iter()
1442                    .find(|adapter| adapter.name == started_lsp_name)?
1443                    .clone();
1444                Some((l, adapter))
1445            });
1446            if let Some((language, adapter)) = language {
1447                let worktree = self.worktree_for_id(worktree_id, cx).ok();
1448                let file = worktree.as_ref().and_then(|tree| {
1449                    tree.update(cx, |tree, cx| tree.root_file(cx).map(|f| f as _))
1450                });
1451                if !language_settings(Some(language), file.as_ref(), cx).enable_language_server {
1452                    language_servers_to_stop.push((worktree_id, started_lsp_name.clone()));
1453                } else if let Some(worktree) = worktree {
1454                    let server_name = &adapter.name;
1455                    match (
1456                        current_lsp_settings.get(server_name),
1457                        new_lsp_settings.get(server_name),
1458                    ) {
1459                        (None, None) => {}
1460                        (Some(_), None) | (None, Some(_)) => {
1461                            language_servers_to_restart.push((worktree, language.name()));
1462                        }
1463                        (Some(current_lsp_settings), Some(new_lsp_settings)) => {
1464                            if current_lsp_settings != new_lsp_settings {
1465                                language_servers_to_restart.push((worktree, language.name()));
1466                            }
1467                        }
1468                    }
1469                }
1470            }
1471        }
1472
1473        for (worktree_id, adapter_name) in language_servers_to_stop {
1474            self.stop_language_server(worktree_id, adapter_name, cx)
1475                .detach();
1476        }
1477
1478        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
1479            prettier_store.update(cx, |prettier_store, cx| {
1480                prettier_store.on_settings_changed(language_formatters_to_check, cx)
1481            })
1482        }
1483
1484        // Start all the newly-enabled language servers.
1485        for (worktree, language) in language_servers_to_start {
1486            self.start_language_servers(&worktree, language, cx);
1487        }
1488
1489        // Restart all language servers with changed initialization options.
1490        for (worktree, language) in language_servers_to_restart {
1491            self.restart_language_servers(worktree, language, cx);
1492        }
1493
1494        cx.notify();
1495    }
1496
1497    pub async fn execute_code_actions_on_servers(
1498        this: &WeakModel<LspStore>,
1499        adapters_and_servers: &[(Arc<CachedLspAdapter>, Arc<LanguageServer>)],
1500        code_actions: Vec<lsp::CodeActionKind>,
1501        buffer: &Model<Buffer>,
1502        push_to_history: bool,
1503        project_transaction: &mut ProjectTransaction,
1504        cx: &mut AsyncAppContext,
1505    ) -> Result<(), anyhow::Error> {
1506        for (lsp_adapter, language_server) in adapters_and_servers.iter() {
1507            let code_actions = code_actions.clone();
1508
1509            let actions = this
1510                .update(cx, move |this, cx| {
1511                    let request = GetCodeActions {
1512                        range: text::Anchor::MIN..text::Anchor::MAX,
1513                        kinds: Some(code_actions),
1514                    };
1515                    let server = LanguageServerToQuery::Other(language_server.server_id());
1516                    this.request_lsp(buffer.clone(), server, request, cx)
1517                })?
1518                .await?;
1519
1520            for mut action in actions {
1521                Self::try_resolve_code_action(language_server, &mut action)
1522                    .await
1523                    .context("resolving a formatting code action")?;
1524
1525                if let Some(edit) = action.lsp_action.edit {
1526                    if edit.changes.is_none() && edit.document_changes.is_none() {
1527                        continue;
1528                    }
1529
1530                    let new = Self::deserialize_workspace_edit(
1531                        this.upgrade().ok_or_else(|| anyhow!("project dropped"))?,
1532                        edit,
1533                        push_to_history,
1534                        lsp_adapter.clone(),
1535                        language_server.clone(),
1536                        cx,
1537                    )
1538                    .await?;
1539                    project_transaction.0.extend(new.0);
1540                }
1541
1542                if let Some(command) = action.lsp_action.command {
1543                    this.update(cx, |this, _| {
1544                        if let LspStoreMode::Local(mode) = &mut this.mode {
1545                            mode.last_workspace_edits_by_language_server
1546                                .remove(&language_server.server_id());
1547                        }
1548                    })?;
1549
1550                    language_server
1551                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
1552                            command: command.command,
1553                            arguments: command.arguments.unwrap_or_default(),
1554                            ..Default::default()
1555                        })
1556                        .await?;
1557
1558                    this.update(cx, |this, _| {
1559                        if let LspStoreMode::Local(mode) = &mut this.mode {
1560                            project_transaction.0.extend(
1561                                mode.last_workspace_edits_by_language_server
1562                                    .remove(&language_server.server_id())
1563                                    .unwrap_or_default()
1564                                    .0,
1565                            )
1566                        }
1567                    })?;
1568                }
1569            }
1570        }
1571
1572        Ok(())
1573    }
1574
1575    async fn try_resolve_code_action(
1576        lang_server: &LanguageServer,
1577        action: &mut CodeAction,
1578    ) -> anyhow::Result<()> {
1579        if GetCodeActions::can_resolve_actions(&lang_server.capabilities())
1580            && action.lsp_action.data.is_some()
1581            && (action.lsp_action.command.is_none() || action.lsp_action.edit.is_none())
1582        {
1583            action.lsp_action = lang_server
1584                .request::<lsp::request::CodeActionResolveRequest>(action.lsp_action.clone())
1585                .await?;
1586        }
1587
1588        anyhow::Ok(())
1589    }
1590
1591    pub fn apply_code_action(
1592        &self,
1593        buffer_handle: Model<Buffer>,
1594        mut action: CodeAction,
1595        push_to_history: bool,
1596        cx: &mut ModelContext<Self>,
1597    ) -> Task<Result<ProjectTransaction>> {
1598        if let Some((upstream_client, project_id)) = self.upstream_client() {
1599            let request = proto::ApplyCodeAction {
1600                project_id,
1601                buffer_id: buffer_handle.read(cx).remote_id().into(),
1602                action: Some(Self::serialize_code_action(&action)),
1603            };
1604            cx.spawn(move |this, cx| async move {
1605                let response = upstream_client
1606                    .request(request)
1607                    .await?
1608                    .transaction
1609                    .ok_or_else(|| anyhow!("missing transaction"))?;
1610                BufferStore::deserialize_project_transaction(
1611                    this.read_with(&cx, |this, _| this.buffer_store.downgrade())?,
1612                    response,
1613                    push_to_history,
1614                    cx,
1615                )
1616                .await
1617            })
1618        } else {
1619            let buffer = buffer_handle.read(cx);
1620            let (lsp_adapter, lang_server) = if let Some((adapter, server)) =
1621                self.language_server_for_buffer(buffer, action.server_id, cx)
1622            {
1623                (adapter.clone(), server.clone())
1624            } else {
1625                return Task::ready(Ok(Default::default()));
1626            };
1627            cx.spawn(move |this, mut cx| async move {
1628                Self::try_resolve_code_action(&lang_server, &mut action)
1629                    .await
1630                    .context("resolving a code action")?;
1631                if let Some(edit) = action.lsp_action.edit {
1632                    if edit.changes.is_some() || edit.document_changes.is_some() {
1633                        return Self::deserialize_workspace_edit(
1634                            this.upgrade().ok_or_else(|| anyhow!("no app present"))?,
1635                            edit,
1636                            push_to_history,
1637                            lsp_adapter.clone(),
1638                            lang_server.clone(),
1639                            &mut cx,
1640                        )
1641                        .await;
1642                    }
1643                }
1644
1645                if let Some(command) = action.lsp_action.command {
1646                    this.update(&mut cx, |this, _| {
1647                        this.as_local_mut()
1648                            .unwrap()
1649                            .last_workspace_edits_by_language_server
1650                            .remove(&lang_server.server_id());
1651                    })?;
1652
1653                    let result = lang_server
1654                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
1655                            command: command.command,
1656                            arguments: command.arguments.unwrap_or_default(),
1657                            ..Default::default()
1658                        })
1659                        .await;
1660
1661                    result?;
1662
1663                    return this.update(&mut cx, |this, _| {
1664                        this.as_local_mut()
1665                            .unwrap()
1666                            .last_workspace_edits_by_language_server
1667                            .remove(&lang_server.server_id())
1668                            .unwrap_or_default()
1669                    });
1670                }
1671
1672                Ok(ProjectTransaction::default())
1673            })
1674        }
1675    }
1676
1677    pub fn resolve_inlay_hint(
1678        &self,
1679        hint: InlayHint,
1680        buffer_handle: Model<Buffer>,
1681        server_id: LanguageServerId,
1682        cx: &mut ModelContext<Self>,
1683    ) -> Task<anyhow::Result<InlayHint>> {
1684        if let Some((upstream_client, project_id)) = self.upstream_client() {
1685            let request = proto::ResolveInlayHint {
1686                project_id,
1687                buffer_id: buffer_handle.read(cx).remote_id().into(),
1688                language_server_id: server_id.0 as u64,
1689                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
1690            };
1691            cx.spawn(move |_, _| async move {
1692                let response = upstream_client
1693                    .request(request)
1694                    .await
1695                    .context("inlay hints proto request")?;
1696                match response.hint {
1697                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
1698                        .context("inlay hints proto resolve response conversion"),
1699                    None => Ok(hint),
1700                }
1701            })
1702        } else {
1703            let buffer = buffer_handle.read(cx);
1704            let (_, lang_server) = if let Some((adapter, server)) =
1705                self.language_server_for_buffer(buffer, server_id, cx)
1706            {
1707                (adapter.clone(), server.clone())
1708            } else {
1709                return Task::ready(Ok(hint));
1710            };
1711            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
1712                return Task::ready(Ok(hint));
1713            }
1714
1715            let buffer_snapshot = buffer.snapshot();
1716            cx.spawn(move |_, mut cx| async move {
1717                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
1718                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
1719                );
1720                let resolved_hint = resolve_task
1721                    .await
1722                    .context("inlay hint resolve LSP request")?;
1723                let resolved_hint = InlayHints::lsp_to_project_hint(
1724                    resolved_hint,
1725                    &buffer_handle,
1726                    server_id,
1727                    ResolveState::Resolved,
1728                    false,
1729                    &mut cx,
1730                )
1731                .await?;
1732                Ok(resolved_hint)
1733            })
1734        }
1735    }
1736
1737    pub(crate) fn linked_edit(
1738        &self,
1739        buffer: &Model<Buffer>,
1740        position: Anchor,
1741        cx: &mut ModelContext<Self>,
1742    ) -> Task<Result<Vec<Range<Anchor>>>> {
1743        let snapshot = buffer.read(cx).snapshot();
1744        let scope = snapshot.language_scope_at(position);
1745        let Some(server_id) = self
1746            .language_servers_for_buffer(buffer.read(cx), cx)
1747            .filter(|(_, server)| {
1748                server
1749                    .capabilities()
1750                    .linked_editing_range_provider
1751                    .is_some()
1752            })
1753            .filter(|(adapter, _)| {
1754                scope
1755                    .as_ref()
1756                    .map(|scope| scope.language_allowed(&adapter.name))
1757                    .unwrap_or(true)
1758            })
1759            .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
1760            .next()
1761            .or_else(|| {
1762                self.upstream_client()
1763                    .is_some()
1764                    .then_some(LanguageServerToQuery::Primary)
1765            })
1766            .filter(|_| {
1767                maybe!({
1768                    let language_name = buffer.read(cx).language_at(position)?.name();
1769                    Some(
1770                        AllLanguageSettings::get_global(cx)
1771                            .language(Some(&language_name))
1772                            .linked_edits,
1773                    )
1774                }) == Some(true)
1775            })
1776        else {
1777            return Task::ready(Ok(vec![]));
1778        };
1779
1780        self.request_lsp(
1781            buffer.clone(),
1782            server_id,
1783            LinkedEditingRange { position },
1784            cx,
1785        )
1786    }
1787
1788    fn apply_on_type_formatting(
1789        &mut self,
1790        buffer: Model<Buffer>,
1791        position: Anchor,
1792        trigger: String,
1793        cx: &mut ModelContext<Self>,
1794    ) -> Task<Result<Option<Transaction>>> {
1795        if let Some((client, project_id)) = self.upstream_client() {
1796            let request = proto::OnTypeFormatting {
1797                project_id,
1798                buffer_id: buffer.read(cx).remote_id().into(),
1799                position: Some(serialize_anchor(&position)),
1800                trigger,
1801                version: serialize_version(&buffer.read(cx).version()),
1802            };
1803            cx.spawn(move |_, _| async move {
1804                client
1805                    .request(request)
1806                    .await?
1807                    .transaction
1808                    .map(language::proto::deserialize_transaction)
1809                    .transpose()
1810            })
1811        } else if let Some(local) = self.as_local_mut() {
1812            let buffer_id = buffer.read(cx).remote_id();
1813            local.buffers_being_formatted.insert(buffer_id);
1814            cx.spawn(move |this, mut cx| async move {
1815                let _cleanup = defer({
1816                    let this = this.clone();
1817                    let mut cx = cx.clone();
1818                    move || {
1819                        this.update(&mut cx, |this, _| {
1820                            if let Some(local) = this.as_local_mut() {
1821                                local.buffers_being_formatted.remove(&buffer_id);
1822                            }
1823                        })
1824                        .ok();
1825                    }
1826                });
1827
1828                buffer
1829                    .update(&mut cx, |buffer, _| {
1830                        buffer.wait_for_edits(Some(position.timestamp))
1831                    })?
1832                    .await?;
1833                this.update(&mut cx, |this, cx| {
1834                    let position = position.to_point_utf16(buffer.read(cx));
1835                    this.on_type_format(buffer, position, trigger, false, cx)
1836                })?
1837                .await
1838            })
1839        } else {
1840            Task::ready(Err(anyhow!("No upstream client or local language server")))
1841        }
1842    }
1843
1844    pub fn on_type_format<T: ToPointUtf16>(
1845        &mut self,
1846        buffer: Model<Buffer>,
1847        position: T,
1848        trigger: String,
1849        push_to_history: bool,
1850        cx: &mut ModelContext<Self>,
1851    ) -> Task<Result<Option<Transaction>>> {
1852        let position = position.to_point_utf16(buffer.read(cx));
1853        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
1854    }
1855
1856    fn on_type_format_impl(
1857        &mut self,
1858        buffer: Model<Buffer>,
1859        position: PointUtf16,
1860        trigger: String,
1861        push_to_history: bool,
1862        cx: &mut ModelContext<Self>,
1863    ) -> Task<Result<Option<Transaction>>> {
1864        let options = buffer.update(cx, |buffer, cx| {
1865            lsp_command::lsp_formatting_options(language_settings(
1866                buffer.language_at(position).as_ref(),
1867                buffer.file(),
1868                cx,
1869            ))
1870        });
1871        self.request_lsp(
1872            buffer.clone(),
1873            LanguageServerToQuery::Primary,
1874            OnTypeFormatting {
1875                position,
1876                trigger,
1877                options,
1878                push_to_history,
1879            },
1880            cx,
1881        )
1882    }
1883
1884    pub async fn format_via_lsp(
1885        this: &WeakModel<Self>,
1886        buffer: &Model<Buffer>,
1887        abs_path: &Path,
1888        language_server: &Arc<LanguageServer>,
1889        settings: &LanguageSettings,
1890        cx: &mut AsyncAppContext,
1891    ) -> Result<Vec<(Range<Anchor>, String)>> {
1892        let uri = lsp::Url::from_file_path(abs_path)
1893            .map_err(|_| anyhow!("failed to convert abs path to uri"))?;
1894        let text_document = lsp::TextDocumentIdentifier::new(uri);
1895        let capabilities = &language_server.capabilities();
1896
1897        let formatting_provider = capabilities.document_formatting_provider.as_ref();
1898        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
1899
1900        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
1901            language_server
1902                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
1903                    text_document,
1904                    options: lsp_command::lsp_formatting_options(settings),
1905                    work_done_progress_params: Default::default(),
1906                })
1907                .await?
1908        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
1909            let buffer_start = lsp::Position::new(0, 0);
1910            let buffer_end = buffer.update(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
1911
1912            language_server
1913                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
1914                    text_document,
1915                    range: lsp::Range::new(buffer_start, buffer_end),
1916                    options: lsp_command::lsp_formatting_options(settings),
1917                    work_done_progress_params: Default::default(),
1918                })
1919                .await?
1920        } else {
1921            None
1922        };
1923
1924        if let Some(lsp_edits) = lsp_edits {
1925            this.update(cx, |this, cx| {
1926                this.edits_from_lsp(buffer, lsp_edits, language_server.server_id(), None, cx)
1927            })?
1928            .await
1929        } else {
1930            Ok(Vec::new())
1931        }
1932    }
1933
1934    pub fn code_actions(
1935        &mut self,
1936        buffer_handle: &Model<Buffer>,
1937        range: Range<Anchor>,
1938        cx: &mut ModelContext<Self>,
1939    ) -> Task<Result<Vec<CodeAction>>> {
1940        if let Some((upstream_client, project_id)) = self.upstream_client() {
1941            let request_task = upstream_client.request(proto::MultiLspQuery {
1942                buffer_id: buffer_handle.read(cx).remote_id().into(),
1943                version: serialize_version(&buffer_handle.read(cx).version()),
1944                project_id,
1945                strategy: Some(proto::multi_lsp_query::Strategy::All(
1946                    proto::AllLanguageServers {},
1947                )),
1948                request: Some(proto::multi_lsp_query::Request::GetCodeActions(
1949                    GetCodeActions {
1950                        range: range.clone(),
1951                        kinds: None,
1952                    }
1953                    .to_proto(project_id, buffer_handle.read(cx)),
1954                )),
1955            });
1956            let buffer = buffer_handle.clone();
1957            cx.spawn(|weak_project, cx| async move {
1958                let Some(project) = weak_project.upgrade() else {
1959                    return Ok(Vec::new());
1960                };
1961                let responses = request_task.await?.responses;
1962                let actions = join_all(
1963                    responses
1964                        .into_iter()
1965                        .filter_map(|lsp_response| match lsp_response.response? {
1966                            proto::lsp_response::Response::GetCodeActionsResponse(response) => {
1967                                Some(response)
1968                            }
1969                            unexpected => {
1970                                debug_panic!("Unexpected response: {unexpected:?}");
1971                                None
1972                            }
1973                        })
1974                        .map(|code_actions_response| {
1975                            GetCodeActions {
1976                                range: range.clone(),
1977                                kinds: None,
1978                            }
1979                            .response_from_proto(
1980                                code_actions_response,
1981                                project.clone(),
1982                                buffer.clone(),
1983                                cx.clone(),
1984                            )
1985                        }),
1986                )
1987                .await;
1988
1989                Ok(actions
1990                    .into_iter()
1991                    .collect::<Result<Vec<Vec<_>>>>()?
1992                    .into_iter()
1993                    .flatten()
1994                    .collect())
1995            })
1996        } else {
1997            let all_actions_task = self.request_multiple_lsp_locally(
1998                buffer_handle,
1999                Some(range.start),
2000                GetCodeActions {
2001                    range: range.clone(),
2002                    kinds: None,
2003                },
2004                cx,
2005            );
2006            cx.spawn(
2007                |_, _| async move { Ok(all_actions_task.await.into_iter().flatten().collect()) },
2008            )
2009        }
2010    }
2011
2012    #[inline(never)]
2013    pub fn completions(
2014        &self,
2015        buffer: &Model<Buffer>,
2016        position: PointUtf16,
2017        context: CompletionContext,
2018        cx: &mut ModelContext<Self>,
2019    ) -> Task<Result<Vec<Completion>>> {
2020        let language_registry = self.languages.clone();
2021
2022        if let Some((upstream_client, project_id)) = self.upstream_client() {
2023            let task = self.send_lsp_proto_request(
2024                buffer.clone(),
2025                upstream_client,
2026                project_id,
2027                GetCompletions { position, context },
2028                cx,
2029            );
2030            let language = buffer.read(cx).language().cloned();
2031
2032            // In the future, we should provide project guests with the names of LSP adapters,
2033            // so that they can use the correct LSP adapter when computing labels. For now,
2034            // guests just use the first LSP adapter associated with the buffer's language.
2035            let lsp_adapter = language.as_ref().and_then(|language| {
2036                language_registry
2037                    .lsp_adapters(&language.name())
2038                    .first()
2039                    .cloned()
2040            });
2041
2042            cx.foreground_executor().spawn(async move {
2043                let completions = task.await?;
2044                let mut result = Vec::new();
2045                populate_labels_for_completions(
2046                    completions,
2047                    &language_registry,
2048                    language,
2049                    lsp_adapter,
2050                    &mut result,
2051                )
2052                .await;
2053                Ok(result)
2054            })
2055        } else {
2056            let snapshot = buffer.read(cx).snapshot();
2057            let offset = position.to_offset(&snapshot);
2058            let scope = snapshot.language_scope_at(offset);
2059            let language = snapshot.language().cloned();
2060
2061            let server_ids: Vec<_> = self
2062                .language_servers_for_buffer(buffer.read(cx), cx)
2063                .filter(|(_, server)| server.capabilities().completion_provider.is_some())
2064                .filter(|(adapter, _)| {
2065                    scope
2066                        .as_ref()
2067                        .map(|scope| scope.language_allowed(&adapter.name))
2068                        .unwrap_or(true)
2069                })
2070                .map(|(_, server)| server.server_id())
2071                .collect();
2072
2073            let buffer = buffer.clone();
2074            cx.spawn(move |this, mut cx| async move {
2075                let mut tasks = Vec::with_capacity(server_ids.len());
2076                this.update(&mut cx, |this, cx| {
2077                    for server_id in server_ids {
2078                        let lsp_adapter = this.language_server_adapter_for_id(server_id);
2079                        tasks.push((
2080                            lsp_adapter,
2081                            this.request_lsp(
2082                                buffer.clone(),
2083                                LanguageServerToQuery::Other(server_id),
2084                                GetCompletions {
2085                                    position,
2086                                    context: context.clone(),
2087                                },
2088                                cx,
2089                            ),
2090                        ));
2091                    }
2092                })?;
2093
2094                let mut completions = Vec::new();
2095                for (lsp_adapter, task) in tasks {
2096                    if let Ok(new_completions) = task.await {
2097                        populate_labels_for_completions(
2098                            new_completions,
2099                            &language_registry,
2100                            language.clone(),
2101                            lsp_adapter,
2102                            &mut completions,
2103                        )
2104                        .await;
2105                    }
2106                }
2107
2108                Ok(completions)
2109            })
2110        }
2111    }
2112
2113    pub fn resolve_completions(
2114        &self,
2115        buffer: Model<Buffer>,
2116        completion_indices: Vec<usize>,
2117        completions: Arc<RwLock<Box<[Completion]>>>,
2118        cx: &mut ModelContext<Self>,
2119    ) -> Task<Result<bool>> {
2120        let client = self.upstream_client();
2121        let language_registry = self.languages.clone();
2122
2123        let buffer_id = buffer.read(cx).remote_id();
2124        let buffer_snapshot = buffer.read(cx).snapshot();
2125
2126        cx.spawn(move |this, cx| async move {
2127            let mut did_resolve = false;
2128            if let Some((client, project_id)) = client {
2129                for completion_index in completion_indices {
2130                    let (server_id, completion) = {
2131                        let completions_guard = completions.read();
2132                        let completion = &completions_guard[completion_index];
2133                        did_resolve = true;
2134                        let server_id = completion.server_id;
2135                        let completion = completion.lsp_completion.clone();
2136
2137                        (server_id, completion)
2138                    };
2139
2140                    Self::resolve_completion_remote(
2141                        project_id,
2142                        server_id,
2143                        buffer_id,
2144                        completions.clone(),
2145                        completion_index,
2146                        completion,
2147                        client.clone(),
2148                        language_registry.clone(),
2149                    )
2150                    .await;
2151                }
2152            } else {
2153                for completion_index in completion_indices {
2154                    let (server_id, completion) = {
2155                        let completions_guard = completions.read();
2156                        let completion = &completions_guard[completion_index];
2157                        let server_id = completion.server_id;
2158                        let completion = completion.lsp_completion.clone();
2159
2160                        (server_id, completion)
2161                    };
2162
2163                    let server = this
2164                        .read_with(&cx, |this, _| this.language_server_for_id(server_id))
2165                        .ok()
2166                        .flatten();
2167                    let Some(server) = server else {
2168                        continue;
2169                    };
2170
2171                    did_resolve = true;
2172                    Self::resolve_completion_local(
2173                        server,
2174                        &buffer_snapshot,
2175                        completions.clone(),
2176                        completion_index,
2177                        completion,
2178                        language_registry.clone(),
2179                    )
2180                    .await;
2181                }
2182            }
2183
2184            Ok(did_resolve)
2185        })
2186    }
2187
2188    async fn resolve_completion_local(
2189        server: Arc<lsp::LanguageServer>,
2190        snapshot: &BufferSnapshot,
2191        completions: Arc<RwLock<Box<[Completion]>>>,
2192        completion_index: usize,
2193        completion: lsp::CompletionItem,
2194        language_registry: Arc<LanguageRegistry>,
2195    ) {
2196        let can_resolve = server
2197            .capabilities()
2198            .completion_provider
2199            .as_ref()
2200            .and_then(|options| options.resolve_provider)
2201            .unwrap_or(false);
2202        if !can_resolve {
2203            return;
2204        }
2205
2206        let request = server.request::<lsp::request::ResolveCompletionItem>(completion);
2207        let Some(completion_item) = request.await.log_err() else {
2208            return;
2209        };
2210
2211        if let Some(lsp_documentation) = completion_item.documentation.as_ref() {
2212            let documentation = language::prepare_completion_documentation(
2213                lsp_documentation,
2214                &language_registry,
2215                None, // TODO: Try to reasonably work out which language the completion is for
2216            )
2217            .await;
2218
2219            let mut completions = completions.write();
2220            let completion = &mut completions[completion_index];
2221            completion.documentation = Some(documentation);
2222        } else {
2223            let mut completions = completions.write();
2224            let completion = &mut completions[completion_index];
2225            completion.documentation = Some(Documentation::Undocumented);
2226        }
2227
2228        if let Some(text_edit) = completion_item.text_edit.as_ref() {
2229            // Technically we don't have to parse the whole `text_edit`, since the only
2230            // language server we currently use that does update `text_edit` in `completionItem/resolve`
2231            // is `typescript-language-server` and they only update `text_edit.new_text`.
2232            // But we should not rely on that.
2233            let edit = parse_completion_text_edit(text_edit, snapshot);
2234
2235            if let Some((old_range, mut new_text)) = edit {
2236                LineEnding::normalize(&mut new_text);
2237
2238                let mut completions = completions.write();
2239                let completion = &mut completions[completion_index];
2240
2241                completion.new_text = new_text;
2242                completion.old_range = old_range;
2243            }
2244        }
2245        if completion_item.insert_text_format == Some(InsertTextFormat::SNIPPET) {
2246            // vtsls might change the type of completion after resolution.
2247            let mut completions = completions.write();
2248            let completion = &mut completions[completion_index];
2249            if completion_item.insert_text_format != completion.lsp_completion.insert_text_format {
2250                completion.lsp_completion.insert_text_format = completion_item.insert_text_format;
2251            }
2252        }
2253
2254        let mut completions = completions.write();
2255        let completion = &mut completions[completion_index];
2256        completion.lsp_completion = completion_item;
2257    }
2258
2259    #[allow(clippy::too_many_arguments)]
2260    async fn resolve_completion_remote(
2261        project_id: u64,
2262        server_id: LanguageServerId,
2263        buffer_id: BufferId,
2264        completions: Arc<RwLock<Box<[Completion]>>>,
2265        completion_index: usize,
2266        completion: lsp::CompletionItem,
2267        client: AnyProtoClient,
2268        language_registry: Arc<LanguageRegistry>,
2269    ) {
2270        let request = proto::ResolveCompletionDocumentation {
2271            project_id,
2272            language_server_id: server_id.0 as u64,
2273            lsp_completion: serde_json::to_string(&completion).unwrap().into_bytes(),
2274            buffer_id: buffer_id.into(),
2275        };
2276
2277        let Some(response) = client
2278            .request(request)
2279            .await
2280            .context("completion documentation resolve proto request")
2281            .log_err()
2282        else {
2283            return;
2284        };
2285        let Some(lsp_completion) = serde_json::from_slice(&response.lsp_completion).log_err()
2286        else {
2287            return;
2288        };
2289
2290        let documentation = if response.documentation.is_empty() {
2291            Documentation::Undocumented
2292        } else if response.documentation_is_markdown {
2293            Documentation::MultiLineMarkdown(
2294                markdown::parse_markdown(&response.documentation, &language_registry, None).await,
2295            )
2296        } else if response.documentation.lines().count() <= 1 {
2297            Documentation::SingleLine(response.documentation)
2298        } else {
2299            Documentation::MultiLinePlainText(response.documentation)
2300        };
2301
2302        let mut completions = completions.write();
2303        let completion = &mut completions[completion_index];
2304        completion.documentation = Some(documentation);
2305        completion.lsp_completion = lsp_completion;
2306
2307        let old_range = response
2308            .old_start
2309            .and_then(deserialize_anchor)
2310            .zip(response.old_end.and_then(deserialize_anchor));
2311        if let Some((old_start, old_end)) = old_range {
2312            if !response.new_text.is_empty() {
2313                completion.new_text = response.new_text;
2314                completion.old_range = old_start..old_end;
2315            }
2316        }
2317    }
2318
2319    pub fn apply_additional_edits_for_completion(
2320        &self,
2321        buffer_handle: Model<Buffer>,
2322        completion: Completion,
2323        push_to_history: bool,
2324        cx: &mut ModelContext<Self>,
2325    ) -> Task<Result<Option<Transaction>>> {
2326        let buffer = buffer_handle.read(cx);
2327        let buffer_id = buffer.remote_id();
2328
2329        if let Some((client, project_id)) = self.upstream_client() {
2330            cx.spawn(move |_, mut cx| async move {
2331                let response = client
2332                    .request(proto::ApplyCompletionAdditionalEdits {
2333                        project_id,
2334                        buffer_id: buffer_id.into(),
2335                        completion: Some(Self::serialize_completion(&CoreCompletion {
2336                            old_range: completion.old_range,
2337                            new_text: completion.new_text,
2338                            server_id: completion.server_id,
2339                            lsp_completion: completion.lsp_completion,
2340                        })),
2341                    })
2342                    .await?;
2343
2344                if let Some(transaction) = response.transaction {
2345                    let transaction = language::proto::deserialize_transaction(transaction)?;
2346                    buffer_handle
2347                        .update(&mut cx, |buffer, _| {
2348                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
2349                        })?
2350                        .await?;
2351                    if push_to_history {
2352                        buffer_handle.update(&mut cx, |buffer, _| {
2353                            buffer.push_transaction(transaction.clone(), Instant::now());
2354                        })?;
2355                    }
2356                    Ok(Some(transaction))
2357                } else {
2358                    Ok(None)
2359                }
2360            })
2361        } else {
2362            let server_id = completion.server_id;
2363            let lang_server = match self.language_server_for_buffer(buffer, server_id, cx) {
2364                Some((_, server)) => server.clone(),
2365                _ => return Task::ready(Ok(Default::default())),
2366            };
2367
2368            cx.spawn(move |this, mut cx| async move {
2369                let can_resolve = lang_server
2370                    .capabilities()
2371                    .completion_provider
2372                    .as_ref()
2373                    .and_then(|options| options.resolve_provider)
2374                    .unwrap_or(false);
2375                let additional_text_edits = if can_resolve {
2376                    lang_server
2377                        .request::<lsp::request::ResolveCompletionItem>(completion.lsp_completion)
2378                        .await?
2379                        .additional_text_edits
2380                } else {
2381                    completion.lsp_completion.additional_text_edits
2382                };
2383                if let Some(edits) = additional_text_edits {
2384                    let edits = this
2385                        .update(&mut cx, |this, cx| {
2386                            this.edits_from_lsp(
2387                                &buffer_handle,
2388                                edits,
2389                                lang_server.server_id(),
2390                                None,
2391                                cx,
2392                            )
2393                        })?
2394                        .await?;
2395
2396                    buffer_handle.update(&mut cx, |buffer, cx| {
2397                        buffer.finalize_last_transaction();
2398                        buffer.start_transaction();
2399
2400                        for (range, text) in edits {
2401                            let primary = &completion.old_range;
2402                            let start_within = primary.start.cmp(&range.start, buffer).is_le()
2403                                && primary.end.cmp(&range.start, buffer).is_ge();
2404                            let end_within = range.start.cmp(&primary.end, buffer).is_le()
2405                                && range.end.cmp(&primary.end, buffer).is_ge();
2406
2407                            //Skip additional edits which overlap with the primary completion edit
2408                            //https://github.com/zed-industries/zed/pull/1871
2409                            if !start_within && !end_within {
2410                                buffer.edit([(range, text)], None, cx);
2411                            }
2412                        }
2413
2414                        let transaction = if buffer.end_transaction(cx).is_some() {
2415                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
2416                            if !push_to_history {
2417                                buffer.forget_transaction(transaction.id);
2418                            }
2419                            Some(transaction)
2420                        } else {
2421                            None
2422                        };
2423                        Ok(transaction)
2424                    })?
2425                } else {
2426                    Ok(None)
2427                }
2428            })
2429        }
2430    }
2431
2432    pub fn inlay_hints(
2433        &mut self,
2434        buffer_handle: Model<Buffer>,
2435        range: Range<Anchor>,
2436        cx: &mut ModelContext<Self>,
2437    ) -> Task<anyhow::Result<Vec<InlayHint>>> {
2438        let buffer = buffer_handle.read(cx);
2439        let range_start = range.start;
2440        let range_end = range.end;
2441        let buffer_id = buffer.remote_id().into();
2442        let lsp_request = InlayHints { range };
2443
2444        if let Some((client, project_id)) = self.upstream_client() {
2445            let request = proto::InlayHints {
2446                project_id,
2447                buffer_id,
2448                start: Some(serialize_anchor(&range_start)),
2449                end: Some(serialize_anchor(&range_end)),
2450                version: serialize_version(&buffer_handle.read(cx).version()),
2451            };
2452            cx.spawn(move |project, cx| async move {
2453                let response = client
2454                    .request(request)
2455                    .await
2456                    .context("inlay hints proto request")?;
2457                LspCommand::response_from_proto(
2458                    lsp_request,
2459                    response,
2460                    project.upgrade().ok_or_else(|| anyhow!("No project"))?,
2461                    buffer_handle.clone(),
2462                    cx.clone(),
2463                )
2464                .await
2465                .context("inlay hints proto response conversion")
2466            })
2467        } else {
2468            let lsp_request_task = self.request_lsp(
2469                buffer_handle.clone(),
2470                LanguageServerToQuery::Primary,
2471                lsp_request,
2472                cx,
2473            );
2474            cx.spawn(move |_, mut cx| async move {
2475                buffer_handle
2476                    .update(&mut cx, |buffer, _| {
2477                        buffer.wait_for_edits(vec![range_start.timestamp, range_end.timestamp])
2478                    })?
2479                    .await
2480                    .context("waiting for inlay hint request range edits")?;
2481                lsp_request_task.await.context("inlay hints LSP request")
2482            })
2483        }
2484    }
2485
2486    pub fn signature_help<T: ToPointUtf16>(
2487        &self,
2488        buffer: &Model<Buffer>,
2489        position: T,
2490        cx: &mut ModelContext<Self>,
2491    ) -> Task<Vec<SignatureHelp>> {
2492        let position = position.to_point_utf16(buffer.read(cx));
2493
2494        if let Some((client, upstream_project_id)) = self.upstream_client() {
2495            let request_task = client.request(proto::MultiLspQuery {
2496                buffer_id: buffer.read(cx).remote_id().into(),
2497                version: serialize_version(&buffer.read(cx).version()),
2498                project_id: upstream_project_id,
2499                strategy: Some(proto::multi_lsp_query::Strategy::All(
2500                    proto::AllLanguageServers {},
2501                )),
2502                request: Some(proto::multi_lsp_query::Request::GetSignatureHelp(
2503                    GetSignatureHelp { position }.to_proto(upstream_project_id, buffer.read(cx)),
2504                )),
2505            });
2506            let buffer = buffer.clone();
2507            cx.spawn(|weak_project, cx| async move {
2508                let Some(project) = weak_project.upgrade() else {
2509                    return Vec::new();
2510                };
2511                join_all(
2512                    request_task
2513                        .await
2514                        .log_err()
2515                        .map(|response| response.responses)
2516                        .unwrap_or_default()
2517                        .into_iter()
2518                        .filter_map(|lsp_response| match lsp_response.response? {
2519                            proto::lsp_response::Response::GetSignatureHelpResponse(response) => {
2520                                Some(response)
2521                            }
2522                            unexpected => {
2523                                debug_panic!("Unexpected response: {unexpected:?}");
2524                                None
2525                            }
2526                        })
2527                        .map(|signature_response| {
2528                            let response = GetSignatureHelp { position }.response_from_proto(
2529                                signature_response,
2530                                project.clone(),
2531                                buffer.clone(),
2532                                cx.clone(),
2533                            );
2534                            async move { response.await.log_err().flatten() }
2535                        }),
2536                )
2537                .await
2538                .into_iter()
2539                .flatten()
2540                .collect()
2541            })
2542        } else {
2543            let all_actions_task = self.request_multiple_lsp_locally(
2544                buffer,
2545                Some(position),
2546                GetSignatureHelp { position },
2547                cx,
2548            );
2549            cx.spawn(|_, _| async move {
2550                all_actions_task
2551                    .await
2552                    .into_iter()
2553                    .flatten()
2554                    .filter(|help| !help.markdown.is_empty())
2555                    .collect::<Vec<_>>()
2556            })
2557        }
2558    }
2559
2560    pub fn hover(
2561        &self,
2562        buffer: &Model<Buffer>,
2563        position: PointUtf16,
2564        cx: &mut ModelContext<Self>,
2565    ) -> Task<Vec<Hover>> {
2566        if let Some((client, upstream_project_id)) = self.upstream_client() {
2567            let request_task = client.request(proto::MultiLspQuery {
2568                buffer_id: buffer.read(cx).remote_id().into(),
2569                version: serialize_version(&buffer.read(cx).version()),
2570                project_id: upstream_project_id,
2571                strategy: Some(proto::multi_lsp_query::Strategy::All(
2572                    proto::AllLanguageServers {},
2573                )),
2574                request: Some(proto::multi_lsp_query::Request::GetHover(
2575                    GetHover { position }.to_proto(upstream_project_id, buffer.read(cx)),
2576                )),
2577            });
2578            let buffer = buffer.clone();
2579            cx.spawn(|weak_project, cx| async move {
2580                let Some(project) = weak_project.upgrade() else {
2581                    return Vec::new();
2582                };
2583                join_all(
2584                    request_task
2585                        .await
2586                        .log_err()
2587                        .map(|response| response.responses)
2588                        .unwrap_or_default()
2589                        .into_iter()
2590                        .filter_map(|lsp_response| match lsp_response.response? {
2591                            proto::lsp_response::Response::GetHoverResponse(response) => {
2592                                Some(response)
2593                            }
2594                            unexpected => {
2595                                debug_panic!("Unexpected response: {unexpected:?}");
2596                                None
2597                            }
2598                        })
2599                        .map(|hover_response| {
2600                            let response = GetHover { position }.response_from_proto(
2601                                hover_response,
2602                                project.clone(),
2603                                buffer.clone(),
2604                                cx.clone(),
2605                            );
2606                            async move {
2607                                response
2608                                    .await
2609                                    .log_err()
2610                                    .flatten()
2611                                    .and_then(remove_empty_hover_blocks)
2612                            }
2613                        }),
2614                )
2615                .await
2616                .into_iter()
2617                .flatten()
2618                .collect()
2619            })
2620        } else {
2621            let all_actions_task = self.request_multiple_lsp_locally(
2622                buffer,
2623                Some(position),
2624                GetHover { position },
2625                cx,
2626            );
2627            cx.spawn(|_, _| async move {
2628                all_actions_task
2629                    .await
2630                    .into_iter()
2631                    .filter_map(|hover| remove_empty_hover_blocks(hover?))
2632                    .collect::<Vec<Hover>>()
2633            })
2634        }
2635    }
2636
2637    pub fn symbols(&self, query: &str, cx: &mut ModelContext<Self>) -> Task<Result<Vec<Symbol>>> {
2638        let language_registry = self.languages.clone();
2639
2640        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
2641            let request = upstream_client.request(proto::GetProjectSymbols {
2642                project_id: *project_id,
2643                query: query.to_string(),
2644            });
2645            cx.foreground_executor().spawn(async move {
2646                let response = request.await?;
2647                let mut symbols = Vec::new();
2648                let core_symbols = response
2649                    .symbols
2650                    .into_iter()
2651                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
2652                    .collect::<Vec<_>>();
2653                populate_labels_for_symbols(
2654                    core_symbols,
2655                    &language_registry,
2656                    None,
2657                    None,
2658                    &mut symbols,
2659                )
2660                .await;
2661                Ok(symbols)
2662            })
2663        } else {
2664            struct WorkspaceSymbolsResult {
2665                lsp_adapter: Arc<CachedLspAdapter>,
2666                language: LanguageName,
2667                worktree: WeakModel<Worktree>,
2668                worktree_abs_path: Arc<Path>,
2669                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
2670            }
2671
2672            let mut requests = Vec::new();
2673            for ((worktree_id, _), server_id) in self.language_server_ids.iter() {
2674                let Some(worktree_handle) = self
2675                    .worktree_store
2676                    .read(cx)
2677                    .worktree_for_id(*worktree_id, cx)
2678                else {
2679                    continue;
2680                };
2681                let worktree = worktree_handle.read(cx);
2682                if !worktree.is_visible() {
2683                    continue;
2684                }
2685                let worktree_abs_path = worktree.abs_path().clone();
2686
2687                let (lsp_adapter, language, server) =
2688                    match self.as_local().unwrap().language_servers.get(server_id) {
2689                        Some(LanguageServerState::Running {
2690                            adapter,
2691                            language,
2692                            server,
2693                            ..
2694                        }) => (adapter.clone(), language.clone(), server),
2695
2696                        _ => continue,
2697                    };
2698
2699                requests.push(
2700                    server
2701                        .request::<lsp::request::WorkspaceSymbolRequest>(
2702                            lsp::WorkspaceSymbolParams {
2703                                query: query.to_string(),
2704                                ..Default::default()
2705                            },
2706                        )
2707                        .log_err()
2708                        .map(move |response| {
2709                            let lsp_symbols = response.flatten().map(|symbol_response| match symbol_response {
2710                                lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
2711                                    flat_responses.into_iter().map(|lsp_symbol| {
2712                                        (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
2713                                    }).collect::<Vec<_>>()
2714                                }
2715                                lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
2716                                    nested_responses.into_iter().filter_map(|lsp_symbol| {
2717                                        let location = match lsp_symbol.location {
2718                                            OneOf::Left(location) => location,
2719                                            OneOf::Right(_) => {
2720                                                log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
2721                                                return None
2722                                            }
2723                                        };
2724                                        Some((lsp_symbol.name, lsp_symbol.kind, location))
2725                                    }).collect::<Vec<_>>()
2726                                }
2727                            }).unwrap_or_default();
2728
2729                            WorkspaceSymbolsResult {
2730                                lsp_adapter,
2731                                language,
2732                                worktree: worktree_handle.downgrade(),
2733                                worktree_abs_path,
2734                                lsp_symbols,
2735                            }
2736                        }),
2737                );
2738            }
2739
2740            cx.spawn(move |this, mut cx| async move {
2741                let responses = futures::future::join_all(requests).await;
2742                let this = match this.upgrade() {
2743                    Some(this) => this,
2744                    None => return Ok(Vec::new()),
2745                };
2746
2747                let mut symbols = Vec::new();
2748                for result in responses {
2749                    let core_symbols = this.update(&mut cx, |this, cx| {
2750                        result
2751                            .lsp_symbols
2752                            .into_iter()
2753                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
2754                                let abs_path = symbol_location.uri.to_file_path().ok()?;
2755                                let source_worktree = result.worktree.upgrade()?;
2756                                let source_worktree_id = source_worktree.read(cx).id();
2757
2758                                let path;
2759                                let worktree;
2760                                if let Some((tree, rel_path)) =
2761                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
2762                                {
2763                                    worktree = tree;
2764                                    path = rel_path;
2765                                } else {
2766                                    worktree = source_worktree.clone();
2767                                    path = relativize_path(&result.worktree_abs_path, &abs_path);
2768                                }
2769
2770                                let worktree_id = worktree.read(cx).id();
2771                                let project_path = ProjectPath {
2772                                    worktree_id,
2773                                    path: path.into(),
2774                                };
2775                                let signature = this.symbol_signature(&project_path);
2776                                Some(CoreSymbol {
2777                                    language_server_name: result.lsp_adapter.name.clone(),
2778                                    source_worktree_id,
2779                                    path: project_path,
2780                                    kind: symbol_kind,
2781                                    name: symbol_name,
2782                                    range: range_from_lsp(symbol_location.range),
2783                                    signature,
2784                                })
2785                            })
2786                            .collect()
2787                    })?;
2788
2789                    populate_labels_for_symbols(
2790                        core_symbols,
2791                        &language_registry,
2792                        Some(result.language),
2793                        Some(result.lsp_adapter),
2794                        &mut symbols,
2795                    )
2796                    .await;
2797                }
2798
2799                Ok(symbols)
2800            })
2801        }
2802    }
2803
2804    pub fn diagnostic_summaries<'a>(
2805        &'a self,
2806        include_ignored: bool,
2807        cx: &'a AppContext,
2808    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
2809        self.worktree_store
2810            .read(cx)
2811            .visible_worktrees(cx)
2812            .filter_map(|worktree| {
2813                let worktree = worktree.read(cx);
2814                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
2815            })
2816            .flat_map(move |(worktree, summaries)| {
2817                let worktree_id = worktree.id();
2818                summaries
2819                    .iter()
2820                    .filter(move |(path, _)| {
2821                        include_ignored
2822                            || worktree
2823                                .entry_for_path(path.as_ref())
2824                                .map_or(false, |entry| !entry.is_ignored)
2825                    })
2826                    .flat_map(move |(path, summaries)| {
2827                        summaries.iter().map(move |(server_id, summary)| {
2828                            (
2829                                ProjectPath {
2830                                    worktree_id,
2831                                    path: path.clone(),
2832                                },
2833                                *server_id,
2834                                *summary,
2835                            )
2836                        })
2837                    })
2838            })
2839    }
2840
2841    pub fn started_language_servers(&self) -> Vec<(WorktreeId, LanguageServerName)> {
2842        self.language_server_ids.keys().cloned().collect()
2843    }
2844
2845    pub fn on_buffer_edited(
2846        &mut self,
2847        buffer: Model<Buffer>,
2848        cx: &mut ModelContext<Self>,
2849    ) -> Option<()> {
2850        let buffer = buffer.read(cx);
2851        let file = File::from_dyn(buffer.file())?;
2852        let abs_path = file.as_local()?.abs_path(cx);
2853        let uri = lsp::Url::from_file_path(abs_path).unwrap();
2854        let next_snapshot = buffer.text_snapshot();
2855
2856        let language_servers: Vec<_> = self
2857            .language_servers_for_buffer(buffer, cx)
2858            .map(|i| i.1.clone())
2859            .collect();
2860
2861        for language_server in language_servers {
2862            let language_server = language_server.clone();
2863
2864            let buffer_snapshots = self
2865                .buffer_snapshots
2866                .get_mut(&buffer.remote_id())
2867                .and_then(|m| m.get_mut(&language_server.server_id()))?;
2868            let previous_snapshot = buffer_snapshots.last()?;
2869
2870            let build_incremental_change = || {
2871                buffer
2872                    .edits_since::<(PointUtf16, usize)>(previous_snapshot.snapshot.version())
2873                    .map(|edit| {
2874                        let edit_start = edit.new.start.0;
2875                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
2876                        let new_text = next_snapshot
2877                            .text_for_range(edit.new.start.1..edit.new.end.1)
2878                            .collect();
2879                        lsp::TextDocumentContentChangeEvent {
2880                            range: Some(lsp::Range::new(
2881                                point_to_lsp(edit_start),
2882                                point_to_lsp(edit_end),
2883                            )),
2884                            range_length: None,
2885                            text: new_text,
2886                        }
2887                    })
2888                    .collect()
2889            };
2890
2891            let document_sync_kind = language_server
2892                .capabilities()
2893                .text_document_sync
2894                .as_ref()
2895                .and_then(|sync| match sync {
2896                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
2897                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
2898                });
2899
2900            let content_changes: Vec<_> = match document_sync_kind {
2901                Some(lsp::TextDocumentSyncKind::FULL) => {
2902                    vec![lsp::TextDocumentContentChangeEvent {
2903                        range: None,
2904                        range_length: None,
2905                        text: next_snapshot.text(),
2906                    }]
2907                }
2908                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
2909                _ => {
2910                    #[cfg(any(test, feature = "test-support"))]
2911                    {
2912                        build_incremental_change()
2913                    }
2914
2915                    #[cfg(not(any(test, feature = "test-support")))]
2916                    {
2917                        continue;
2918                    }
2919                }
2920            };
2921
2922            let next_version = previous_snapshot.version + 1;
2923            buffer_snapshots.push(LspBufferSnapshot {
2924                version: next_version,
2925                snapshot: next_snapshot.clone(),
2926            });
2927
2928            language_server
2929                .notify::<lsp::notification::DidChangeTextDocument>(
2930                    lsp::DidChangeTextDocumentParams {
2931                        text_document: lsp::VersionedTextDocumentIdentifier::new(
2932                            uri.clone(),
2933                            next_version,
2934                        ),
2935                        content_changes,
2936                    },
2937                )
2938                .log_err();
2939        }
2940
2941        None
2942    }
2943
2944    pub fn on_buffer_saved(
2945        &mut self,
2946        buffer: Model<Buffer>,
2947        cx: &mut ModelContext<Self>,
2948    ) -> Option<()> {
2949        let file = File::from_dyn(buffer.read(cx).file())?;
2950        let worktree_id = file.worktree_id(cx);
2951        let abs_path = file.as_local()?.abs_path(cx);
2952        let text_document = lsp::TextDocumentIdentifier {
2953            uri: lsp::Url::from_file_path(abs_path).log_err()?,
2954        };
2955
2956        for server in self.language_servers_for_worktree(worktree_id) {
2957            if let Some(include_text) = include_text(server.as_ref()) {
2958                let text = if include_text {
2959                    Some(buffer.read(cx).text())
2960                } else {
2961                    None
2962                };
2963                server
2964                    .notify::<lsp::notification::DidSaveTextDocument>(
2965                        lsp::DidSaveTextDocumentParams {
2966                            text_document: text_document.clone(),
2967                            text,
2968                        },
2969                    )
2970                    .log_err();
2971            }
2972        }
2973
2974        for language_server_id in self.language_server_ids_for_buffer(buffer.read(cx), cx) {
2975            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
2976        }
2977
2978        None
2979    }
2980
2981    fn maintain_workspace_config(cx: &mut ModelContext<Self>) -> Task<Result<()>> {
2982        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
2983        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
2984
2985        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
2986            *settings_changed_tx.borrow_mut() = ();
2987        });
2988
2989        cx.spawn(move |this, mut cx| async move {
2990            while let Some(()) = settings_changed_rx.next().await {
2991                let servers = this.update(&mut cx, |this, cx| {
2992                    this.language_server_ids
2993                        .iter()
2994                        .filter_map(|((worktree_id, _), server_id)| {
2995                            let worktree = this
2996                                .worktree_store
2997                                .read(cx)
2998                                .worktree_for_id(*worktree_id, cx)?;
2999                            let state = this.as_local()?.language_servers.get(server_id)?;
3000                            let delegate = LocalLspAdapterDelegate::for_local(this, &worktree, cx);
3001                            match state {
3002                                LanguageServerState::Starting(_) => None,
3003                                LanguageServerState::Running {
3004                                    adapter, server, ..
3005                                } => Some((
3006                                    adapter.adapter.clone(),
3007                                    server.clone(),
3008                                    delegate as Arc<dyn LspAdapterDelegate>,
3009                                )),
3010                            }
3011                        })
3012                        .collect::<Vec<_>>()
3013                })?;
3014
3015                for (adapter, server, delegate) in servers {
3016                    let settings = adapter.workspace_configuration(&delegate, &mut cx).await?;
3017
3018                    server
3019                        .notify::<lsp::notification::DidChangeConfiguration>(
3020                            lsp::DidChangeConfigurationParams { settings },
3021                        )
3022                        .ok();
3023                }
3024            }
3025
3026            drop(settings_observation);
3027            anyhow::Ok(())
3028        })
3029    }
3030
3031    pub fn primary_language_server_for_buffer<'a>(
3032        &'a self,
3033        buffer: &'a Buffer,
3034        cx: &'a AppContext,
3035    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
3036        // The list of language servers is ordered based on the `language_servers` setting
3037        // for each language, thus we can consider the first one in the list to be the
3038        // primary one.
3039        self.language_servers_for_buffer(buffer, cx).next()
3040    }
3041
3042    pub fn language_server_for_buffer<'a>(
3043        &'a self,
3044        buffer: &'a Buffer,
3045        server_id: LanguageServerId,
3046        cx: &'a AppContext,
3047    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
3048        self.language_servers_for_buffer(buffer, cx)
3049            .find(|(_, s)| s.server_id() == server_id)
3050    }
3051
3052    fn language_servers_for_worktree(
3053        &self,
3054        worktree_id: WorktreeId,
3055    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
3056        self.language_server_ids
3057            .iter()
3058            .filter_map(move |((language_server_worktree_id, _), id)| {
3059                if *language_server_worktree_id == worktree_id {
3060                    if let Some(LanguageServerState::Running { server, .. }) =
3061                        self.as_local()?.language_servers.get(id)
3062                    {
3063                        return Some(server);
3064                    }
3065                }
3066                None
3067            })
3068    }
3069
3070    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut ModelContext<Self>) {
3071        self.diagnostics.remove(&id_to_remove);
3072        self.diagnostic_summaries.remove(&id_to_remove);
3073
3074        let mut servers_to_remove = HashMap::default();
3075        let mut servers_to_preserve = HashSet::default();
3076        for ((worktree_id, server_name), &server_id) in &self.language_server_ids {
3077            if worktree_id == &id_to_remove {
3078                servers_to_remove.insert(server_id, server_name.clone());
3079            } else {
3080                servers_to_preserve.insert(server_id);
3081            }
3082        }
3083        servers_to_remove.retain(|server_id, _| !servers_to_preserve.contains(server_id));
3084        for (server_id_to_remove, server_name) in servers_to_remove {
3085            self.language_server_ids
3086                .remove(&(id_to_remove, server_name));
3087            self.language_server_statuses.remove(&server_id_to_remove);
3088            if let Some(local_lsp_store) = self.as_local_mut() {
3089                local_lsp_store
3090                    .language_server_watched_paths
3091                    .remove(&server_id_to_remove);
3092                local_lsp_store
3093                    .last_workspace_edits_by_language_server
3094                    .remove(&server_id_to_remove);
3095                local_lsp_store
3096                    .language_servers
3097                    .remove(&server_id_to_remove);
3098            }
3099            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id_to_remove));
3100        }
3101
3102        if let Some(local) = self.as_local() {
3103            local.prettier_store.update(cx, |prettier_store, cx| {
3104                prettier_store.remove_worktree(id_to_remove, cx);
3105            })
3106        }
3107    }
3108
3109    pub fn shared(
3110        &mut self,
3111        project_id: u64,
3112        downstream_client: AnyProtoClient,
3113        _: &mut ModelContext<Self>,
3114    ) {
3115        self.downstream_client = Some((downstream_client.clone(), project_id));
3116
3117        for (server_id, status) in &self.language_server_statuses {
3118            downstream_client
3119                .send(proto::StartLanguageServer {
3120                    project_id,
3121                    server: Some(proto::LanguageServer {
3122                        id: server_id.0 as u64,
3123                        name: status.name.clone(),
3124                    }),
3125                })
3126                .log_err();
3127        }
3128    }
3129
3130    pub fn disconnected_from_host(&mut self) {
3131        self.downstream_client.take();
3132    }
3133
3134    pub(crate) fn set_language_server_statuses_from_proto(
3135        &mut self,
3136        language_servers: Vec<proto::LanguageServer>,
3137    ) {
3138        self.language_server_statuses = language_servers
3139            .into_iter()
3140            .map(|server| {
3141                (
3142                    LanguageServerId(server.id as usize),
3143                    LanguageServerStatus {
3144                        name: server.name,
3145                        pending_work: Default::default(),
3146                        has_pending_diagnostic_updates: false,
3147                        progress_tokens: Default::default(),
3148                    },
3149                )
3150            })
3151            .collect();
3152    }
3153
3154    pub(crate) fn register_language_server(
3155        &mut self,
3156        worktree_id: WorktreeId,
3157        language_server_name: LanguageServerName,
3158        language_server_id: LanguageServerId,
3159    ) {
3160        self.language_server_ids
3161            .insert((worktree_id, language_server_name), language_server_id);
3162    }
3163
3164    #[track_caller]
3165    pub(crate) fn register_buffer_with_language_servers(
3166        &mut self,
3167        buffer_handle: &Model<Buffer>,
3168        cx: &mut ModelContext<Self>,
3169    ) {
3170        let available_language = self.detect_language_for_buffer(buffer_handle, cx);
3171
3172        let buffer = buffer_handle.read(cx);
3173        let buffer_id = buffer.remote_id();
3174
3175        if let Some(file) = File::from_dyn(buffer.file()) {
3176            if !file.is_local() {
3177                return;
3178            }
3179
3180            let abs_path = file.abs_path(cx);
3181            let Some(uri) = lsp::Url::from_file_path(&abs_path).log_err() else {
3182                return;
3183            };
3184            let initial_snapshot = buffer.text_snapshot();
3185            let worktree_id = file.worktree_id(cx);
3186
3187            if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
3188                for (server_id, diagnostics) in
3189                    diagnostics.get(file.path()).cloned().unwrap_or_default()
3190                {
3191                    self.update_buffer_diagnostics(buffer_handle, server_id, None, diagnostics, cx)
3192                        .log_err();
3193                }
3194            }
3195
3196            if let Some(language) = available_language {
3197                for adapter in self.languages.lsp_adapters(&language.name()) {
3198                    let server = self
3199                        .language_server_ids
3200                        .get(&(worktree_id, adapter.name.clone()))
3201                        .and_then(|id| self.as_local()?.language_servers.get(id))
3202                        .and_then(|server_state| {
3203                            if let LanguageServerState::Running { server, .. } = server_state {
3204                                Some(server.clone())
3205                            } else {
3206                                None
3207                            }
3208                        });
3209                    let server = match server {
3210                        Some(server) => server,
3211                        None => continue,
3212                    };
3213
3214                    server
3215                        .notify::<lsp::notification::DidOpenTextDocument>(
3216                            lsp::DidOpenTextDocumentParams {
3217                                text_document: lsp::TextDocumentItem::new(
3218                                    uri.clone(),
3219                                    adapter.language_id(&language.name()),
3220                                    0,
3221                                    initial_snapshot.text(),
3222                                ),
3223                            },
3224                        )
3225                        .log_err();
3226
3227                    buffer_handle.update(cx, |buffer, cx| {
3228                        buffer.set_completion_triggers(
3229                            server
3230                                .capabilities()
3231                                .completion_provider
3232                                .as_ref()
3233                                .and_then(|provider| provider.trigger_characters.clone())
3234                                .unwrap_or_default(),
3235                            cx,
3236                        );
3237                    });
3238
3239                    let snapshot = LspBufferSnapshot {
3240                        version: 0,
3241                        snapshot: initial_snapshot.clone(),
3242                    };
3243                    self.buffer_snapshots
3244                        .entry(buffer_id)
3245                        .or_default()
3246                        .insert(server.server_id(), vec![snapshot]);
3247                }
3248            }
3249        }
3250    }
3251
3252    pub(crate) fn unregister_buffer_from_language_servers(
3253        &mut self,
3254        buffer: &Model<Buffer>,
3255        old_file: &File,
3256        cx: &mut AppContext,
3257    ) {
3258        let old_path = match old_file.as_local() {
3259            Some(local) => local.abs_path(cx),
3260            None => return,
3261        };
3262
3263        buffer.update(cx, |buffer, cx| {
3264            let worktree_id = old_file.worktree_id(cx);
3265
3266            let ids = &self.language_server_ids;
3267
3268            if let Some(language) = buffer.language().cloned() {
3269                for adapter in self.languages.lsp_adapters(&language.name()) {
3270                    if let Some(server_id) = ids.get(&(worktree_id, adapter.name.clone())) {
3271                        buffer.update_diagnostics(*server_id, DiagnosticSet::new([], buffer), cx);
3272                    }
3273                }
3274            }
3275
3276            self.buffer_snapshots.remove(&buffer.remote_id());
3277            let file_url = lsp::Url::from_file_path(old_path).unwrap();
3278            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
3279                language_server
3280                    .notify::<lsp::notification::DidCloseTextDocument>(
3281                        lsp::DidCloseTextDocumentParams {
3282                            text_document: lsp::TextDocumentIdentifier::new(file_url.clone()),
3283                        },
3284                    )
3285                    .log_err();
3286            }
3287        });
3288    }
3289
3290    pub fn update_diagnostic_entries(
3291        &mut self,
3292        server_id: LanguageServerId,
3293        abs_path: PathBuf,
3294        version: Option<i32>,
3295        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
3296        cx: &mut ModelContext<Self>,
3297    ) -> Result<(), anyhow::Error> {
3298        let (worktree, relative_path) =
3299            self.worktree_store
3300                .read(cx)
3301                .find_worktree(&abs_path, cx)
3302                .ok_or_else(|| anyhow!("no worktree found for diagnostics path {abs_path:?}"))?;
3303
3304        let project_path = ProjectPath {
3305            worktree_id: worktree.read(cx).id(),
3306            path: relative_path.into(),
3307        };
3308
3309        if let Some(buffer) = self.buffer_store.read(cx).get_by_path(&project_path, cx) {
3310            self.update_buffer_diagnostics(&buffer, server_id, version, diagnostics.clone(), cx)?;
3311        }
3312
3313        let updated = worktree.update(cx, |worktree, cx| {
3314            self.update_worktree_diagnostics(
3315                worktree.id(),
3316                server_id,
3317                project_path.path.clone(),
3318                diagnostics,
3319                cx,
3320            )
3321        })?;
3322        if updated {
3323            cx.emit(LspStoreEvent::DiagnosticsUpdated {
3324                language_server_id: server_id,
3325                path: project_path,
3326            })
3327        }
3328        Ok(())
3329    }
3330
3331    pub fn update_worktree_diagnostics(
3332        &mut self,
3333        worktree_id: WorktreeId,
3334        server_id: LanguageServerId,
3335        worktree_path: Arc<Path>,
3336        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
3337        _: &mut ModelContext<Worktree>,
3338    ) -> Result<bool> {
3339        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
3340        let diagnostics_for_tree = self.diagnostics.entry(worktree_id).or_default();
3341        let summaries_by_server_id = summaries_for_tree.entry(worktree_path.clone()).or_default();
3342
3343        let old_summary = summaries_by_server_id
3344            .remove(&server_id)
3345            .unwrap_or_default();
3346
3347        let new_summary = DiagnosticSummary::new(&diagnostics);
3348        if new_summary.is_empty() {
3349            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&worktree_path) {
3350                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
3351                    diagnostics_by_server_id.remove(ix);
3352                }
3353                if diagnostics_by_server_id.is_empty() {
3354                    diagnostics_for_tree.remove(&worktree_path);
3355                }
3356            }
3357        } else {
3358            summaries_by_server_id.insert(server_id, new_summary);
3359            let diagnostics_by_server_id = diagnostics_for_tree
3360                .entry(worktree_path.clone())
3361                .or_default();
3362            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
3363                Ok(ix) => {
3364                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
3365                }
3366                Err(ix) => {
3367                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
3368                }
3369            }
3370        }
3371
3372        if !old_summary.is_empty() || !new_summary.is_empty() {
3373            if let Some((downstream_client, project_id)) = &self.downstream_client {
3374                downstream_client
3375                    .send(proto::UpdateDiagnosticSummary {
3376                        project_id: *project_id,
3377                        worktree_id: worktree_id.to_proto(),
3378                        summary: Some(proto::DiagnosticSummary {
3379                            path: worktree_path.to_string_lossy().to_string(),
3380                            language_server_id: server_id.0 as u64,
3381                            error_count: new_summary.error_count as u32,
3382                            warning_count: new_summary.warning_count as u32,
3383                        }),
3384                    })
3385                    .log_err();
3386            }
3387        }
3388
3389        Ok(!old_summary.is_empty() || !new_summary.is_empty())
3390    }
3391
3392    pub fn open_buffer_for_symbol(
3393        &mut self,
3394        symbol: &Symbol,
3395        cx: &mut ModelContext<Self>,
3396    ) -> Task<Result<Model<Buffer>>> {
3397        if let Some((client, project_id)) = self.upstream_client() {
3398            let request = client.request(proto::OpenBufferForSymbol {
3399                project_id,
3400                symbol: Some(Self::serialize_symbol(symbol)),
3401            });
3402            cx.spawn(move |this, mut cx| async move {
3403                let response = request.await?;
3404                let buffer_id = BufferId::new(response.buffer_id)?;
3405                this.update(&mut cx, |this, cx| {
3406                    this.wait_for_remote_buffer(buffer_id, cx)
3407                })?
3408                .await
3409            })
3410        } else {
3411            let Some(&language_server_id) = self.language_server_ids.get(&(
3412                symbol.source_worktree_id,
3413                symbol.language_server_name.clone(),
3414            )) else {
3415                return Task::ready(Err(anyhow!(
3416                    "language server for worktree and language not found"
3417                )));
3418            };
3419
3420            let worktree_abs_path = if let Some(worktree_abs_path) = self
3421                .worktree_store
3422                .read(cx)
3423                .worktree_for_id(symbol.path.worktree_id, cx)
3424                .map(|worktree| worktree.read(cx).abs_path())
3425            {
3426                worktree_abs_path
3427            } else {
3428                return Task::ready(Err(anyhow!("worktree not found for symbol")));
3429            };
3430
3431            let symbol_abs_path = resolve_path(&worktree_abs_path, &symbol.path.path);
3432            let symbol_uri = if let Ok(uri) = lsp::Url::from_file_path(symbol_abs_path) {
3433                uri
3434            } else {
3435                return Task::ready(Err(anyhow!("invalid symbol path")));
3436            };
3437
3438            self.open_local_buffer_via_lsp(
3439                symbol_uri,
3440                language_server_id,
3441                symbol.language_server_name.clone(),
3442                cx,
3443            )
3444        }
3445    }
3446
3447    pub fn open_local_buffer_via_lsp(
3448        &mut self,
3449        mut abs_path: lsp::Url,
3450        language_server_id: LanguageServerId,
3451        language_server_name: LanguageServerName,
3452        cx: &mut ModelContext<Self>,
3453    ) -> Task<Result<Model<Buffer>>> {
3454        cx.spawn(move |this, mut cx| async move {
3455            // Escape percent-encoded string.
3456            let current_scheme = abs_path.scheme().to_owned();
3457            let _ = abs_path.set_scheme("file");
3458
3459            let abs_path = abs_path
3460                .to_file_path()
3461                .map_err(|_| anyhow!("can't convert URI to path"))?;
3462            let p = abs_path.clone();
3463            let yarn_worktree = this
3464                .update(&mut cx, move |this, cx| {
3465                    this.as_local().unwrap().yarn.update(cx, |_, cx| {
3466                        cx.spawn(|this, mut cx| async move {
3467                            let t = this
3468                                .update(&mut cx, |this, cx| {
3469                                    this.process_path(&p, &current_scheme, cx)
3470                                })
3471                                .ok()?;
3472                            t.await
3473                        })
3474                    })
3475                })?
3476                .await;
3477            let (worktree_root_target, known_relative_path) =
3478                if let Some((zip_root, relative_path)) = yarn_worktree {
3479                    (zip_root, Some(relative_path))
3480                } else {
3481                    (Arc::<Path>::from(abs_path.as_path()), None)
3482                };
3483            let (worktree, relative_path) = if let Some(result) =
3484                this.update(&mut cx, |this, cx| {
3485                    this.worktree_store.update(cx, |worktree_store, cx| {
3486                        worktree_store.find_worktree(&worktree_root_target, cx)
3487                    })
3488                })? {
3489                let relative_path =
3490                    known_relative_path.unwrap_or_else(|| Arc::<Path>::from(result.1));
3491                (result.0, relative_path)
3492            } else {
3493                let worktree = this
3494                    .update(&mut cx, |this, cx| {
3495                        this.worktree_store.update(cx, |worktree_store, cx| {
3496                            worktree_store.create_worktree(&worktree_root_target, false, cx)
3497                        })
3498                    })?
3499                    .await?;
3500                this.update(&mut cx, |this, cx| {
3501                    this.register_language_server(
3502                        worktree.read(cx).id(),
3503                        language_server_name,
3504                        language_server_id,
3505                    )
3506                })
3507                .ok();
3508                let worktree_root = worktree.update(&mut cx, |this, _| this.abs_path())?;
3509                let relative_path = if let Some(known_path) = known_relative_path {
3510                    known_path
3511                } else {
3512                    abs_path.strip_prefix(worktree_root)?.into()
3513                };
3514                (worktree, relative_path)
3515            };
3516            let project_path = ProjectPath {
3517                worktree_id: worktree.update(&mut cx, |worktree, _| worktree.id())?,
3518                path: relative_path,
3519            };
3520            this.update(&mut cx, |this, cx| {
3521                this.buffer_store().update(cx, |buffer_store, cx| {
3522                    buffer_store.open_buffer(project_path, cx)
3523                })
3524            })?
3525            .await
3526        })
3527    }
3528
3529    pub(crate) fn update_buffer_diagnostics(
3530        &mut self,
3531        buffer: &Model<Buffer>,
3532        server_id: LanguageServerId,
3533        version: Option<i32>,
3534        mut diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
3535        cx: &mut ModelContext<Self>,
3536    ) -> Result<()> {
3537        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
3538            Ordering::Equal
3539                .then_with(|| b.is_primary.cmp(&a.is_primary))
3540                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
3541                .then_with(|| a.severity.cmp(&b.severity))
3542                .then_with(|| a.message.cmp(&b.message))
3543        }
3544
3545        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
3546
3547        diagnostics.sort_unstable_by(|a, b| {
3548            Ordering::Equal
3549                .then_with(|| a.range.start.cmp(&b.range.start))
3550                .then_with(|| b.range.end.cmp(&a.range.end))
3551                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
3552        });
3553
3554        let mut sanitized_diagnostics = Vec::new();
3555        let edits_since_save = Patch::new(
3556            snapshot
3557                .edits_since::<Unclipped<PointUtf16>>(buffer.read(cx).saved_version())
3558                .collect(),
3559        );
3560        for entry in diagnostics {
3561            let start;
3562            let end;
3563            if entry.diagnostic.is_disk_based {
3564                // Some diagnostics are based on files on disk instead of buffers'
3565                // current contents. Adjust these diagnostics' ranges to reflect
3566                // any unsaved edits.
3567                start = edits_since_save.old_to_new(entry.range.start);
3568                end = edits_since_save.old_to_new(entry.range.end);
3569            } else {
3570                start = entry.range.start;
3571                end = entry.range.end;
3572            }
3573
3574            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
3575                ..snapshot.clip_point_utf16(end, Bias::Right);
3576
3577            // Expand empty ranges by one codepoint
3578            if range.start == range.end {
3579                // This will be go to the next boundary when being clipped
3580                range.end.column += 1;
3581                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
3582                if range.start == range.end && range.end.column > 0 {
3583                    range.start.column -= 1;
3584                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
3585                }
3586            }
3587
3588            sanitized_diagnostics.push(DiagnosticEntry {
3589                range,
3590                diagnostic: entry.diagnostic,
3591            });
3592        }
3593        drop(edits_since_save);
3594
3595        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
3596        buffer.update(cx, |buffer, cx| {
3597            buffer.update_diagnostics(server_id, set, cx)
3598        });
3599        Ok(())
3600    }
3601
3602    fn request_multiple_lsp_locally<P, R>(
3603        &self,
3604        buffer: &Model<Buffer>,
3605        position: Option<P>,
3606        request: R,
3607        cx: &mut ModelContext<'_, Self>,
3608    ) -> Task<Vec<R::Response>>
3609    where
3610        P: ToOffset,
3611        R: LspCommand + Clone,
3612        <R::LspRequest as lsp::request::Request>::Result: Send,
3613        <R::LspRequest as lsp::request::Request>::Params: Send,
3614    {
3615        debug_assert!(self.upstream_client().is_none());
3616
3617        let snapshot = buffer.read(cx).snapshot();
3618        let scope = position.and_then(|position| snapshot.language_scope_at(position));
3619        let server_ids = self
3620            .language_servers_for_buffer(buffer.read(cx), cx)
3621            .filter(|(adapter, _)| {
3622                scope
3623                    .as_ref()
3624                    .map(|scope| scope.language_allowed(&adapter.name))
3625                    .unwrap_or(true)
3626            })
3627            .map(|(_, server)| server.server_id())
3628            .collect::<Vec<_>>();
3629
3630        let mut response_results = server_ids
3631            .into_iter()
3632            .map(|server_id| {
3633                self.request_lsp(
3634                    buffer.clone(),
3635                    LanguageServerToQuery::Other(server_id),
3636                    request.clone(),
3637                    cx,
3638                )
3639            })
3640            .collect::<FuturesUnordered<_>>();
3641
3642        cx.spawn(|_, _| async move {
3643            let mut responses = Vec::with_capacity(response_results.len());
3644            while let Some(response_result) = response_results.next().await {
3645                if let Some(response) = response_result.log_err() {
3646                    responses.push(response);
3647                }
3648            }
3649            responses
3650        })
3651    }
3652
3653    async fn handle_lsp_command<T: LspCommand>(
3654        this: Model<Self>,
3655        envelope: TypedEnvelope<T::ProtoRequest>,
3656        mut cx: AsyncAppContext,
3657    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
3658    where
3659        <T::LspRequest as lsp::request::Request>::Params: Send,
3660        <T::LspRequest as lsp::request::Request>::Result: Send,
3661    {
3662        let sender_id = envelope.original_sender_id().unwrap_or_default();
3663        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
3664        let buffer_handle = this.update(&mut cx, |this, cx| {
3665            this.buffer_store.read(cx).get_existing(buffer_id)
3666        })??;
3667        let request = T::from_proto(
3668            envelope.payload,
3669            this.clone(),
3670            buffer_handle.clone(),
3671            cx.clone(),
3672        )
3673        .await?;
3674        let response = this
3675            .update(&mut cx, |this, cx| {
3676                this.request_lsp(
3677                    buffer_handle.clone(),
3678                    LanguageServerToQuery::Primary,
3679                    request,
3680                    cx,
3681                )
3682            })?
3683            .await?;
3684        this.update(&mut cx, |this, cx| {
3685            Ok(T::response_to_proto(
3686                response,
3687                this,
3688                sender_id,
3689                &buffer_handle.read(cx).version(),
3690                cx,
3691            ))
3692        })?
3693    }
3694
3695    async fn handle_multi_lsp_query(
3696        this: Model<Self>,
3697        envelope: TypedEnvelope<proto::MultiLspQuery>,
3698        mut cx: AsyncAppContext,
3699    ) -> Result<proto::MultiLspQueryResponse> {
3700        let response_from_ssh = this.update(&mut cx, |this, _| {
3701            let ssh = this.as_ssh()?;
3702            let mut payload = envelope.payload.clone();
3703            payload.project_id = SSH_PROJECT_ID;
3704
3705            Some(ssh.upstream_client.request(payload))
3706        })?;
3707        if let Some(response_from_ssh) = response_from_ssh {
3708            return response_from_ssh.await;
3709        }
3710
3711        let sender_id = envelope.original_sender_id().unwrap_or_default();
3712        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
3713        let version = deserialize_version(&envelope.payload.version);
3714        let buffer = this.update(&mut cx, |this, cx| {
3715            this.buffer_store.read(cx).get_existing(buffer_id)
3716        })??;
3717        buffer
3718            .update(&mut cx, |buffer, _| {
3719                buffer.wait_for_version(version.clone())
3720            })?
3721            .await?;
3722        let buffer_version = buffer.update(&mut cx, |buffer, _| buffer.version())?;
3723        match envelope
3724            .payload
3725            .strategy
3726            .context("invalid request without the strategy")?
3727        {
3728            proto::multi_lsp_query::Strategy::All(_) => {
3729                // currently, there's only one multiple language servers query strategy,
3730                // so just ensure it's specified correctly
3731            }
3732        }
3733        match envelope.payload.request {
3734            Some(proto::multi_lsp_query::Request::GetHover(get_hover)) => {
3735                let get_hover =
3736                    GetHover::from_proto(get_hover, this.clone(), buffer.clone(), cx.clone())
3737                        .await?;
3738                let all_hovers = this
3739                    .update(&mut cx, |this, cx| {
3740                        this.request_multiple_lsp_locally(
3741                            &buffer,
3742                            Some(get_hover.position),
3743                            get_hover,
3744                            cx,
3745                        )
3746                    })?
3747                    .await
3748                    .into_iter()
3749                    .filter_map(|hover| remove_empty_hover_blocks(hover?));
3750                this.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
3751                    responses: all_hovers
3752                        .map(|hover| proto::LspResponse {
3753                            response: Some(proto::lsp_response::Response::GetHoverResponse(
3754                                GetHover::response_to_proto(
3755                                    Some(hover),
3756                                    project,
3757                                    sender_id,
3758                                    &buffer_version,
3759                                    cx,
3760                                ),
3761                            )),
3762                        })
3763                        .collect(),
3764                })
3765            }
3766            Some(proto::multi_lsp_query::Request::GetCodeActions(get_code_actions)) => {
3767                let get_code_actions = GetCodeActions::from_proto(
3768                    get_code_actions,
3769                    this.clone(),
3770                    buffer.clone(),
3771                    cx.clone(),
3772                )
3773                .await?;
3774
3775                let all_actions = this
3776                    .update(&mut cx, |project, cx| {
3777                        project.request_multiple_lsp_locally(
3778                            &buffer,
3779                            Some(get_code_actions.range.start),
3780                            get_code_actions,
3781                            cx,
3782                        )
3783                    })?
3784                    .await
3785                    .into_iter();
3786
3787                this.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
3788                    responses: all_actions
3789                        .map(|code_actions| proto::LspResponse {
3790                            response: Some(proto::lsp_response::Response::GetCodeActionsResponse(
3791                                GetCodeActions::response_to_proto(
3792                                    code_actions,
3793                                    project,
3794                                    sender_id,
3795                                    &buffer_version,
3796                                    cx,
3797                                ),
3798                            )),
3799                        })
3800                        .collect(),
3801                })
3802            }
3803            Some(proto::multi_lsp_query::Request::GetSignatureHelp(get_signature_help)) => {
3804                let get_signature_help = GetSignatureHelp::from_proto(
3805                    get_signature_help,
3806                    this.clone(),
3807                    buffer.clone(),
3808                    cx.clone(),
3809                )
3810                .await?;
3811
3812                let all_signatures = this
3813                    .update(&mut cx, |project, cx| {
3814                        project.request_multiple_lsp_locally(
3815                            &buffer,
3816                            Some(get_signature_help.position),
3817                            get_signature_help,
3818                            cx,
3819                        )
3820                    })?
3821                    .await
3822                    .into_iter();
3823
3824                this.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
3825                    responses: all_signatures
3826                        .map(|signature_help| proto::LspResponse {
3827                            response: Some(
3828                                proto::lsp_response::Response::GetSignatureHelpResponse(
3829                                    GetSignatureHelp::response_to_proto(
3830                                        signature_help,
3831                                        project,
3832                                        sender_id,
3833                                        &buffer_version,
3834                                        cx,
3835                                    ),
3836                                ),
3837                            ),
3838                        })
3839                        .collect(),
3840                })
3841            }
3842            None => anyhow::bail!("empty multi lsp query request"),
3843        }
3844    }
3845
3846    async fn handle_apply_code_action(
3847        this: Model<Self>,
3848        envelope: TypedEnvelope<proto::ApplyCodeAction>,
3849        mut cx: AsyncAppContext,
3850    ) -> Result<proto::ApplyCodeActionResponse> {
3851        let sender_id = envelope.original_sender_id().unwrap_or_default();
3852        let action = Self::deserialize_code_action(
3853            envelope
3854                .payload
3855                .action
3856                .ok_or_else(|| anyhow!("invalid action"))?,
3857        )?;
3858        let apply_code_action = this.update(&mut cx, |this, cx| {
3859            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
3860            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
3861            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
3862        })??;
3863
3864        let project_transaction = apply_code_action.await?;
3865        let project_transaction = this.update(&mut cx, |this, cx| {
3866            this.buffer_store.update(cx, |buffer_store, cx| {
3867                buffer_store.serialize_project_transaction_for_peer(
3868                    project_transaction,
3869                    sender_id,
3870                    cx,
3871                )
3872            })
3873        })?;
3874        Ok(proto::ApplyCodeActionResponse {
3875            transaction: Some(project_transaction),
3876        })
3877    }
3878
3879    async fn handle_update_diagnostic_summary(
3880        this: Model<Self>,
3881        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
3882        mut cx: AsyncAppContext,
3883    ) -> Result<()> {
3884        this.update(&mut cx, |this, cx| {
3885            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
3886            if let Some(message) = envelope.payload.summary {
3887                let project_path = ProjectPath {
3888                    worktree_id,
3889                    path: Path::new(&message.path).into(),
3890                };
3891                let path = project_path.path.clone();
3892                let server_id = LanguageServerId(message.language_server_id as usize);
3893                let summary = DiagnosticSummary {
3894                    error_count: message.error_count as usize,
3895                    warning_count: message.warning_count as usize,
3896                };
3897
3898                if summary.is_empty() {
3899                    if let Some(worktree_summaries) =
3900                        this.diagnostic_summaries.get_mut(&worktree_id)
3901                    {
3902                        if let Some(summaries) = worktree_summaries.get_mut(&path) {
3903                            summaries.remove(&server_id);
3904                            if summaries.is_empty() {
3905                                worktree_summaries.remove(&path);
3906                            }
3907                        }
3908                    }
3909                } else {
3910                    this.diagnostic_summaries
3911                        .entry(worktree_id)
3912                        .or_default()
3913                        .entry(path)
3914                        .or_default()
3915                        .insert(server_id, summary);
3916                }
3917                cx.emit(LspStoreEvent::DiagnosticsUpdated {
3918                    language_server_id: LanguageServerId(message.language_server_id as usize),
3919                    path: project_path,
3920                });
3921            }
3922            Ok(())
3923        })?
3924    }
3925
3926    async fn handle_start_language_server(
3927        this: Model<Self>,
3928        envelope: TypedEnvelope<proto::StartLanguageServer>,
3929        mut cx: AsyncAppContext,
3930    ) -> Result<()> {
3931        let server = envelope
3932            .payload
3933            .server
3934            .ok_or_else(|| anyhow!("invalid server"))?;
3935        this.update(&mut cx, |this, cx| {
3936            this.language_server_statuses.insert(
3937                LanguageServerId(server.id as usize),
3938                LanguageServerStatus {
3939                    name: server.name,
3940                    pending_work: Default::default(),
3941                    has_pending_diagnostic_updates: false,
3942                    progress_tokens: Default::default(),
3943                },
3944            );
3945            cx.notify();
3946        })?;
3947        Ok(())
3948    }
3949
3950    async fn handle_update_language_server(
3951        this: Model<Self>,
3952        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
3953        mut cx: AsyncAppContext,
3954    ) -> Result<()> {
3955        this.update(&mut cx, |this, cx| {
3956            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
3957
3958            match envelope
3959                .payload
3960                .variant
3961                .ok_or_else(|| anyhow!("invalid variant"))?
3962            {
3963                proto::update_language_server::Variant::WorkStart(payload) => {
3964                    this.on_lsp_work_start(
3965                        language_server_id,
3966                        payload.token,
3967                        LanguageServerProgress {
3968                            title: payload.title,
3969                            is_disk_based_diagnostics_progress: false,
3970                            is_cancellable: false,
3971                            message: payload.message,
3972                            percentage: payload.percentage.map(|p| p as usize),
3973                            last_update_at: cx.background_executor().now(),
3974                        },
3975                        cx,
3976                    );
3977                }
3978
3979                proto::update_language_server::Variant::WorkProgress(payload) => {
3980                    this.on_lsp_work_progress(
3981                        language_server_id,
3982                        payload.token,
3983                        LanguageServerProgress {
3984                            title: None,
3985                            is_disk_based_diagnostics_progress: false,
3986                            is_cancellable: false,
3987                            message: payload.message,
3988                            percentage: payload.percentage.map(|p| p as usize),
3989                            last_update_at: cx.background_executor().now(),
3990                        },
3991                        cx,
3992                    );
3993                }
3994
3995                proto::update_language_server::Variant::WorkEnd(payload) => {
3996                    this.on_lsp_work_end(language_server_id, payload.token, cx);
3997                }
3998
3999                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
4000                    this.disk_based_diagnostics_started(language_server_id, cx);
4001                }
4002
4003                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
4004                    this.disk_based_diagnostics_finished(language_server_id, cx)
4005                }
4006            }
4007
4008            Ok(())
4009        })?
4010    }
4011
4012    pub fn disk_based_diagnostics_started(
4013        &mut self,
4014        language_server_id: LanguageServerId,
4015        cx: &mut ModelContext<Self>,
4016    ) {
4017        if let Some(language_server_status) =
4018            self.language_server_statuses.get_mut(&language_server_id)
4019        {
4020            language_server_status.has_pending_diagnostic_updates = true;
4021        }
4022
4023        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
4024        cx.emit(LspStoreEvent::LanguageServerUpdate {
4025            language_server_id,
4026            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
4027                Default::default(),
4028            ),
4029        })
4030    }
4031
4032    pub fn disk_based_diagnostics_finished(
4033        &mut self,
4034        language_server_id: LanguageServerId,
4035        cx: &mut ModelContext<Self>,
4036    ) {
4037        if let Some(language_server_status) =
4038            self.language_server_statuses.get_mut(&language_server_id)
4039        {
4040            language_server_status.has_pending_diagnostic_updates = false;
4041        }
4042
4043        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
4044        cx.emit(LspStoreEvent::LanguageServerUpdate {
4045            language_server_id,
4046            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
4047                Default::default(),
4048            ),
4049        })
4050    }
4051
4052    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
4053    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
4054    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
4055    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
4056    // the language server might take some time to publish diagnostics.
4057    fn simulate_disk_based_diagnostics_events_if_needed(
4058        &mut self,
4059        language_server_id: LanguageServerId,
4060        cx: &mut ModelContext<Self>,
4061    ) {
4062        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
4063
4064        let Some(LanguageServerState::Running {
4065            simulate_disk_based_diagnostics_completion,
4066            adapter,
4067            ..
4068        }) = self
4069            .as_local_mut()
4070            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
4071        else {
4072            return;
4073        };
4074
4075        if adapter.disk_based_diagnostics_progress_token.is_some() {
4076            return;
4077        }
4078
4079        let prev_task = simulate_disk_based_diagnostics_completion.replace(cx.spawn(
4080            move |this, mut cx| async move {
4081                cx.background_executor()
4082                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
4083                    .await;
4084
4085                this.update(&mut cx, |this, cx| {
4086                    this.disk_based_diagnostics_finished(language_server_id, cx);
4087
4088                    if let Some(LanguageServerState::Running {
4089                        simulate_disk_based_diagnostics_completion,
4090                        ..
4091                    }) = this.as_local_mut().and_then(|local_store| {
4092                        local_store.language_servers.get_mut(&language_server_id)
4093                    }) {
4094                        *simulate_disk_based_diagnostics_completion = None;
4095                    }
4096                })
4097                .ok();
4098            },
4099        ));
4100
4101        if prev_task.is_none() {
4102            self.disk_based_diagnostics_started(language_server_id, cx);
4103        }
4104    }
4105
4106    pub fn language_server_statuses(
4107        &self,
4108    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
4109        self.language_server_statuses
4110            .iter()
4111            .map(|(key, value)| (*key, value))
4112    }
4113
4114    fn lsp_notify_abs_paths_changed(
4115        &mut self,
4116        server_id: LanguageServerId,
4117        changes: Vec<PathEvent>,
4118    ) {
4119        maybe!({
4120            let server = self.language_server_for_id(server_id)?;
4121            let changes = changes
4122                .into_iter()
4123                .filter_map(|event| {
4124                    let typ = match event.kind? {
4125                        PathEventKind::Created => lsp::FileChangeType::CREATED,
4126                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
4127                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
4128                    };
4129                    Some(lsp::FileEvent {
4130                        uri: lsp::Url::from_file_path(&event.path).ok()?,
4131                        typ,
4132                    })
4133                })
4134                .collect::<Vec<_>>();
4135            if !changes.is_empty() {
4136                server
4137                    .notify::<lsp::notification::DidChangeWatchedFiles>(
4138                        lsp::DidChangeWatchedFilesParams { changes },
4139                    )
4140                    .log_err();
4141            }
4142            Some(())
4143        });
4144    }
4145
4146    fn rebuild_watched_paths(
4147        &mut self,
4148        language_server_id: LanguageServerId,
4149        cx: &mut ModelContext<Self>,
4150    ) {
4151        let worktrees = self
4152            .worktree_store
4153            .read(cx)
4154            .worktrees()
4155            .filter_map(|worktree| {
4156                self.language_servers_for_worktree(worktree.read(cx).id())
4157                    .find(|server| server.server_id() == language_server_id)
4158                    .map(|_| worktree)
4159            })
4160            .collect::<Vec<_>>();
4161
4162        let local_lsp_store = self.as_local_mut().unwrap();
4163
4164        let Some(watchers) = local_lsp_store
4165            .language_server_watcher_registrations
4166            .get(&language_server_id)
4167        else {
4168            return;
4169        };
4170
4171        let mut worktree_globs = HashMap::default();
4172        let mut abs_globs = HashMap::default();
4173        log::trace!(
4174            "Processing new watcher paths for language server with id {}",
4175            language_server_id
4176        );
4177
4178        enum PathToWatch {
4179            Worktree {
4180                literal_prefix: Arc<Path>,
4181                pattern: String,
4182            },
4183            Absolute {
4184                path: Arc<Path>,
4185                pattern: String,
4186            },
4187        }
4188        for watcher in watchers.values().flatten() {
4189            let mut found_host = false;
4190            for worktree in &worktrees {
4191                let glob_is_inside_worktree = worktree.update(cx, |tree, _| {
4192                    if let Some(worktree_root_path) = tree.abs_path().to_str() {
4193                        let path_to_watch = match &watcher.glob_pattern {
4194                            lsp::GlobPattern::String(s) => {
4195                                match s.strip_prefix(worktree_root_path) {
4196                                    Some(relative) => {
4197                                        let pattern = relative
4198                                            .strip_prefix(std::path::MAIN_SEPARATOR)
4199                                            .unwrap_or(relative)
4200                                            .to_owned();
4201                                        let literal_prefix = glob_literal_prefix(&pattern);
4202
4203                                        let literal_prefix = Arc::from(PathBuf::from(
4204                                            literal_prefix
4205                                                .strip_prefix(std::path::MAIN_SEPARATOR)
4206                                                .unwrap_or(literal_prefix),
4207                                        ));
4208                                        PathToWatch::Worktree {
4209                                            literal_prefix,
4210                                            pattern,
4211                                        }
4212                                    }
4213                                    None => {
4214                                        let path = glob_literal_prefix(s);
4215                                        let glob = &s[path.len()..];
4216                                        let pattern = glob
4217                                            .strip_prefix(std::path::MAIN_SEPARATOR)
4218                                            .unwrap_or(glob)
4219                                            .to_owned();
4220                                        let path = if Path::new(path).components().next().is_none()
4221                                        {
4222                                            Arc::from(Path::new(worktree_root_path))
4223                                        } else {
4224                                            PathBuf::from(path).into()
4225                                        };
4226
4227                                        PathToWatch::Absolute { path, pattern }
4228                                    }
4229                                }
4230                            }
4231                            lsp::GlobPattern::Relative(rp) => {
4232                                let Ok(mut base_uri) = match &rp.base_uri {
4233                                    lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
4234                                    lsp::OneOf::Right(base_uri) => base_uri,
4235                                }
4236                                .to_file_path() else {
4237                                    return false;
4238                                };
4239
4240                                match base_uri.strip_prefix(worktree_root_path) {
4241                                    Ok(relative) => {
4242                                        let mut literal_prefix = relative.to_owned();
4243                                        literal_prefix.push(glob_literal_prefix(&rp.pattern));
4244
4245                                        PathToWatch::Worktree {
4246                                            literal_prefix: literal_prefix.into(),
4247                                            pattern: rp.pattern.clone(),
4248                                        }
4249                                    }
4250                                    Err(_) => {
4251                                        let path = glob_literal_prefix(&rp.pattern);
4252                                        let glob = &rp.pattern[path.len()..];
4253                                        let pattern = glob
4254                                            .strip_prefix(std::path::MAIN_SEPARATOR)
4255                                            .unwrap_or(glob)
4256                                            .to_owned();
4257                                        base_uri.push(path);
4258
4259                                        let path = if base_uri.components().next().is_none() {
4260                                            Arc::from(Path::new("/"))
4261                                        } else {
4262                                            base_uri.into()
4263                                        };
4264                                        PathToWatch::Absolute { path, pattern }
4265                                    }
4266                                }
4267                            }
4268                        };
4269                        match path_to_watch {
4270                            PathToWatch::Worktree {
4271                                literal_prefix,
4272                                pattern,
4273                            } => {
4274                                if let Some((tree, glob)) =
4275                                    tree.as_local_mut().zip(Glob::new(&pattern).log_err())
4276                                {
4277                                    tree.add_path_prefix_to_scan(literal_prefix);
4278                                    worktree_globs
4279                                        .entry(tree.id())
4280                                        .or_insert_with(GlobSetBuilder::new)
4281                                        .add(glob);
4282                                } else {
4283                                    return false;
4284                                }
4285                            }
4286                            PathToWatch::Absolute { path, pattern } => {
4287                                if let Some(glob) = Glob::new(&pattern).log_err() {
4288                                    abs_globs
4289                                        .entry(path)
4290                                        .or_insert_with(GlobSetBuilder::new)
4291                                        .add(glob);
4292                                }
4293                            }
4294                        }
4295                        return true;
4296                    }
4297                    false
4298                });
4299                if glob_is_inside_worktree {
4300                    log::trace!(
4301                        "Watcher pattern `{}` has been attached to the worktree at `{}`",
4302                        serde_json::to_string(&watcher.glob_pattern).unwrap(),
4303                        worktree.read(cx).abs_path().display()
4304                    );
4305                    found_host = true;
4306                }
4307            }
4308            if !found_host {
4309                log::error!(
4310                    "Watcher pattern `{}` has not been attached to any worktree or absolute path",
4311                    serde_json::to_string(&watcher.glob_pattern).unwrap()
4312                )
4313            }
4314        }
4315
4316        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
4317        for (worktree_id, builder) in worktree_globs {
4318            if let Ok(globset) = builder.build() {
4319                watch_builder.watch_worktree(worktree_id, globset);
4320            }
4321        }
4322        for (abs_path, builder) in abs_globs {
4323            if let Ok(globset) = builder.build() {
4324                watch_builder.watch_abs_path(abs_path, globset);
4325            }
4326        }
4327        let watcher = watch_builder.build(local_lsp_store.fs.clone(), language_server_id, cx);
4328        local_lsp_store
4329            .language_server_watched_paths
4330            .insert(language_server_id, watcher);
4331
4332        cx.notify();
4333    }
4334
4335    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
4336        if let Some(local_lsp_store) = self.as_local() {
4337            if let Some(LanguageServerState::Running { server, .. }) =
4338                local_lsp_store.language_servers.get(&id)
4339            {
4340                Some(server.clone())
4341            } else if let Some((_, server)) =
4342                local_lsp_store.supplementary_language_servers.get(&id)
4343            {
4344                Some(Arc::clone(server))
4345            } else {
4346                None
4347            }
4348        } else {
4349            None
4350        }
4351    }
4352
4353    async fn on_lsp_workspace_edit(
4354        this: WeakModel<Self>,
4355        params: lsp::ApplyWorkspaceEditParams,
4356        server_id: LanguageServerId,
4357        adapter: Arc<CachedLspAdapter>,
4358        mut cx: AsyncAppContext,
4359    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
4360        let this = this
4361            .upgrade()
4362            .ok_or_else(|| anyhow!("project project closed"))?;
4363        let language_server = this
4364            .update(&mut cx, |this, _| this.language_server_for_id(server_id))?
4365            .ok_or_else(|| anyhow!("language server not found"))?;
4366        let transaction = Self::deserialize_workspace_edit(
4367            this.clone(),
4368            params.edit,
4369            true,
4370            adapter.clone(),
4371            language_server.clone(),
4372            &mut cx,
4373        )
4374        .await
4375        .log_err();
4376        this.update(&mut cx, |this, _| {
4377            if let Some(transaction) = transaction {
4378                this.as_local_mut()
4379                    .unwrap()
4380                    .last_workspace_edits_by_language_server
4381                    .insert(server_id, transaction);
4382            }
4383        })?;
4384        Ok(lsp::ApplyWorkspaceEditResponse {
4385            applied: true,
4386            failed_change: None,
4387            failure_reason: None,
4388        })
4389    }
4390
4391    fn on_lsp_progress(
4392        &mut self,
4393        progress: lsp::ProgressParams,
4394        language_server_id: LanguageServerId,
4395        disk_based_diagnostics_progress_token: Option<String>,
4396        cx: &mut ModelContext<Self>,
4397    ) {
4398        let token = match progress.token {
4399            lsp::NumberOrString::String(token) => token,
4400            lsp::NumberOrString::Number(token) => {
4401                log::info!("skipping numeric progress token {}", token);
4402                return;
4403            }
4404        };
4405
4406        let lsp::ProgressParamsValue::WorkDone(progress) = progress.value;
4407        let language_server_status =
4408            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
4409                status
4410            } else {
4411                return;
4412            };
4413
4414        if !language_server_status.progress_tokens.contains(&token) {
4415            return;
4416        }
4417
4418        let is_disk_based_diagnostics_progress = disk_based_diagnostics_progress_token
4419            .as_ref()
4420            .map_or(false, |disk_based_token| {
4421                token.starts_with(disk_based_token)
4422            });
4423
4424        match progress {
4425            lsp::WorkDoneProgress::Begin(report) => {
4426                if is_disk_based_diagnostics_progress {
4427                    self.disk_based_diagnostics_started(language_server_id, cx);
4428                }
4429                self.on_lsp_work_start(
4430                    language_server_id,
4431                    token.clone(),
4432                    LanguageServerProgress {
4433                        title: Some(report.title),
4434                        is_disk_based_diagnostics_progress,
4435                        is_cancellable: report.cancellable.unwrap_or(false),
4436                        message: report.message.clone(),
4437                        percentage: report.percentage.map(|p| p as usize),
4438                        last_update_at: cx.background_executor().now(),
4439                    },
4440                    cx,
4441                );
4442            }
4443            lsp::WorkDoneProgress::Report(report) => {
4444                if self.on_lsp_work_progress(
4445                    language_server_id,
4446                    token.clone(),
4447                    LanguageServerProgress {
4448                        title: None,
4449                        is_disk_based_diagnostics_progress,
4450                        is_cancellable: report.cancellable.unwrap_or(false),
4451                        message: report.message.clone(),
4452                        percentage: report.percentage.map(|p| p as usize),
4453                        last_update_at: cx.background_executor().now(),
4454                    },
4455                    cx,
4456                ) {
4457                    cx.emit(LspStoreEvent::LanguageServerUpdate {
4458                        language_server_id,
4459                        message: proto::update_language_server::Variant::WorkProgress(
4460                            proto::LspWorkProgress {
4461                                token,
4462                                message: report.message,
4463                                percentage: report.percentage,
4464                            },
4465                        ),
4466                    })
4467                }
4468            }
4469            lsp::WorkDoneProgress::End(_) => {
4470                language_server_status.progress_tokens.remove(&token);
4471                self.on_lsp_work_end(language_server_id, token.clone(), cx);
4472                if is_disk_based_diagnostics_progress {
4473                    self.disk_based_diagnostics_finished(language_server_id, cx);
4474                }
4475            }
4476        }
4477    }
4478
4479    fn on_lsp_work_start(
4480        &mut self,
4481        language_server_id: LanguageServerId,
4482        token: String,
4483        progress: LanguageServerProgress,
4484        cx: &mut ModelContext<Self>,
4485    ) {
4486        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
4487            status.pending_work.insert(token.clone(), progress.clone());
4488            cx.notify();
4489        }
4490        cx.emit(LspStoreEvent::LanguageServerUpdate {
4491            language_server_id,
4492            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
4493                token,
4494                title: progress.title,
4495                message: progress.message,
4496                percentage: progress.percentage.map(|p| p as u32),
4497            }),
4498        })
4499    }
4500
4501    fn on_lsp_work_progress(
4502        &mut self,
4503        language_server_id: LanguageServerId,
4504        token: String,
4505        progress: LanguageServerProgress,
4506        cx: &mut ModelContext<Self>,
4507    ) -> bool {
4508        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
4509            match status.pending_work.entry(token) {
4510                btree_map::Entry::Vacant(entry) => {
4511                    entry.insert(progress);
4512                    cx.notify();
4513                    return true;
4514                }
4515                btree_map::Entry::Occupied(mut entry) => {
4516                    let entry = entry.get_mut();
4517                    if (progress.last_update_at - entry.last_update_at)
4518                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
4519                    {
4520                        entry.last_update_at = progress.last_update_at;
4521                        if progress.message.is_some() {
4522                            entry.message = progress.message;
4523                        }
4524                        if progress.percentage.is_some() {
4525                            entry.percentage = progress.percentage;
4526                        }
4527                        cx.notify();
4528                        return true;
4529                    }
4530                }
4531            }
4532        }
4533
4534        false
4535    }
4536
4537    fn on_lsp_work_end(
4538        &mut self,
4539        language_server_id: LanguageServerId,
4540        token: String,
4541        cx: &mut ModelContext<Self>,
4542    ) {
4543        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
4544            if let Some(work) = status.pending_work.remove(&token) {
4545                if !work.is_disk_based_diagnostics_progress {
4546                    cx.emit(LspStoreEvent::RefreshInlayHints);
4547                }
4548            }
4549            cx.notify();
4550        }
4551
4552        cx.emit(LspStoreEvent::LanguageServerUpdate {
4553            language_server_id,
4554            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd { token }),
4555        })
4556    }
4557
4558    fn on_lsp_did_change_watched_files(
4559        &mut self,
4560        language_server_id: LanguageServerId,
4561        registration_id: &str,
4562        params: DidChangeWatchedFilesRegistrationOptions,
4563        cx: &mut ModelContext<Self>,
4564    ) {
4565        if let Some(local) = self.as_local_mut() {
4566            let registrations = local
4567                .language_server_watcher_registrations
4568                .entry(language_server_id)
4569                .or_default();
4570
4571            registrations.insert(registration_id.to_string(), params.watchers);
4572
4573            self.rebuild_watched_paths(language_server_id, cx);
4574        }
4575    }
4576
4577    fn on_lsp_unregister_did_change_watched_files(
4578        &mut self,
4579        language_server_id: LanguageServerId,
4580        registration_id: &str,
4581        cx: &mut ModelContext<Self>,
4582    ) {
4583        if let Some(local) = self.as_local_mut() {
4584            let registrations = local
4585                .language_server_watcher_registrations
4586                .entry(language_server_id)
4587                .or_default();
4588
4589            if registrations.remove(registration_id).is_some() {
4590                log::info!(
4591                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
4592                language_server_id,
4593                registration_id
4594            );
4595            } else {
4596                log::warn!(
4597                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
4598                language_server_id,
4599                registration_id
4600            );
4601            }
4602
4603            self.rebuild_watched_paths(language_server_id, cx);
4604        }
4605    }
4606
4607    #[allow(clippy::type_complexity)]
4608    pub(crate) fn edits_from_lsp(
4609        &mut self,
4610        buffer: &Model<Buffer>,
4611        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
4612        server_id: LanguageServerId,
4613        version: Option<i32>,
4614        cx: &mut ModelContext<Self>,
4615    ) -> Task<Result<Vec<(Range<Anchor>, String)>>> {
4616        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
4617        cx.background_executor().spawn(async move {
4618            let snapshot = snapshot?;
4619            let mut lsp_edits = lsp_edits
4620                .into_iter()
4621                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
4622                .collect::<Vec<_>>();
4623            lsp_edits.sort_by_key(|(range, _)| range.start);
4624
4625            let mut lsp_edits = lsp_edits.into_iter().peekable();
4626            let mut edits = Vec::new();
4627            while let Some((range, mut new_text)) = lsp_edits.next() {
4628                // Clip invalid ranges provided by the language server.
4629                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
4630                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
4631
4632                // Combine any LSP edits that are adjacent.
4633                //
4634                // Also, combine LSP edits that are separated from each other by only
4635                // a newline. This is important because for some code actions,
4636                // Rust-analyzer rewrites the entire buffer via a series of edits that
4637                // are separated by unchanged newline characters.
4638                //
4639                // In order for the diffing logic below to work properly, any edits that
4640                // cancel each other out must be combined into one.
4641                while let Some((next_range, next_text)) = lsp_edits.peek() {
4642                    if next_range.start.0 > range.end {
4643                        if next_range.start.0.row > range.end.row + 1
4644                            || next_range.start.0.column > 0
4645                            || snapshot.clip_point_utf16(
4646                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
4647                                Bias::Left,
4648                            ) > range.end
4649                        {
4650                            break;
4651                        }
4652                        new_text.push('\n');
4653                    }
4654                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
4655                    new_text.push_str(next_text);
4656                    lsp_edits.next();
4657                }
4658
4659                // For multiline edits, perform a diff of the old and new text so that
4660                // we can identify the changes more precisely, preserving the locations
4661                // of any anchors positioned in the unchanged regions.
4662                if range.end.row > range.start.row {
4663                    let mut offset = range.start.to_offset(&snapshot);
4664                    let old_text = snapshot.text_for_range(range).collect::<String>();
4665
4666                    let diff = TextDiff::from_lines(old_text.as_str(), &new_text);
4667                    let mut moved_since_edit = true;
4668                    for change in diff.iter_all_changes() {
4669                        let tag = change.tag();
4670                        let value = change.value();
4671                        match tag {
4672                            ChangeTag::Equal => {
4673                                offset += value.len();
4674                                moved_since_edit = true;
4675                            }
4676                            ChangeTag::Delete => {
4677                                let start = snapshot.anchor_after(offset);
4678                                let end = snapshot.anchor_before(offset + value.len());
4679                                if moved_since_edit {
4680                                    edits.push((start..end, String::new()));
4681                                } else {
4682                                    edits.last_mut().unwrap().0.end = end;
4683                                }
4684                                offset += value.len();
4685                                moved_since_edit = false;
4686                            }
4687                            ChangeTag::Insert => {
4688                                if moved_since_edit {
4689                                    let anchor = snapshot.anchor_after(offset);
4690                                    edits.push((anchor..anchor, value.to_string()));
4691                                } else {
4692                                    edits.last_mut().unwrap().1.push_str(value);
4693                                }
4694                                moved_since_edit = false;
4695                            }
4696                        }
4697                    }
4698                } else if range.end == range.start {
4699                    let anchor = snapshot.anchor_after(range.start);
4700                    edits.push((anchor..anchor, new_text));
4701                } else {
4702                    let edit_start = snapshot.anchor_after(range.start);
4703                    let edit_end = snapshot.anchor_before(range.end);
4704                    edits.push((edit_start..edit_end, new_text));
4705                }
4706            }
4707
4708            Ok(edits)
4709        })
4710    }
4711
4712    pub async fn handle_resolve_completion_documentation(
4713        this: Model<Self>,
4714        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
4715        mut cx: AsyncAppContext,
4716    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
4717        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
4718
4719        let completion = this
4720            .read_with(&cx, |this, cx| {
4721                let id = LanguageServerId(envelope.payload.language_server_id as usize);
4722                let Some(server) = this.language_server_for_id(id) else {
4723                    return Err(anyhow!("No language server {id}"));
4724                };
4725
4726                Ok(cx.background_executor().spawn(async move {
4727                    let can_resolve = server
4728                        .capabilities()
4729                        .completion_provider
4730                        .as_ref()
4731                        .and_then(|options| options.resolve_provider)
4732                        .unwrap_or(false);
4733                    if can_resolve {
4734                        server
4735                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
4736                            .await
4737                    } else {
4738                        anyhow::Ok(lsp_completion)
4739                    }
4740                }))
4741            })??
4742            .await?;
4743
4744        let mut documentation_is_markdown = false;
4745        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
4746        let documentation = match completion.documentation {
4747            Some(lsp::Documentation::String(text)) => text,
4748
4749            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
4750                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
4751                value
4752            }
4753
4754            _ => String::new(),
4755        };
4756
4757        // If we have a new buffer_id, that means we're talking to a new client
4758        // and want to check for new text_edits in the completion too.
4759        let mut old_start = None;
4760        let mut old_end = None;
4761        let mut new_text = String::default();
4762        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
4763            let buffer_snapshot = this.update(&mut cx, |this, cx| {
4764                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
4765                anyhow::Ok(buffer.read(cx).snapshot())
4766            })??;
4767
4768            if let Some(text_edit) = completion.text_edit.as_ref() {
4769                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
4770
4771                if let Some((old_range, mut text_edit_new_text)) = edit {
4772                    LineEnding::normalize(&mut text_edit_new_text);
4773
4774                    new_text = text_edit_new_text;
4775                    old_start = Some(serialize_anchor(&old_range.start));
4776                    old_end = Some(serialize_anchor(&old_range.end));
4777                }
4778            }
4779        }
4780
4781        Ok(proto::ResolveCompletionDocumentationResponse {
4782            documentation,
4783            documentation_is_markdown,
4784            old_start,
4785            old_end,
4786            new_text,
4787            lsp_completion,
4788        })
4789    }
4790
4791    async fn handle_on_type_formatting(
4792        this: Model<Self>,
4793        envelope: TypedEnvelope<proto::OnTypeFormatting>,
4794        mut cx: AsyncAppContext,
4795    ) -> Result<proto::OnTypeFormattingResponse> {
4796        let on_type_formatting = this.update(&mut cx, |this, cx| {
4797            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
4798            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
4799            let position = envelope
4800                .payload
4801                .position
4802                .and_then(deserialize_anchor)
4803                .ok_or_else(|| anyhow!("invalid position"))?;
4804            Ok::<_, anyhow::Error>(this.apply_on_type_formatting(
4805                buffer,
4806                position,
4807                envelope.payload.trigger.clone(),
4808                cx,
4809            ))
4810        })??;
4811
4812        let transaction = on_type_formatting
4813            .await?
4814            .as_ref()
4815            .map(language::proto::serialize_transaction);
4816        Ok(proto::OnTypeFormattingResponse { transaction })
4817    }
4818
4819    async fn handle_refresh_inlay_hints(
4820        this: Model<Self>,
4821        _: TypedEnvelope<proto::RefreshInlayHints>,
4822        mut cx: AsyncAppContext,
4823    ) -> Result<proto::Ack> {
4824        this.update(&mut cx, |_, cx| {
4825            cx.emit(LspStoreEvent::RefreshInlayHints);
4826        })?;
4827        Ok(proto::Ack {})
4828    }
4829
4830    async fn handle_inlay_hints(
4831        this: Model<Self>,
4832        envelope: TypedEnvelope<proto::InlayHints>,
4833        mut cx: AsyncAppContext,
4834    ) -> Result<proto::InlayHintsResponse> {
4835        let sender_id = envelope.original_sender_id().unwrap_or_default();
4836        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
4837        let buffer = this.update(&mut cx, |this, cx| {
4838            this.buffer_store.read(cx).get_existing(buffer_id)
4839        })??;
4840        buffer
4841            .update(&mut cx, |buffer, _| {
4842                buffer.wait_for_version(deserialize_version(&envelope.payload.version))
4843            })?
4844            .await
4845            .with_context(|| format!("waiting for version for buffer {}", buffer.entity_id()))?;
4846
4847        let start = envelope
4848            .payload
4849            .start
4850            .and_then(deserialize_anchor)
4851            .context("missing range start")?;
4852        let end = envelope
4853            .payload
4854            .end
4855            .and_then(deserialize_anchor)
4856            .context("missing range end")?;
4857        let buffer_hints = this
4858            .update(&mut cx, |lsp_store, cx| {
4859                lsp_store.inlay_hints(buffer.clone(), start..end, cx)
4860            })?
4861            .await
4862            .context("inlay hints fetch")?;
4863
4864        this.update(&mut cx, |project, cx| {
4865            InlayHints::response_to_proto(
4866                buffer_hints,
4867                project,
4868                sender_id,
4869                &buffer.read(cx).version(),
4870                cx,
4871            )
4872        })
4873    }
4874
4875    async fn handle_resolve_inlay_hint(
4876        this: Model<Self>,
4877        envelope: TypedEnvelope<proto::ResolveInlayHint>,
4878        mut cx: AsyncAppContext,
4879    ) -> Result<proto::ResolveInlayHintResponse> {
4880        let proto_hint = envelope
4881            .payload
4882            .hint
4883            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
4884        let hint = InlayHints::proto_to_project_hint(proto_hint)
4885            .context("resolved proto inlay hint conversion")?;
4886        let buffer = this.update(&mut cx, |this, cx| {
4887            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
4888            this.buffer_store.read(cx).get_existing(buffer_id)
4889        })??;
4890        let response_hint = this
4891            .update(&mut cx, |this, cx| {
4892                this.resolve_inlay_hint(
4893                    hint,
4894                    buffer,
4895                    LanguageServerId(envelope.payload.language_server_id as usize),
4896                    cx,
4897                )
4898            })?
4899            .await
4900            .context("inlay hints fetch")?;
4901        Ok(proto::ResolveInlayHintResponse {
4902            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
4903        })
4904    }
4905
4906    async fn handle_open_buffer_for_symbol(
4907        this: Model<Self>,
4908        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
4909        mut cx: AsyncAppContext,
4910    ) -> Result<proto::OpenBufferForSymbolResponse> {
4911        let peer_id = envelope.original_sender_id().unwrap_or_default();
4912        let symbol = envelope
4913            .payload
4914            .symbol
4915            .ok_or_else(|| anyhow!("invalid symbol"))?;
4916        let symbol = Self::deserialize_symbol(symbol)?;
4917        let symbol = this.update(&mut cx, |this, _| {
4918            let signature = this.symbol_signature(&symbol.path);
4919            if signature == symbol.signature {
4920                Ok(symbol)
4921            } else {
4922                Err(anyhow!("invalid symbol signature"))
4923            }
4924        })??;
4925        let buffer = this
4926            .update(&mut cx, |this, cx| {
4927                this.open_buffer_for_symbol(
4928                    &Symbol {
4929                        language_server_name: symbol.language_server_name,
4930                        source_worktree_id: symbol.source_worktree_id,
4931                        path: symbol.path,
4932                        name: symbol.name,
4933                        kind: symbol.kind,
4934                        range: symbol.range,
4935                        signature: symbol.signature,
4936                        label: CodeLabel {
4937                            text: Default::default(),
4938                            runs: Default::default(),
4939                            filter_range: Default::default(),
4940                        },
4941                    },
4942                    cx,
4943                )
4944            })?
4945            .await?;
4946
4947        this.update(&mut cx, |this, cx| {
4948            let is_private = buffer
4949                .read(cx)
4950                .file()
4951                .map(|f| f.is_private())
4952                .unwrap_or_default();
4953            if is_private {
4954                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
4955            } else {
4956                this.buffer_store
4957                    .update(cx, |buffer_store, cx| {
4958                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
4959                    })
4960                    .detach_and_log_err(cx);
4961                let buffer_id = buffer.read(cx).remote_id().to_proto();
4962                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
4963            }
4964        })?
4965    }
4966
4967    fn symbol_signature(&self, project_path: &ProjectPath) -> [u8; 32] {
4968        let mut hasher = Sha256::new();
4969        hasher.update(project_path.worktree_id.to_proto().to_be_bytes());
4970        hasher.update(project_path.path.to_string_lossy().as_bytes());
4971        hasher.update(self.nonce.to_be_bytes());
4972        hasher.finalize().as_slice().try_into().unwrap()
4973    }
4974
4975    pub async fn handle_get_project_symbols(
4976        this: Model<Self>,
4977        envelope: TypedEnvelope<proto::GetProjectSymbols>,
4978        mut cx: AsyncAppContext,
4979    ) -> Result<proto::GetProjectSymbolsResponse> {
4980        let symbols = this
4981            .update(&mut cx, |this, cx| {
4982                this.symbols(&envelope.payload.query, cx)
4983            })?
4984            .await?;
4985
4986        Ok(proto::GetProjectSymbolsResponse {
4987            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
4988        })
4989    }
4990
4991    pub async fn handle_restart_language_servers(
4992        this: Model<Self>,
4993        envelope: TypedEnvelope<proto::RestartLanguageServers>,
4994        mut cx: AsyncAppContext,
4995    ) -> Result<proto::Ack> {
4996        this.update(&mut cx, |this, cx| {
4997            let buffers: Vec<_> = envelope
4998                .payload
4999                .buffer_ids
5000                .into_iter()
5001                .flat_map(|buffer_id| {
5002                    this.buffer_store
5003                        .read(cx)
5004                        .get(BufferId::new(buffer_id).log_err()?)
5005                })
5006                .collect();
5007            this.restart_language_servers_for_buffers(buffers, cx)
5008        })?;
5009
5010        Ok(proto::Ack {})
5011    }
5012
5013    pub async fn handle_create_language_server(
5014        this: Model<Self>,
5015        envelope: TypedEnvelope<proto::CreateLanguageServer>,
5016        mut cx: AsyncAppContext,
5017    ) -> Result<proto::Ack> {
5018        let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
5019        let server_name = LanguageServerName::from_proto(envelope.payload.name);
5020
5021        let binary = envelope
5022            .payload
5023            .binary
5024            .ok_or_else(|| anyhow!("missing binary"))?;
5025        let binary = LanguageServerBinary {
5026            path: PathBuf::from(binary.path),
5027            env: None,
5028            arguments: binary.arguments.into_iter().map(Into::into).collect(),
5029        };
5030        let language = envelope
5031            .payload
5032            .language
5033            .ok_or_else(|| anyhow!("missing language"))?;
5034        let language_name = LanguageName::from_proto(language.name);
5035        let matcher: LanguageMatcher = serde_json::from_str(&language.matcher)?;
5036
5037        this.update(&mut cx, |this, cx| {
5038            let Some(worktree) = this
5039                .worktree_store
5040                .read(cx)
5041                .worktree_for_id(worktree_id, cx)
5042            else {
5043                return Err(anyhow!("worktree not found"));
5044            };
5045
5046            this.languages
5047                .register_language(language_name.clone(), None, matcher.clone(), {
5048                    let language_name = language_name.clone();
5049                    move || {
5050                        Ok((
5051                            LanguageConfig {
5052                                name: language_name.clone(),
5053                                matcher: matcher.clone(),
5054                                ..Default::default()
5055                            },
5056                            Default::default(),
5057                            Default::default(),
5058                        ))
5059                    }
5060                });
5061            cx.background_executor()
5062                .spawn(this.languages.language_for_name(language_name.0.as_ref()))
5063                .detach();
5064
5065            let adapter = this.languages.get_or_register_lsp_adapter(
5066                language_name.clone(),
5067                server_name.clone(),
5068                || {
5069                    Arc::new(SshLspAdapter::new(
5070                        server_name,
5071                        binary,
5072                        envelope.payload.initialization_options,
5073                        envelope.payload.code_action_kinds,
5074                    ))
5075                },
5076            );
5077
5078            this.start_language_server(&worktree, adapter, language_name, cx);
5079            Ok(())
5080        })??;
5081        Ok(proto::Ack {})
5082    }
5083
5084    pub async fn handle_which_command(
5085        this: Model<Self>,
5086        envelope: TypedEnvelope<proto::WhichCommand>,
5087        mut cx: AsyncAppContext,
5088    ) -> Result<proto::WhichCommandResponse> {
5089        let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
5090        let command = PathBuf::from(envelope.payload.command);
5091        let response = this
5092            .update(&mut cx, |this, cx| {
5093                let worktree = this.worktree_for_id(worktree_id, cx)?;
5094                let delegate = LocalLspAdapterDelegate::for_local(this, &worktree, cx);
5095                anyhow::Ok(
5096                    cx.spawn(|_, _| async move { delegate.which(command.as_os_str()).await }),
5097                )
5098            })??
5099            .await;
5100
5101        Ok(proto::WhichCommandResponse {
5102            path: response.map(|path| path.to_string_lossy().to_string()),
5103        })
5104    }
5105
5106    pub async fn handle_shell_env(
5107        this: Model<Self>,
5108        envelope: TypedEnvelope<proto::ShellEnv>,
5109        mut cx: AsyncAppContext,
5110    ) -> Result<proto::ShellEnvResponse> {
5111        let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
5112        let response = this
5113            .update(&mut cx, |this, cx| {
5114                let worktree = this.worktree_for_id(worktree_id, cx)?;
5115                let delegate = LocalLspAdapterDelegate::for_local(this, &worktree, cx);
5116                anyhow::Ok(cx.spawn(|_, _| async move { delegate.shell_env().await }))
5117            })??
5118            .await;
5119
5120        Ok(proto::ShellEnvResponse {
5121            env: response.into_iter().collect(),
5122        })
5123    }
5124    pub async fn handle_try_exec(
5125        this: Model<Self>,
5126        envelope: TypedEnvelope<proto::TryExec>,
5127        mut cx: AsyncAppContext,
5128    ) -> Result<proto::Ack> {
5129        let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
5130        let binary = envelope
5131            .payload
5132            .binary
5133            .ok_or_else(|| anyhow!("missing binary"))?;
5134        let binary = LanguageServerBinary {
5135            path: PathBuf::from(binary.path),
5136            env: None,
5137            arguments: binary.arguments.into_iter().map(Into::into).collect(),
5138        };
5139        this.update(&mut cx, |this, cx| {
5140            let worktree = this.worktree_for_id(worktree_id, cx)?;
5141            let delegate = LocalLspAdapterDelegate::for_local(this, &worktree, cx);
5142            anyhow::Ok(cx.spawn(|_, _| async move { delegate.try_exec(binary).await }))
5143        })??
5144        .await?;
5145
5146        Ok(proto::Ack {})
5147    }
5148
5149    pub async fn handle_read_text_file(
5150        this: Model<Self>,
5151        envelope: TypedEnvelope<proto::ReadTextFile>,
5152        mut cx: AsyncAppContext,
5153    ) -> Result<proto::ReadTextFileResponse> {
5154        let path = envelope
5155            .payload
5156            .path
5157            .ok_or_else(|| anyhow!("missing path"))?;
5158        let worktree_id = WorktreeId::from_proto(path.worktree_id);
5159        let path = PathBuf::from(path.path);
5160        let response = this
5161            .update(&mut cx, |this, cx| {
5162                let worktree = this.worktree_for_id(worktree_id, cx)?;
5163                let delegate = LocalLspAdapterDelegate::for_local(this, &worktree, cx);
5164                anyhow::Ok(cx.spawn(|_, _| async move { delegate.read_text_file(path).await }))
5165            })??
5166            .await?;
5167
5168        Ok(proto::ReadTextFileResponse { text: response })
5169    }
5170
5171    async fn handle_apply_additional_edits_for_completion(
5172        this: Model<Self>,
5173        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
5174        mut cx: AsyncAppContext,
5175    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
5176        let (buffer, completion) = this.update(&mut cx, |this, cx| {
5177            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
5178            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
5179            let completion = Self::deserialize_completion(
5180                envelope
5181                    .payload
5182                    .completion
5183                    .ok_or_else(|| anyhow!("invalid completion"))?,
5184            )?;
5185            anyhow::Ok((buffer, completion))
5186        })??;
5187
5188        let apply_additional_edits = this.update(&mut cx, |this, cx| {
5189            this.apply_additional_edits_for_completion(
5190                buffer,
5191                Completion {
5192                    old_range: completion.old_range,
5193                    new_text: completion.new_text,
5194                    lsp_completion: completion.lsp_completion,
5195                    server_id: completion.server_id,
5196                    documentation: None,
5197                    label: CodeLabel {
5198                        text: Default::default(),
5199                        runs: Default::default(),
5200                        filter_range: Default::default(),
5201                    },
5202                    confirm: None,
5203                },
5204                false,
5205                cx,
5206            )
5207        })?;
5208
5209        Ok(proto::ApplyCompletionAdditionalEditsResponse {
5210            transaction: apply_additional_edits
5211                .await?
5212                .as_ref()
5213                .map(language::proto::serialize_transaction),
5214        })
5215    }
5216    pub fn last_formatting_failure(&self) -> Option<&str> {
5217        self.as_local()
5218            .and_then(|local| local.last_formatting_failure.as_deref())
5219    }
5220
5221    pub fn format(
5222        &mut self,
5223        buffers: HashSet<Model<Buffer>>,
5224        push_to_history: bool,
5225        trigger: FormatTrigger,
5226        cx: &mut ModelContext<Self>,
5227    ) -> Task<anyhow::Result<ProjectTransaction>> {
5228        if let Some(_) = self.as_local() {
5229            let buffers_with_paths = buffers
5230                .into_iter()
5231                .map(|buffer_handle| {
5232                    let buffer = buffer_handle.read(cx);
5233                    let buffer_abs_path = File::from_dyn(buffer.file())
5234                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
5235                    (buffer_handle, buffer_abs_path)
5236                })
5237                .collect::<Vec<_>>();
5238
5239            cx.spawn(move |lsp_store, mut cx| async move {
5240                let result = LocalLspStore::format_locally(
5241                    lsp_store.clone(),
5242                    buffers_with_paths,
5243                    push_to_history,
5244                    trigger,
5245                    cx.clone(),
5246                )
5247                .await;
5248
5249                lsp_store.update(&mut cx, |lsp_store, _| {
5250                    let local = lsp_store.as_local_mut().unwrap();
5251                    match &result {
5252                        Ok(_) => local.last_formatting_failure = None,
5253                        Err(error) => {
5254                            local.last_formatting_failure.replace(error.to_string());
5255                        }
5256                    }
5257                })?;
5258
5259                result
5260            })
5261        } else if let Some((client, project_id)) = self.upstream_client() {
5262            cx.spawn(move |this, mut cx| async move {
5263                let response = client
5264                    .request(proto::FormatBuffers {
5265                        project_id,
5266                        trigger: trigger as i32,
5267                        buffer_ids: buffers
5268                            .iter()
5269                            .map(|buffer| {
5270                                buffer.update(&mut cx, |buffer, _| buffer.remote_id().into())
5271                            })
5272                            .collect::<Result<_>>()?,
5273                    })
5274                    .await?
5275                    .transaction
5276                    .ok_or_else(|| anyhow!("missing transaction"))?;
5277                BufferStore::deserialize_project_transaction(
5278                    this.read_with(&cx, |this, _| this.buffer_store.downgrade())?,
5279                    response,
5280                    push_to_history,
5281                    cx,
5282                )
5283                .await
5284            })
5285        } else {
5286            Task::ready(Ok(ProjectTransaction::default()))
5287        }
5288    }
5289
5290    async fn handle_format_buffers(
5291        this: Model<Self>,
5292        envelope: TypedEnvelope<proto::FormatBuffers>,
5293        mut cx: AsyncAppContext,
5294    ) -> Result<proto::FormatBuffersResponse> {
5295        let sender_id = envelope.original_sender_id().unwrap_or_default();
5296        let format = this.update(&mut cx, |this, cx| {
5297            let mut buffers = HashSet::default();
5298            for buffer_id in &envelope.payload.buffer_ids {
5299                let buffer_id = BufferId::new(*buffer_id)?;
5300                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
5301            }
5302            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
5303            Ok::<_, anyhow::Error>(this.format(buffers, false, trigger, cx))
5304        })??;
5305
5306        let project_transaction = format.await?;
5307        let project_transaction = this.update(&mut cx, |this, cx| {
5308            this.buffer_store.update(cx, |buffer_store, cx| {
5309                buffer_store.serialize_project_transaction_for_peer(
5310                    project_transaction,
5311                    sender_id,
5312                    cx,
5313                )
5314            })
5315        })?;
5316        Ok(proto::FormatBuffersResponse {
5317            transaction: Some(project_transaction),
5318        })
5319    }
5320
5321    fn language_settings<'a>(
5322        &'a self,
5323        worktree: &'a Model<Worktree>,
5324        language: &LanguageName,
5325        cx: &'a mut ModelContext<Self>,
5326    ) -> &'a LanguageSettings {
5327        let root_file = worktree.update(cx, |tree, cx| tree.root_file(cx));
5328        all_language_settings(root_file.map(|f| f as _).as_ref(), cx).language(Some(language))
5329    }
5330
5331    pub fn start_language_servers(
5332        &mut self,
5333        worktree: &Model<Worktree>,
5334        language: LanguageName,
5335        cx: &mut ModelContext<Self>,
5336    ) {
5337        let settings = self.language_settings(worktree, &language, cx);
5338        if !settings.enable_language_server || self.mode.is_remote() {
5339            return;
5340        }
5341
5342        let available_lsp_adapters = self.languages.clone().lsp_adapters(&language);
5343        let available_language_servers = available_lsp_adapters
5344            .iter()
5345            .map(|lsp_adapter| lsp_adapter.name.clone())
5346            .collect::<Vec<_>>();
5347
5348        let desired_language_servers =
5349            settings.customized_language_servers(&available_language_servers);
5350
5351        let mut enabled_lsp_adapters: Vec<Arc<CachedLspAdapter>> = Vec::new();
5352        for desired_language_server in desired_language_servers {
5353            if let Some(adapter) = available_lsp_adapters
5354                .iter()
5355                .find(|adapter| adapter.name == desired_language_server)
5356            {
5357                enabled_lsp_adapters.push(adapter.clone());
5358                continue;
5359            }
5360
5361            if let Some(adapter) = self
5362                .languages
5363                .load_available_lsp_adapter(&desired_language_server)
5364            {
5365                self.languages
5366                    .register_lsp_adapter(language.clone(), adapter.adapter.clone());
5367                enabled_lsp_adapters.push(adapter);
5368                continue;
5369            }
5370
5371            log::warn!(
5372                "no language server found matching '{}'",
5373                desired_language_server.0
5374            );
5375        }
5376
5377        for adapter in &enabled_lsp_adapters {
5378            self.start_language_server(worktree, adapter.clone(), language.clone(), cx);
5379        }
5380
5381        // After starting all the language servers, reorder them to reflect the desired order
5382        // based on the settings.
5383        //
5384        // This is done, in part, to ensure that language servers loaded at different points
5385        // (e.g., native vs extension) still end up in the right order at the end, rather than
5386        // it being based on which language server happened to be loaded in first.
5387        self.languages
5388            .reorder_language_servers(&language, enabled_lsp_adapters);
5389    }
5390
5391    fn start_language_server_on_ssh_host(
5392        &mut self,
5393        worktree: &Model<Worktree>,
5394        adapter: Arc<CachedLspAdapter>,
5395        language: LanguageName,
5396        cx: &mut ModelContext<Self>,
5397    ) {
5398        let ssh = self.as_ssh().unwrap();
5399
5400        let delegate = Arc::new(SshLspAdapterDelegate {
5401            lsp_store: cx.handle().downgrade(),
5402            worktree: worktree.read(cx).snapshot(),
5403            upstream_client: ssh.upstream_client.clone(),
5404            language_registry: self.languages.clone(),
5405        }) as Arc<dyn LspAdapterDelegate>;
5406
5407        // TODO: We should use `adapter` here instead of reaching through the `CachedLspAdapter`.
5408        let lsp_adapter = adapter.adapter.clone();
5409
5410        let Some((upstream_client, project_id)) = self.upstream_client() else {
5411            return;
5412        };
5413        let worktree_id = worktree.read(cx).id().to_proto();
5414        let name = adapter.name().to_string();
5415
5416        let Some(available_language) = self.languages.available_language_for_name(&language) else {
5417            log::error!("failed to find available language {language}");
5418            return;
5419        };
5420
5421        let task = cx.spawn(|_, cx| async move {
5422            let user_binary_task = lsp_adapter.check_if_user_installed(delegate.as_ref(), &cx);
5423            let binary = match user_binary_task.await {
5424                Some(binary) => binary,
5425                None => {
5426                    return Err(anyhow!(
5427                        "Downloading language server for ssh host is not supported yet"
5428                    ))
5429                }
5430            };
5431
5432            let name = adapter.name();
5433            let code_action_kinds = adapter
5434                .adapter
5435                .code_action_kinds()
5436                .map(|kinds| serde_json::to_string(&kinds))
5437                .transpose()?;
5438            let get_options = adapter.adapter.clone().initialization_options(&delegate);
5439            let initialization_options = get_options
5440                .await?
5441                .map(|options| serde_json::to_string(&options))
5442                .transpose()?;
5443
5444            let language_server_command = proto::LanguageServerCommand {
5445                path: binary.path.to_string_lossy().to_string(),
5446                arguments: binary
5447                    .arguments
5448                    .iter()
5449                    .map(|args| args.to_string_lossy().to_string())
5450                    .collect(),
5451                env: binary.env.unwrap_or_default().into_iter().collect(),
5452            };
5453
5454            upstream_client
5455                .request(proto::CreateLanguageServer {
5456                    project_id,
5457                    worktree_id,
5458                    name: name.0.to_string(),
5459                    binary: Some(language_server_command),
5460                    initialization_options,
5461                    code_action_kinds,
5462                    language: Some(proto::AvailableLanguage {
5463                        name: language.to_proto(),
5464                        matcher: serde_json::to_string(&available_language.matcher())?,
5465                    }),
5466                })
5467                .await
5468        });
5469        cx.spawn(|this, mut cx| async move {
5470            if let Err(e) = task.await {
5471                this.update(&mut cx, |_this, cx| {
5472                    cx.emit(LspStoreEvent::Notification(format!(
5473                        "failed to start {}: {}",
5474                        name, e
5475                    )))
5476                })
5477                .ok();
5478            }
5479        })
5480        .detach();
5481    }
5482
5483    fn start_language_server(
5484        &mut self,
5485        worktree_handle: &Model<Worktree>,
5486        adapter: Arc<CachedLspAdapter>,
5487        language: LanguageName,
5488        cx: &mut ModelContext<Self>,
5489    ) {
5490        if self.mode.is_remote() {
5491            return;
5492        }
5493
5494        let worktree = worktree_handle.read(cx);
5495        let worktree_id = worktree.id();
5496        let worktree_path = worktree.abs_path();
5497        let key = (worktree_id, adapter.name.clone());
5498        if self.language_server_ids.contains_key(&key) {
5499            return;
5500        }
5501
5502        if self.mode.is_ssh() {
5503            self.start_language_server_on_ssh_host(worktree_handle, adapter, language, cx);
5504            return;
5505        }
5506
5507        if adapter.reinstall_attempt_count.load(SeqCst) > MAX_SERVER_REINSTALL_ATTEMPT_COUNT {
5508            return;
5509        }
5510
5511        let local = self.as_local().unwrap();
5512
5513        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
5514        let lsp_adapter_delegate = LocalLspAdapterDelegate::for_local(self, worktree_handle, cx);
5515        let project_environment = local.environment.update(cx, |environment, cx| {
5516            environment.get_environment(Some(worktree_id), Some(worktree_path.clone()), cx)
5517        });
5518
5519        let pending_server = match self.languages.create_pending_language_server(
5520            stderr_capture.clone(),
5521            language.clone(),
5522            adapter.clone(),
5523            Arc::clone(&worktree_path),
5524            lsp_adapter_delegate.clone(),
5525            project_environment,
5526            cx,
5527        ) {
5528            Some(pending_server) => pending_server,
5529            None => return,
5530        };
5531
5532        let project_settings = ProjectSettings::get(
5533            Some(SettingsLocation {
5534                worktree_id,
5535                path: Path::new(""),
5536            }),
5537            cx,
5538        );
5539
5540        // We need some on the SSH client, and some on SSH host
5541        let lsp = project_settings.lsp.get(&adapter.name);
5542        let override_options = lsp.and_then(|s| s.initialization_options.clone());
5543
5544        let server_id = pending_server.server_id;
5545        let container_dir = pending_server.container_dir.clone();
5546        let state = LanguageServerState::Starting({
5547            let adapter = adapter.clone();
5548            let server_name = adapter.name.0.clone();
5549            let language = language.clone();
5550            let key = key.clone();
5551
5552            cx.spawn(move |this, mut cx| async move {
5553                let result = Self::setup_and_insert_language_server(
5554                    this.clone(),
5555                    lsp_adapter_delegate,
5556                    override_options,
5557                    pending_server,
5558                    adapter.clone(),
5559                    language.clone(),
5560                    server_id,
5561                    key,
5562                    &mut cx,
5563                )
5564                .await;
5565
5566                match result {
5567                    Ok(server) => {
5568                        stderr_capture.lock().take();
5569                        server
5570                    }
5571
5572                    Err(err) => {
5573                        log::error!("failed to start language server {server_name:?}: {err}");
5574                        log::error!("server stderr: {:?}", stderr_capture.lock().take());
5575
5576                        let this = this.upgrade()?;
5577                        let container_dir = container_dir?;
5578
5579                        let attempt_count = adapter.reinstall_attempt_count.fetch_add(1, SeqCst);
5580                        if attempt_count >= MAX_SERVER_REINSTALL_ATTEMPT_COUNT {
5581                            let max = MAX_SERVER_REINSTALL_ATTEMPT_COUNT;
5582                            log::error!("Hit {max} reinstallation attempts for {server_name:?}");
5583                            return None;
5584                        }
5585
5586                        log::info!(
5587                            "retrying installation of language server {server_name:?} in {}s",
5588                            SERVER_REINSTALL_DEBOUNCE_TIMEOUT.as_secs()
5589                        );
5590                        cx.background_executor()
5591                            .timer(SERVER_REINSTALL_DEBOUNCE_TIMEOUT)
5592                            .await;
5593
5594                        let installation_test_binary = adapter
5595                            .installation_test_binary(container_dir.to_path_buf())
5596                            .await;
5597
5598                        this.update(&mut cx, |_, cx| {
5599                            Self::check_errored_server(
5600                                language,
5601                                adapter,
5602                                server_id,
5603                                installation_test_binary,
5604                                cx,
5605                            )
5606                        })
5607                        .ok();
5608
5609                        None
5610                    }
5611                }
5612            })
5613        });
5614
5615        self.as_local_mut()
5616            .unwrap()
5617            .language_servers
5618            .insert(server_id, state);
5619        self.language_server_ids.insert(key, server_id);
5620    }
5621
5622    #[allow(clippy::too_many_arguments)]
5623    async fn setup_and_insert_language_server(
5624        this: WeakModel<Self>,
5625        delegate: Arc<dyn LspAdapterDelegate>,
5626        override_initialization_options: Option<serde_json::Value>,
5627        pending_server: PendingLanguageServer,
5628        adapter: Arc<CachedLspAdapter>,
5629        language: LanguageName,
5630        server_id: LanguageServerId,
5631        key: (WorktreeId, LanguageServerName),
5632        cx: &mut AsyncAppContext,
5633    ) -> Result<Option<Arc<LanguageServer>>> {
5634        let language_server = Self::setup_pending_language_server(
5635            this.clone(),
5636            override_initialization_options,
5637            pending_server,
5638            delegate,
5639            adapter.clone(),
5640            server_id,
5641            cx,
5642        )
5643        .await?;
5644
5645        let this = match this.upgrade() {
5646            Some(this) => this,
5647            None => return Err(anyhow!("failed to upgrade project handle")),
5648        };
5649
5650        this.update(cx, |this, cx| {
5651            this.insert_newly_running_language_server(
5652                language,
5653                adapter,
5654                language_server.clone(),
5655                server_id,
5656                key,
5657                cx,
5658            )
5659        })??;
5660
5661        Ok(Some(language_server))
5662    }
5663
5664    fn reinstall_language_server(
5665        &mut self,
5666        language: LanguageName,
5667        adapter: Arc<CachedLspAdapter>,
5668        server_id: LanguageServerId,
5669        cx: &mut ModelContext<Self>,
5670    ) -> Option<Task<()>> {
5671        log::info!("beginning to reinstall server");
5672
5673        if let Some(local) = self.as_local_mut() {
5674            let existing_server = match local.language_servers.remove(&server_id) {
5675                Some(LanguageServerState::Running { server, .. }) => Some(server),
5676                _ => None,
5677            };
5678
5679            self.worktree_store.update(cx, |store, cx| {
5680                for worktree in store.worktrees() {
5681                    let key = (worktree.read(cx).id(), adapter.name.clone());
5682                    self.language_server_ids.remove(&key);
5683                }
5684            });
5685
5686            Some(cx.spawn(move |this, mut cx| async move {
5687                if let Some(task) = existing_server.and_then(|server| server.shutdown()) {
5688                    log::info!("shutting down existing server");
5689                    task.await;
5690                }
5691
5692                // TODO: This is race-safe with regards to preventing new instances from
5693                // starting while deleting, but existing instances in other projects are going
5694                // to be very confused and messed up
5695                let Some(task) = this
5696                    .update(&mut cx, |this, cx| {
5697                        this.languages.delete_server_container(adapter.clone(), cx)
5698                    })
5699                    .log_err()
5700                else {
5701                    return;
5702                };
5703                task.await;
5704
5705                this.update(&mut cx, |this, cx| {
5706                    for worktree in this.worktree_store.read(cx).worktrees().collect::<Vec<_>>() {
5707                        this.start_language_server(
5708                            &worktree,
5709                            adapter.clone(),
5710                            language.clone(),
5711                            cx,
5712                        );
5713                    }
5714                })
5715                .ok();
5716            }))
5717        } else if let Some(_ssh_store) = self.as_ssh() {
5718            // TODO
5719            None
5720        } else {
5721            None
5722        }
5723    }
5724
5725    async fn shutdown_language_server(
5726        server_state: Option<LanguageServerState>,
5727        name: LanguageServerName,
5728        cx: AsyncAppContext,
5729    ) {
5730        let server = match server_state {
5731            Some(LanguageServerState::Starting(task)) => {
5732                let mut timer = cx
5733                    .background_executor()
5734                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
5735                    .fuse();
5736
5737                select! {
5738                    server = task.fuse() => server,
5739                    _ = timer => {
5740                        log::info!(
5741                            "timeout waiting for language server {} to finish launching before stopping",
5742                            name
5743                        );
5744                        None
5745                    },
5746                }
5747            }
5748
5749            Some(LanguageServerState::Running { server, .. }) => Some(server),
5750
5751            None => None,
5752        };
5753
5754        if let Some(server) = server {
5755            if let Some(shutdown) = server.shutdown() {
5756                shutdown.await;
5757            }
5758        }
5759    }
5760
5761    // Returns a list of all of the worktrees which no longer have a language server and the root path
5762    // for the stopped server
5763    pub fn stop_language_server(
5764        &mut self,
5765        worktree_id: WorktreeId,
5766        adapter_name: LanguageServerName,
5767        cx: &mut ModelContext<Self>,
5768    ) -> Task<Vec<WorktreeId>> {
5769        let key = (worktree_id, adapter_name);
5770        if self.mode.is_local() {
5771            if let Some(server_id) = self.language_server_ids.remove(&key) {
5772                let name = key.1;
5773                log::info!("stopping language server {name}");
5774
5775                // Remove other entries for this language server as well
5776                let mut orphaned_worktrees = vec![worktree_id];
5777                let other_keys = self.language_server_ids.keys().cloned().collect::<Vec<_>>();
5778                for other_key in other_keys {
5779                    if self.language_server_ids.get(&other_key) == Some(&server_id) {
5780                        self.language_server_ids.remove(&other_key);
5781                        orphaned_worktrees.push(other_key.0);
5782                    }
5783                }
5784
5785                self.buffer_store.update(cx, |buffer_store, cx| {
5786                    for buffer in buffer_store.buffers() {
5787                        buffer.update(cx, |buffer, cx| {
5788                            buffer.update_diagnostics(
5789                                server_id,
5790                                DiagnosticSet::new([], buffer),
5791                                cx,
5792                            );
5793                        });
5794                    }
5795                });
5796
5797                for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
5798                    summaries.retain(|path, summaries_by_server_id| {
5799                        if summaries_by_server_id.remove(&server_id).is_some() {
5800                            if let Some((client, project_id)) = self.downstream_client.clone() {
5801                                client
5802                                    .send(proto::UpdateDiagnosticSummary {
5803                                        project_id,
5804                                        worktree_id: worktree_id.to_proto(),
5805                                        summary: Some(proto::DiagnosticSummary {
5806                                            path: path.to_string_lossy().to_string(),
5807                                            language_server_id: server_id.0 as u64,
5808                                            error_count: 0,
5809                                            warning_count: 0,
5810                                        }),
5811                                    })
5812                                    .log_err();
5813                            }
5814                            !summaries_by_server_id.is_empty()
5815                        } else {
5816                            true
5817                        }
5818                    });
5819                }
5820
5821                for diagnostics in self.diagnostics.values_mut() {
5822                    diagnostics.retain(|_, diagnostics_by_server_id| {
5823                        if let Ok(ix) =
5824                            diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0)
5825                        {
5826                            diagnostics_by_server_id.remove(ix);
5827                            !diagnostics_by_server_id.is_empty()
5828                        } else {
5829                            true
5830                        }
5831                    });
5832                }
5833
5834                self.as_local_mut()
5835                    .unwrap()
5836                    .language_server_watched_paths
5837                    .remove(&server_id);
5838                self.language_server_statuses.remove(&server_id);
5839                cx.notify();
5840
5841                let server_state = self
5842                    .as_local_mut()
5843                    .unwrap()
5844                    .language_servers
5845                    .remove(&server_id);
5846                cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
5847                cx.spawn(move |_, cx| async move {
5848                    Self::shutdown_language_server(server_state, name, cx).await;
5849                    orphaned_worktrees
5850                })
5851            } else {
5852                Task::ready(Vec::new())
5853            }
5854        } else if self.mode.is_ssh() {
5855            // TODO ssh
5856            Task::ready(Vec::new())
5857        } else {
5858            Task::ready(Vec::new())
5859        }
5860    }
5861
5862    pub fn restart_language_servers_for_buffers(
5863        &mut self,
5864        buffers: impl IntoIterator<Item = Model<Buffer>>,
5865        cx: &mut ModelContext<Self>,
5866    ) {
5867        if let Some((client, project_id)) = self.upstream_client() {
5868            let request = client.request(proto::RestartLanguageServers {
5869                project_id,
5870                buffer_ids: buffers
5871                    .into_iter()
5872                    .map(|b| b.read(cx).remote_id().to_proto())
5873                    .collect(),
5874            });
5875            cx.background_executor()
5876                .spawn(request)
5877                .detach_and_log_err(cx);
5878        } else {
5879            #[allow(clippy::mutable_key_type)]
5880            let language_server_lookup_info: HashSet<(Model<Worktree>, LanguageName)> = buffers
5881                .into_iter()
5882                .filter_map(|buffer| {
5883                    let buffer = buffer.read(cx);
5884                    let file = buffer.file()?;
5885                    let worktree = File::from_dyn(Some(file))?.worktree.clone();
5886                    let language =
5887                        self.languages
5888                            .language_for_file(file, Some(buffer.as_rope()), cx)?;
5889
5890                    Some((worktree, language.name()))
5891                })
5892                .collect();
5893
5894            for (worktree, language) in language_server_lookup_info {
5895                self.restart_language_servers(worktree, language, cx);
5896            }
5897        }
5898    }
5899
5900    pub fn restart_language_servers(
5901        &mut self,
5902        worktree: Model<Worktree>,
5903        language: LanguageName,
5904        cx: &mut ModelContext<Self>,
5905    ) {
5906        let worktree_id = worktree.read(cx).id();
5907
5908        let stop_tasks = self
5909            .languages
5910            .clone()
5911            .lsp_adapters(&language)
5912            .iter()
5913            .map(|adapter| {
5914                let stop_task = self.stop_language_server(worktree_id, adapter.name.clone(), cx);
5915                (stop_task, adapter.name.clone())
5916            })
5917            .collect::<Vec<_>>();
5918        if stop_tasks.is_empty() {
5919            return;
5920        }
5921
5922        cx.spawn(move |this, mut cx| async move {
5923            // For each stopped language server, record all of the worktrees with which
5924            // it was associated.
5925            let mut affected_worktrees = Vec::new();
5926            for (stop_task, language_server_name) in stop_tasks {
5927                for affected_worktree_id in stop_task.await {
5928                    affected_worktrees.push((affected_worktree_id, language_server_name.clone()));
5929                }
5930            }
5931
5932            this.update(&mut cx, |this, cx| {
5933                // Restart the language server for the given worktree.
5934                this.start_language_servers(&worktree, language.clone(), cx);
5935
5936                // Lookup new server ids and set them for each of the orphaned worktrees
5937                for (affected_worktree_id, language_server_name) in affected_worktrees {
5938                    if let Some(new_server_id) = this
5939                        .language_server_ids
5940                        .get(&(worktree_id, language_server_name.clone()))
5941                        .cloned()
5942                    {
5943                        this.language_server_ids
5944                            .insert((affected_worktree_id, language_server_name), new_server_id);
5945                    }
5946                }
5947            })
5948            .ok();
5949        })
5950        .detach();
5951    }
5952
5953    fn check_errored_server(
5954        language: LanguageName,
5955        adapter: Arc<CachedLspAdapter>,
5956        server_id: LanguageServerId,
5957        installation_test_binary: Option<LanguageServerBinary>,
5958        cx: &mut ModelContext<Self>,
5959    ) {
5960        if !adapter.can_be_reinstalled() {
5961            log::info!(
5962                "Validation check requested for {:?} but it cannot be reinstalled",
5963                adapter.name.0
5964            );
5965            return;
5966        }
5967
5968        cx.spawn(move |this, mut cx| async move {
5969            log::info!("About to spawn test binary");
5970
5971            // A lack of test binary counts as a failure
5972            let process = installation_test_binary.and_then(|binary| {
5973                smol::process::Command::new(&binary.path)
5974                    .current_dir(&binary.path)
5975                    .args(binary.arguments)
5976                    .stdin(Stdio::piped())
5977                    .stdout(Stdio::piped())
5978                    .stderr(Stdio::inherit())
5979                    .kill_on_drop(true)
5980                    .spawn()
5981                    .ok()
5982            });
5983
5984            const PROCESS_TIMEOUT: Duration = Duration::from_secs(5);
5985            let mut timeout = cx.background_executor().timer(PROCESS_TIMEOUT).fuse();
5986
5987            let mut errored = false;
5988            if let Some(mut process) = process {
5989                futures::select! {
5990                    status = process.status().fuse() => match status {
5991                        Ok(status) => errored = !status.success(),
5992                        Err(_) => errored = true,
5993                    },
5994
5995                    _ = timeout => {
5996                        log::info!("test binary time-ed out, this counts as a success");
5997                        _ = process.kill();
5998                    }
5999                }
6000            } else {
6001                log::warn!("test binary failed to launch");
6002                errored = true;
6003            }
6004
6005            if errored {
6006                log::warn!("test binary check failed");
6007                let task = this
6008                    .update(&mut cx, move |this, cx| {
6009                        this.reinstall_language_server(language, adapter, server_id, cx)
6010                    })
6011                    .ok()
6012                    .flatten();
6013
6014                if let Some(task) = task {
6015                    task.await;
6016                }
6017            }
6018        })
6019        .detach();
6020    }
6021
6022    async fn setup_pending_language_server(
6023        this: WeakModel<Self>,
6024        override_options: Option<serde_json::Value>,
6025        pending_server: PendingLanguageServer,
6026        delegate: Arc<dyn LspAdapterDelegate>,
6027        adapter: Arc<CachedLspAdapter>,
6028        server_id: LanguageServerId,
6029        cx: &mut AsyncAppContext,
6030    ) -> Result<Arc<LanguageServer>> {
6031        let workspace_config = adapter
6032            .adapter
6033            .clone()
6034            .workspace_configuration(&delegate, cx)
6035            .await?;
6036        // This has to come from the server
6037        let (language_server, mut initialization_options) = pending_server.task.await?;
6038
6039        let name = language_server.name();
6040        language_server
6041            .on_notification::<lsp::notification::PublishDiagnostics, _>({
6042                let adapter = adapter.clone();
6043                let this = this.clone();
6044                move |mut params, mut cx| {
6045                    let adapter = adapter.clone();
6046                    if let Some(this) = this.upgrade() {
6047                        adapter.process_diagnostics(&mut params);
6048                        // Everything else has to be on the server, Can we make it on the client?
6049                        this.update(&mut cx, |this, cx| {
6050                            this.update_diagnostics(
6051                                server_id,
6052                                params,
6053                                &adapter.disk_based_diagnostic_sources,
6054                                cx,
6055                            )
6056                            .log_err();
6057                        })
6058                        .ok();
6059                    }
6060                }
6061            })
6062            .detach();
6063
6064        language_server
6065            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
6066                let adapter = adapter.adapter.clone();
6067                let delegate = delegate.clone();
6068                move |params, mut cx| {
6069                    let adapter = adapter.clone();
6070                    let delegate = delegate.clone();
6071                    async move {
6072                        let workspace_config =
6073                            adapter.workspace_configuration(&delegate, &mut cx).await?;
6074                        Ok(params
6075                            .items
6076                            .into_iter()
6077                            .map(|item| {
6078                                if let Some(section) = &item.section {
6079                                    workspace_config
6080                                        .get(section)
6081                                        .cloned()
6082                                        .unwrap_or(serde_json::Value::Null)
6083                                } else {
6084                                    workspace_config.clone()
6085                                }
6086                            })
6087                            .collect())
6088                    }
6089                }
6090            })
6091            .detach();
6092
6093        let id = language_server.server_id();
6094        language_server
6095            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
6096                let this = this.clone();
6097                move |_, mut cx| {
6098                    let this = this.clone();
6099                    async move {
6100                        let Some(server) =
6101                            this.update(&mut cx, |this, _| this.language_server_for_id(id))?
6102                        else {
6103                            return Ok(None);
6104                        };
6105                        let root = server.root_path();
6106                        let Ok(uri) = Url::from_file_path(&root) else {
6107                            return Ok(None);
6108                        };
6109                        Ok(Some(vec![WorkspaceFolder {
6110                            uri,
6111                            name: Default::default(),
6112                        }]))
6113                    }
6114                }
6115            })
6116            .detach();
6117        // Even though we don't have handling for these requests, respond to them to
6118        // avoid stalling any language server like `gopls` which waits for a response
6119        // to these requests when initializing.
6120        language_server
6121            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
6122                let this = this.clone();
6123                move |params, mut cx| {
6124                    let this = this.clone();
6125                    async move {
6126                        this.update(&mut cx, |this, _| {
6127                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
6128                            {
6129                                if let lsp::NumberOrString::String(token) = params.token {
6130                                    status.progress_tokens.insert(token);
6131                                }
6132                            }
6133                        })?;
6134
6135                        Ok(())
6136                    }
6137                }
6138            })
6139            .detach();
6140
6141        language_server
6142            .on_request::<lsp::request::RegisterCapability, _, _>({
6143                let this = this.clone();
6144                move |params, mut cx| {
6145                    let this = this.clone();
6146                    async move {
6147                        for reg in params.registrations {
6148                            match reg.method.as_str() {
6149                                "workspace/didChangeWatchedFiles" => {
6150                                    if let Some(options) = reg.register_options {
6151                                        let options = serde_json::from_value(options)?;
6152                                        this.update(&mut cx, |this, cx| {
6153                                            this.on_lsp_did_change_watched_files(
6154                                                server_id, &reg.id, options, cx,
6155                                            );
6156                                        })?;
6157                                    }
6158                                }
6159                                "textDocument/rangeFormatting" => {
6160                                    this.update(&mut cx, |this, _| {
6161                                        if let Some(server) = this.language_server_for_id(server_id)
6162                                        {
6163                                            let options = reg
6164                                                .register_options
6165                                                .map(|options| {
6166                                                    serde_json::from_value::<
6167                                                        lsp::DocumentRangeFormattingOptions,
6168                                                    >(
6169                                                        options
6170                                                    )
6171                                                })
6172                                                .transpose()?;
6173                                            let provider = match options {
6174                                                None => OneOf::Left(true),
6175                                                Some(options) => OneOf::Right(options),
6176                                            };
6177                                            server.update_capabilities(|capabilities| {
6178                                                capabilities.document_range_formatting_provider =
6179                                                    Some(provider);
6180                                            })
6181                                        }
6182                                        anyhow::Ok(())
6183                                    })??;
6184                                }
6185                                "textDocument/onTypeFormatting" => {
6186                                    this.update(&mut cx, |this, _| {
6187                                        if let Some(server) = this.language_server_for_id(server_id)
6188                                        {
6189                                            let options = reg
6190                                                .register_options
6191                                                .map(|options| {
6192                                                    serde_json::from_value::<
6193                                                        lsp::DocumentOnTypeFormattingOptions,
6194                                                    >(
6195                                                        options
6196                                                    )
6197                                                })
6198                                                .transpose()?;
6199                                            if let Some(options) = options {
6200                                                server.update_capabilities(|capabilities| {
6201                                                    capabilities
6202                                                        .document_on_type_formatting_provider =
6203                                                        Some(options);
6204                                                })
6205                                            }
6206                                        }
6207                                        anyhow::Ok(())
6208                                    })??;
6209                                }
6210                                "textDocument/formatting" => {
6211                                    this.update(&mut cx, |this, _| {
6212                                        if let Some(server) = this.language_server_for_id(server_id)
6213                                        {
6214                                            let options = reg
6215                                                .register_options
6216                                                .map(|options| {
6217                                                    serde_json::from_value::<
6218                                                        lsp::DocumentFormattingOptions,
6219                                                    >(
6220                                                        options
6221                                                    )
6222                                                })
6223                                                .transpose()?;
6224                                            let provider = match options {
6225                                                None => OneOf::Left(true),
6226                                                Some(options) => OneOf::Right(options),
6227                                            };
6228                                            server.update_capabilities(|capabilities| {
6229                                                capabilities.document_formatting_provider =
6230                                                    Some(provider);
6231                                            })
6232                                        }
6233                                        anyhow::Ok(())
6234                                    })??;
6235                                }
6236                                _ => log::warn!("unhandled capability registration: {reg:?}"),
6237                            }
6238                        }
6239                        Ok(())
6240                    }
6241                }
6242            })
6243            .detach();
6244
6245        language_server
6246            .on_request::<lsp::request::UnregisterCapability, _, _>({
6247                let this = this.clone();
6248                move |params, mut cx| {
6249                    let this = this.clone();
6250                    async move {
6251                        for unreg in params.unregisterations.iter() {
6252                            match unreg.method.as_str() {
6253                                "workspace/didChangeWatchedFiles" => {
6254                                    this.update(&mut cx, |this, cx| {
6255                                        this.on_lsp_unregister_did_change_watched_files(
6256                                            server_id, &unreg.id, cx,
6257                                        );
6258                                    })?;
6259                                }
6260                                "textDocument/rangeFormatting" => {
6261                                    this.update(&mut cx, |this, _| {
6262                                        if let Some(server) = this.language_server_for_id(server_id)
6263                                        {
6264                                            server.update_capabilities(|capabilities| {
6265                                                capabilities.document_range_formatting_provider =
6266                                                    None
6267                                            })
6268                                        }
6269                                    })?;
6270                                }
6271                                "textDocument/onTypeFormatting" => {
6272                                    this.update(&mut cx, |this, _| {
6273                                        if let Some(server) = this.language_server_for_id(server_id)
6274                                        {
6275                                            server.update_capabilities(|capabilities| {
6276                                                capabilities.document_on_type_formatting_provider =
6277                                                    None;
6278                                            })
6279                                        }
6280                                    })?;
6281                                }
6282                                "textDocument/formatting" => {
6283                                    this.update(&mut cx, |this, _| {
6284                                        if let Some(server) = this.language_server_for_id(server_id)
6285                                        {
6286                                            server.update_capabilities(|capabilities| {
6287                                                capabilities.document_formatting_provider = None;
6288                                            })
6289                                        }
6290                                    })?;
6291                                }
6292                                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
6293                            }
6294                        }
6295                        Ok(())
6296                    }
6297                }
6298            })
6299            .detach();
6300
6301        language_server
6302            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
6303                let adapter = adapter.clone();
6304                let this = this.clone();
6305                move |params, cx| {
6306                    Self::on_lsp_workspace_edit(
6307                        this.clone(),
6308                        params,
6309                        server_id,
6310                        adapter.clone(),
6311                        cx,
6312                    )
6313                }
6314            })
6315            .detach();
6316
6317        language_server
6318            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
6319                let this = this.clone();
6320                move |(), mut cx| {
6321                    let this = this.clone();
6322                    async move {
6323                        this.update(&mut cx, |this, cx| {
6324                            cx.emit(LspStoreEvent::RefreshInlayHints);
6325                            this.downstream_client.as_ref().map(|(client, project_id)| {
6326                                client.send(proto::RefreshInlayHints {
6327                                    project_id: *project_id,
6328                                })
6329                            })
6330                        })?
6331                        .transpose()?;
6332                        Ok(())
6333                    }
6334                }
6335            })
6336            .detach();
6337
6338        language_server
6339            .on_request::<lsp::request::ShowMessageRequest, _, _>({
6340                let this = this.clone();
6341                let name = name.to_string();
6342                move |params, mut cx| {
6343                    let this = this.clone();
6344                    let name = name.to_string();
6345                    async move {
6346                        let actions = params.actions.unwrap_or_default();
6347                        let (tx, mut rx) = smol::channel::bounded(1);
6348                        let request = LanguageServerPromptRequest {
6349                            level: match params.typ {
6350                                lsp::MessageType::ERROR => PromptLevel::Critical,
6351                                lsp::MessageType::WARNING => PromptLevel::Warning,
6352                                _ => PromptLevel::Info,
6353                            },
6354                            message: params.message,
6355                            actions,
6356                            response_channel: tx,
6357                            lsp_name: name.clone(),
6358                        };
6359
6360                        let did_update = this
6361                            .update(&mut cx, |_, cx| {
6362                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
6363                            })
6364                            .is_ok();
6365                        if did_update {
6366                            let response = rx.next().await;
6367
6368                            Ok(response)
6369                        } else {
6370                            Ok(None)
6371                        }
6372                    }
6373                }
6374            })
6375            .detach();
6376
6377        let disk_based_diagnostics_progress_token =
6378            adapter.disk_based_diagnostics_progress_token.clone();
6379
6380        language_server
6381            .on_notification::<ServerStatus, _>({
6382                let this = this.clone();
6383                let name = name.to_string();
6384                move |params, mut cx| {
6385                    let this = this.clone();
6386                    let name = name.to_string();
6387                    if let Some(ref message) = params.message {
6388                        let message = message.trim();
6389                        if !message.is_empty() {
6390                            let formatted_message = format!(
6391                                "Language server {name} (id {server_id}) status update: {message}"
6392                            );
6393                            match params.health {
6394                                ServerHealthStatus::Ok => log::info!("{}", formatted_message),
6395                                ServerHealthStatus::Warning => log::warn!("{}", formatted_message),
6396                                ServerHealthStatus::Error => {
6397                                    log::error!("{}", formatted_message);
6398                                    let (tx, _rx) = smol::channel::bounded(1);
6399                                    let request = LanguageServerPromptRequest {
6400                                        level: PromptLevel::Critical,
6401                                        message: params.message.unwrap_or_default(),
6402                                        actions: Vec::new(),
6403                                        response_channel: tx,
6404                                        lsp_name: name.clone(),
6405                                    };
6406                                    let _ = this
6407                                        .update(&mut cx, |_, cx| {
6408                                            cx.emit(LspStoreEvent::LanguageServerPrompt(request));
6409                                        })
6410                                        .ok();
6411                                }
6412                                ServerHealthStatus::Other(status) => {
6413                                    log::info!(
6414                                        "Unknown server health: {status}\n{formatted_message}"
6415                                    )
6416                                }
6417                            }
6418                        }
6419                    }
6420                }
6421            })
6422            .detach();
6423        language_server
6424            .on_notification::<lsp::notification::ShowMessage, _>({
6425                let this = this.clone();
6426                let name = name.to_string();
6427                move |params, mut cx| {
6428                    let this = this.clone();
6429                    let name = name.to_string();
6430
6431                    let (tx, _) = smol::channel::bounded(1);
6432                    let request = LanguageServerPromptRequest {
6433                        level: match params.typ {
6434                            lsp::MessageType::ERROR => PromptLevel::Critical,
6435                            lsp::MessageType::WARNING => PromptLevel::Warning,
6436                            _ => PromptLevel::Info,
6437                        },
6438                        message: params.message,
6439                        actions: vec![],
6440                        response_channel: tx,
6441                        lsp_name: name.clone(),
6442                    };
6443
6444                    let _ = this.update(&mut cx, |_, cx| {
6445                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
6446                    });
6447                }
6448            })
6449            .detach();
6450        language_server
6451            .on_notification::<lsp::notification::Progress, _>({
6452                let this = this.clone();
6453                move |params, mut cx| {
6454                    if let Some(this) = this.upgrade() {
6455                        this.update(&mut cx, |this, cx| {
6456                            this.on_lsp_progress(
6457                                params,
6458                                server_id,
6459                                disk_based_diagnostics_progress_token.clone(),
6460                                cx,
6461                            );
6462                        })
6463                        .ok();
6464                    }
6465                }
6466            })
6467            .detach();
6468
6469        language_server
6470            .on_notification::<lsp::notification::LogMessage, _>({
6471                let this = this.clone();
6472                move |params, mut cx| {
6473                    if let Some(this) = this.upgrade() {
6474                        this.update(&mut cx, |_, cx| {
6475                            cx.emit(LspStoreEvent::LanguageServerLog(
6476                                server_id,
6477                                LanguageServerLogType::Log(params.typ),
6478                                params.message,
6479                            ));
6480                        })
6481                        .ok();
6482                    }
6483                }
6484            })
6485            .detach();
6486
6487        language_server
6488            .on_notification::<lsp::notification::LogTrace, _>({
6489                let this = this.clone();
6490                move |params, mut cx| {
6491                    if let Some(this) = this.upgrade() {
6492                        this.update(&mut cx, |_, cx| {
6493                            cx.emit(LspStoreEvent::LanguageServerLog(
6494                                server_id,
6495                                LanguageServerLogType::Trace(params.verbose),
6496                                params.message,
6497                            ));
6498                        })
6499                        .ok();
6500                    }
6501                }
6502            })
6503            .detach();
6504
6505        match (&mut initialization_options, override_options) {
6506            (Some(initialization_options), Some(override_options)) => {
6507                merge_json_value_into(override_options, initialization_options);
6508            }
6509            (None, override_options) => initialization_options = override_options,
6510            _ => {}
6511        }
6512
6513        let language_server = cx
6514            .update(|cx| language_server.initialize(initialization_options, cx))?
6515            .await
6516            .inspect_err(|_| {
6517                if let Some(this) = this.upgrade() {
6518                    this.update(cx, |_, cx| {
6519                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
6520                    })
6521                    .ok();
6522                }
6523            })?;
6524
6525        language_server
6526            .notify::<lsp::notification::DidChangeConfiguration>(
6527                lsp::DidChangeConfigurationParams {
6528                    settings: workspace_config,
6529                },
6530            )
6531            .ok();
6532
6533        Ok(language_server)
6534    }
6535
6536    pub fn update_diagnostics(
6537        &mut self,
6538        language_server_id: LanguageServerId,
6539        mut params: lsp::PublishDiagnosticsParams,
6540        disk_based_sources: &[String],
6541        cx: &mut ModelContext<Self>,
6542    ) -> Result<()> {
6543        let abs_path = params
6544            .uri
6545            .to_file_path()
6546            .map_err(|_| anyhow!("URI is not a file"))?;
6547        let mut diagnostics = Vec::default();
6548        let mut primary_diagnostic_group_ids = HashMap::default();
6549        let mut sources_by_group_id = HashMap::default();
6550        let mut supporting_diagnostics = HashMap::default();
6551
6552        // Ensure that primary diagnostics are always the most severe
6553        params.diagnostics.sort_by_key(|item| item.severity);
6554
6555        for diagnostic in &params.diagnostics {
6556            let source = diagnostic.source.as_ref();
6557            let code = diagnostic.code.as_ref().map(|code| match code {
6558                lsp::NumberOrString::Number(code) => code.to_string(),
6559                lsp::NumberOrString::String(code) => code.clone(),
6560            });
6561            let range = range_from_lsp(diagnostic.range);
6562            let is_supporting = diagnostic
6563                .related_information
6564                .as_ref()
6565                .map_or(false, |infos| {
6566                    infos.iter().any(|info| {
6567                        primary_diagnostic_group_ids.contains_key(&(
6568                            source,
6569                            code.clone(),
6570                            range_from_lsp(info.location.range),
6571                        ))
6572                    })
6573                });
6574
6575            let is_unnecessary = diagnostic.tags.as_ref().map_or(false, |tags| {
6576                tags.iter().any(|tag| *tag == DiagnosticTag::UNNECESSARY)
6577            });
6578
6579            if is_supporting {
6580                supporting_diagnostics.insert(
6581                    (source, code.clone(), range),
6582                    (diagnostic.severity, is_unnecessary),
6583                );
6584            } else {
6585                let group_id = post_inc(&mut self.next_diagnostic_group_id);
6586                let is_disk_based =
6587                    source.map_or(false, |source| disk_based_sources.contains(source));
6588
6589                sources_by_group_id.insert(group_id, source);
6590                primary_diagnostic_group_ids
6591                    .insert((source, code.clone(), range.clone()), group_id);
6592
6593                diagnostics.push(DiagnosticEntry {
6594                    range,
6595                    diagnostic: Diagnostic {
6596                        source: diagnostic.source.clone(),
6597                        code: code.clone(),
6598                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
6599                        message: diagnostic.message.trim().to_string(),
6600                        group_id,
6601                        is_primary: true,
6602                        is_disk_based,
6603                        is_unnecessary,
6604                        data: diagnostic.data.clone(),
6605                    },
6606                });
6607                if let Some(infos) = &diagnostic.related_information {
6608                    for info in infos {
6609                        if info.location.uri == params.uri && !info.message.is_empty() {
6610                            let range = range_from_lsp(info.location.range);
6611                            diagnostics.push(DiagnosticEntry {
6612                                range,
6613                                diagnostic: Diagnostic {
6614                                    source: diagnostic.source.clone(),
6615                                    code: code.clone(),
6616                                    severity: DiagnosticSeverity::INFORMATION,
6617                                    message: info.message.trim().to_string(),
6618                                    group_id,
6619                                    is_primary: false,
6620                                    is_disk_based,
6621                                    is_unnecessary: false,
6622                                    data: diagnostic.data.clone(),
6623                                },
6624                            });
6625                        }
6626                    }
6627                }
6628            }
6629        }
6630
6631        for entry in &mut diagnostics {
6632            let diagnostic = &mut entry.diagnostic;
6633            if !diagnostic.is_primary {
6634                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
6635                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
6636                    source,
6637                    diagnostic.code.clone(),
6638                    entry.range.clone(),
6639                )) {
6640                    if let Some(severity) = severity {
6641                        diagnostic.severity = severity;
6642                    }
6643                    diagnostic.is_unnecessary = is_unnecessary;
6644                }
6645            }
6646        }
6647
6648        self.update_diagnostic_entries(
6649            language_server_id,
6650            abs_path,
6651            params.version,
6652            diagnostics,
6653            cx,
6654        )?;
6655        Ok(())
6656    }
6657
6658    fn insert_newly_running_language_server(
6659        &mut self,
6660        language: LanguageName,
6661        adapter: Arc<CachedLspAdapter>,
6662        language_server: Arc<LanguageServer>,
6663        server_id: LanguageServerId,
6664        key: (WorktreeId, LanguageServerName),
6665        cx: &mut ModelContext<Self>,
6666    ) -> Result<()> {
6667        // If the language server for this key doesn't match the server id, don't store the
6668        // server. Which will cause it to be dropped, killing the process
6669        if self
6670            .language_server_ids
6671            .get(&key)
6672            .map(|id| id != &server_id)
6673            .unwrap_or(false)
6674        {
6675            return Ok(());
6676        }
6677
6678        // Update language_servers collection with Running variant of LanguageServerState
6679        // indicating that the server is up and running and ready
6680        if let Some(local) = self.as_local_mut() {
6681            local.language_servers.insert(
6682                server_id,
6683                LanguageServerState::Running {
6684                    adapter: adapter.clone(),
6685                    language: language.clone(),
6686                    server: language_server.clone(),
6687                    simulate_disk_based_diagnostics_completion: None,
6688                },
6689            );
6690        }
6691
6692        self.language_server_statuses.insert(
6693            server_id,
6694            LanguageServerStatus {
6695                name: language_server.name().to_string(),
6696                pending_work: Default::default(),
6697                has_pending_diagnostic_updates: false,
6698                progress_tokens: Default::default(),
6699            },
6700        );
6701
6702        cx.emit(LspStoreEvent::LanguageServerAdded(server_id));
6703
6704        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
6705            downstream_client.send(proto::StartLanguageServer {
6706                project_id: *project_id,
6707                server: Some(proto::LanguageServer {
6708                    id: server_id.0 as u64,
6709                    name: language_server.name().to_string(),
6710                }),
6711            })?;
6712        }
6713
6714        // Tell the language server about every open buffer in the worktree that matches the language.
6715        self.buffer_store.update(cx, |buffer_store, cx| {
6716            for buffer_handle in buffer_store.buffers() {
6717                let buffer = buffer_handle.read(cx);
6718                let file = match File::from_dyn(buffer.file()) {
6719                    Some(file) => file,
6720                    None => continue,
6721                };
6722                let language = match buffer.language() {
6723                    Some(language) => language,
6724                    None => continue,
6725                };
6726
6727                if file.worktree.read(cx).id() != key.0
6728                    || !self
6729                        .languages
6730                        .lsp_adapters(&language.name())
6731                        .iter()
6732                        .any(|a| a.name == key.1)
6733                {
6734                    continue;
6735                }
6736
6737                let file = match file.as_local() {
6738                    Some(file) => file,
6739                    None => continue,
6740                };
6741
6742                let versions = self
6743                    .buffer_snapshots
6744                    .entry(buffer.remote_id())
6745                    .or_default()
6746                    .entry(server_id)
6747                    .or_insert_with(|| {
6748                        vec![LspBufferSnapshot {
6749                            version: 0,
6750                            snapshot: buffer.text_snapshot(),
6751                        }]
6752                    });
6753
6754                let snapshot = versions.last().unwrap();
6755                let version = snapshot.version;
6756                let initial_snapshot = &snapshot.snapshot;
6757                let uri = lsp::Url::from_file_path(file.abs_path(cx)).unwrap();
6758                language_server.notify::<lsp::notification::DidOpenTextDocument>(
6759                    lsp::DidOpenTextDocumentParams {
6760                        text_document: lsp::TextDocumentItem::new(
6761                            uri,
6762                            adapter.language_id(&language.name()),
6763                            version,
6764                            initial_snapshot.text(),
6765                        ),
6766                    },
6767                )?;
6768
6769                buffer_handle.update(cx, |buffer, cx| {
6770                    buffer.set_completion_triggers(
6771                        language_server
6772                            .capabilities()
6773                            .completion_provider
6774                            .as_ref()
6775                            .and_then(|provider| provider.trigger_characters.clone())
6776                            .unwrap_or_default(),
6777                        cx,
6778                    )
6779                });
6780            }
6781            anyhow::Ok(())
6782        })?;
6783
6784        cx.notify();
6785        Ok(())
6786    }
6787
6788    fn buffer_snapshot_for_lsp_version(
6789        &mut self,
6790        buffer: &Model<Buffer>,
6791        server_id: LanguageServerId,
6792        version: Option<i32>,
6793        cx: &AppContext,
6794    ) -> Result<TextBufferSnapshot> {
6795        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
6796
6797        if let Some(version) = version {
6798            let buffer_id = buffer.read(cx).remote_id();
6799            let snapshots = self
6800                .buffer_snapshots
6801                .get_mut(&buffer_id)
6802                .and_then(|m| m.get_mut(&server_id))
6803                .ok_or_else(|| {
6804                    anyhow!("no snapshots found for buffer {buffer_id} and server {server_id}")
6805                })?;
6806
6807            let found_snapshot = snapshots
6808                .binary_search_by_key(&version, |e| e.version)
6809                .map(|ix| snapshots[ix].snapshot.clone())
6810                .map_err(|_| {
6811                    anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
6812                })?;
6813
6814            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
6815            Ok(found_snapshot)
6816        } else {
6817            Ok((buffer.read(cx)).text_snapshot())
6818        }
6819    }
6820
6821    pub fn language_servers_running_disk_based_diagnostics(
6822        &self,
6823    ) -> impl Iterator<Item = LanguageServerId> + '_ {
6824        self.language_server_statuses
6825            .iter()
6826            .filter_map(|(id, status)| {
6827                if status.has_pending_diagnostic_updates {
6828                    Some(*id)
6829                } else {
6830                    None
6831                }
6832            })
6833    }
6834
6835    pub(crate) fn language_servers_for_buffer<'a>(
6836        &'a self,
6837        buffer: &'a Buffer,
6838        cx: &'a AppContext,
6839    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
6840        self.language_server_ids_for_buffer(buffer, cx)
6841            .into_iter()
6842            .filter_map(
6843                |server_id| match self.as_local()?.language_servers.get(&server_id)? {
6844                    LanguageServerState::Running {
6845                        adapter, server, ..
6846                    } => Some((adapter, server)),
6847                    _ => None,
6848                },
6849            )
6850    }
6851
6852    pub(crate) fn cancel_language_server_work_for_buffers(
6853        &mut self,
6854        buffers: impl IntoIterator<Item = Model<Buffer>>,
6855        cx: &mut ModelContext<Self>,
6856    ) {
6857        let servers = buffers
6858            .into_iter()
6859            .flat_map(|buffer| {
6860                self.language_server_ids_for_buffer(buffer.read(cx), cx)
6861                    .into_iter()
6862            })
6863            .collect::<HashSet<_>>();
6864
6865        for server_id in servers {
6866            self.cancel_language_server_work(server_id, None, cx);
6867        }
6868    }
6869
6870    pub fn language_servers(
6871        &self,
6872    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName, WorktreeId)> {
6873        self.language_server_ids
6874            .iter()
6875            .map(|((worktree_id, server_name), server_id)| {
6876                (*server_id, server_name.clone(), *worktree_id)
6877            })
6878    }
6879
6880    pub fn register_supplementary_language_server(
6881        &mut self,
6882        id: LanguageServerId,
6883        name: LanguageServerName,
6884        server: Arc<LanguageServer>,
6885        cx: &mut ModelContext<Self>,
6886    ) {
6887        if let Some(local) = self.as_local_mut() {
6888            local
6889                .supplementary_language_servers
6890                .insert(id, (name, server));
6891            cx.emit(LspStoreEvent::LanguageServerAdded(id));
6892        }
6893    }
6894
6895    pub fn unregister_supplementary_language_server(
6896        &mut self,
6897        id: LanguageServerId,
6898        cx: &mut ModelContext<Self>,
6899    ) {
6900        if let Some(local) = self.as_local_mut() {
6901            local.supplementary_language_servers.remove(&id);
6902            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
6903        }
6904    }
6905
6906    pub fn supplementary_language_servers(
6907        &self,
6908    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
6909        self.as_local().into_iter().flat_map(|local| {
6910            local
6911                .supplementary_language_servers
6912                .iter()
6913                .map(|(id, (name, _))| (*id, name.clone()))
6914        })
6915    }
6916
6917    pub fn language_server_adapter_for_id(
6918        &self,
6919        id: LanguageServerId,
6920    ) -> Option<Arc<CachedLspAdapter>> {
6921        self.as_local()
6922            .and_then(|local| local.language_servers.get(&id))
6923            .and_then(|language_server_state| match language_server_state {
6924                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
6925                _ => None,
6926            })
6927    }
6928
6929    pub(super) fn update_local_worktree_language_servers(
6930        &mut self,
6931        worktree_handle: &Model<Worktree>,
6932        changes: &[(Arc<Path>, ProjectEntryId, PathChange)],
6933        cx: &mut ModelContext<Self>,
6934    ) {
6935        if changes.is_empty() {
6936            return;
6937        }
6938
6939        let Some(local) = self.as_local() else { return };
6940
6941        local.prettier_store.update(cx, |prettier_store, cx| {
6942            prettier_store.update_prettier_settings(&worktree_handle, changes, cx)
6943        });
6944
6945        let worktree_id = worktree_handle.read(cx).id();
6946        let mut language_server_ids = self
6947            .language_server_ids
6948            .iter()
6949            .filter_map(|((server_worktree_id, _), server_id)| {
6950                (*server_worktree_id == worktree_id).then_some(*server_id)
6951            })
6952            .collect::<Vec<_>>();
6953        language_server_ids.sort();
6954        language_server_ids.dedup();
6955
6956        let abs_path = worktree_handle.read(cx).abs_path();
6957        for server_id in &language_server_ids {
6958            if let Some(LanguageServerState::Running { server, .. }) =
6959                local.language_servers.get(server_id)
6960            {
6961                if let Some(watched_paths) = local
6962                    .language_server_watched_paths
6963                    .get(server_id)
6964                    .and_then(|paths| paths.read(cx).worktree_paths.get(&worktree_id))
6965                {
6966                    let params = lsp::DidChangeWatchedFilesParams {
6967                        changes: changes
6968                            .iter()
6969                            .filter_map(|(path, _, change)| {
6970                                if !watched_paths.is_match(path) {
6971                                    return None;
6972                                }
6973                                let typ = match change {
6974                                    PathChange::Loaded => return None,
6975                                    PathChange::Added => lsp::FileChangeType::CREATED,
6976                                    PathChange::Removed => lsp::FileChangeType::DELETED,
6977                                    PathChange::Updated => lsp::FileChangeType::CHANGED,
6978                                    PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
6979                                };
6980                                Some(lsp::FileEvent {
6981                                    uri: lsp::Url::from_file_path(abs_path.join(path)).unwrap(),
6982                                    typ,
6983                                })
6984                            })
6985                            .collect(),
6986                    };
6987                    if !params.changes.is_empty() {
6988                        server
6989                            .notify::<lsp::notification::DidChangeWatchedFiles>(params)
6990                            .log_err();
6991                    }
6992                }
6993            }
6994        }
6995    }
6996
6997    pub(crate) fn cancel_language_server_work(
6998        &mut self,
6999        server_id: LanguageServerId,
7000        token_to_cancel: Option<String>,
7001        _cx: &mut ModelContext<Self>,
7002    ) {
7003        let Some(local) = self.as_local() else {
7004            return;
7005        };
7006        let status = self.language_server_statuses.get(&server_id);
7007        let server = local.language_servers.get(&server_id);
7008        if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status) {
7009            for (token, progress) in &status.pending_work {
7010                if let Some(token_to_cancel) = token_to_cancel.as_ref() {
7011                    if token != token_to_cancel {
7012                        continue;
7013                    }
7014                }
7015                if progress.is_cancellable {
7016                    server
7017                        .notify::<lsp::notification::WorkDoneProgressCancel>(
7018                            WorkDoneProgressCancelParams {
7019                                token: lsp::NumberOrString::String(token.clone()),
7020                            },
7021                        )
7022                        .ok();
7023                }
7024
7025                if progress.is_cancellable {
7026                    server
7027                        .notify::<lsp::notification::WorkDoneProgressCancel>(
7028                            WorkDoneProgressCancelParams {
7029                                token: lsp::NumberOrString::String(token.clone()),
7030                            },
7031                        )
7032                        .ok();
7033                }
7034            }
7035        }
7036    }
7037
7038    pub fn wait_for_remote_buffer(
7039        &mut self,
7040        id: BufferId,
7041        cx: &mut ModelContext<Self>,
7042    ) -> Task<Result<Model<Buffer>>> {
7043        self.buffer_store.update(cx, |buffer_store, cx| {
7044            buffer_store.wait_for_remote_buffer(id, cx)
7045        })
7046    }
7047
7048    pub(crate) fn language_server_ids_for_buffer(
7049        &self,
7050        buffer: &Buffer,
7051        cx: &AppContext,
7052    ) -> Vec<LanguageServerId> {
7053        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
7054            let worktree_id = file.worktree_id(cx);
7055            self.languages
7056                .lsp_adapters(&language.name())
7057                .iter()
7058                .flat_map(|adapter| {
7059                    let key = (worktree_id, adapter.name.clone());
7060                    self.language_server_ids.get(&key).copied()
7061                })
7062                .collect()
7063        } else {
7064            Vec::new()
7065        }
7066    }
7067
7068    pub async fn deserialize_text_edits(
7069        this: Model<Self>,
7070        buffer_to_edit: Model<Buffer>,
7071        edits: Vec<lsp::TextEdit>,
7072        push_to_history: bool,
7073        _: Arc<CachedLspAdapter>,
7074        language_server: Arc<LanguageServer>,
7075        cx: &mut AsyncAppContext,
7076    ) -> Result<Option<Transaction>> {
7077        let edits = this
7078            .update(cx, |this, cx| {
7079                this.edits_from_lsp(
7080                    &buffer_to_edit,
7081                    edits,
7082                    language_server.server_id(),
7083                    None,
7084                    cx,
7085                )
7086            })?
7087            .await?;
7088
7089        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
7090            buffer.finalize_last_transaction();
7091            buffer.start_transaction();
7092            for (range, text) in edits {
7093                buffer.edit([(range, text)], None, cx);
7094            }
7095
7096            if buffer.end_transaction(cx).is_some() {
7097                let transaction = buffer.finalize_last_transaction().unwrap().clone();
7098                if !push_to_history {
7099                    buffer.forget_transaction(transaction.id);
7100                }
7101                Some(transaction)
7102            } else {
7103                None
7104            }
7105        })?;
7106
7107        Ok(transaction)
7108    }
7109
7110    pub async fn deserialize_workspace_edit(
7111        this: Model<Self>,
7112        edit: lsp::WorkspaceEdit,
7113        push_to_history: bool,
7114        lsp_adapter: Arc<CachedLspAdapter>,
7115        language_server: Arc<LanguageServer>,
7116        cx: &mut AsyncAppContext,
7117    ) -> Result<ProjectTransaction> {
7118        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
7119
7120        let mut operations = Vec::new();
7121        if let Some(document_changes) = edit.document_changes {
7122            match document_changes {
7123                lsp::DocumentChanges::Edits(edits) => {
7124                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
7125                }
7126                lsp::DocumentChanges::Operations(ops) => operations = ops,
7127            }
7128        } else if let Some(changes) = edit.changes {
7129            operations.extend(changes.into_iter().map(|(uri, edits)| {
7130                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
7131                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
7132                        uri,
7133                        version: None,
7134                    },
7135                    edits: edits.into_iter().map(Edit::Plain).collect(),
7136                })
7137            }));
7138        }
7139
7140        let mut project_transaction = ProjectTransaction::default();
7141        for operation in operations {
7142            match operation {
7143                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
7144                    let abs_path = op
7145                        .uri
7146                        .to_file_path()
7147                        .map_err(|_| anyhow!("can't convert URI to path"))?;
7148
7149                    if let Some(parent_path) = abs_path.parent() {
7150                        fs.create_dir(parent_path).await?;
7151                    }
7152                    if abs_path.ends_with("/") {
7153                        fs.create_dir(&abs_path).await?;
7154                    } else {
7155                        fs.create_file(
7156                            &abs_path,
7157                            op.options
7158                                .map(|options| fs::CreateOptions {
7159                                    overwrite: options.overwrite.unwrap_or(false),
7160                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
7161                                })
7162                                .unwrap_or_default(),
7163                        )
7164                        .await?;
7165                    }
7166                }
7167
7168                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
7169                    let source_abs_path = op
7170                        .old_uri
7171                        .to_file_path()
7172                        .map_err(|_| anyhow!("can't convert URI to path"))?;
7173                    let target_abs_path = op
7174                        .new_uri
7175                        .to_file_path()
7176                        .map_err(|_| anyhow!("can't convert URI to path"))?;
7177                    fs.rename(
7178                        &source_abs_path,
7179                        &target_abs_path,
7180                        op.options
7181                            .map(|options| fs::RenameOptions {
7182                                overwrite: options.overwrite.unwrap_or(false),
7183                                ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
7184                            })
7185                            .unwrap_or_default(),
7186                    )
7187                    .await?;
7188                }
7189
7190                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
7191                    let abs_path = op
7192                        .uri
7193                        .to_file_path()
7194                        .map_err(|_| anyhow!("can't convert URI to path"))?;
7195                    let options = op
7196                        .options
7197                        .map(|options| fs::RemoveOptions {
7198                            recursive: options.recursive.unwrap_or(false),
7199                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
7200                        })
7201                        .unwrap_or_default();
7202                    if abs_path.ends_with("/") {
7203                        fs.remove_dir(&abs_path, options).await?;
7204                    } else {
7205                        fs.remove_file(&abs_path, options).await?;
7206                    }
7207                }
7208
7209                lsp::DocumentChangeOperation::Edit(op) => {
7210                    let buffer_to_edit = this
7211                        .update(cx, |this, cx| {
7212                            this.open_local_buffer_via_lsp(
7213                                op.text_document.uri.clone(),
7214                                language_server.server_id(),
7215                                lsp_adapter.name.clone(),
7216                                cx,
7217                            )
7218                        })?
7219                        .await?;
7220
7221                    let edits = this
7222                        .update(cx, |this, cx| {
7223                            let path = buffer_to_edit.read(cx).project_path(cx);
7224                            let active_entry = this.active_entry;
7225                            let is_active_entry = path.clone().map_or(false, |project_path| {
7226                                this.worktree_store
7227                                    .read(cx)
7228                                    .entry_for_path(&project_path, cx)
7229                                    .map_or(false, |entry| Some(entry.id) == active_entry)
7230                            });
7231
7232                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
7233                            for edit in op.edits {
7234                                match edit {
7235                                    Edit::Plain(edit) => edits.push(edit),
7236                                    Edit::Annotated(edit) => edits.push(edit.text_edit),
7237                                    Edit::Snippet(edit) => {
7238                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
7239                                        else {
7240                                            continue;
7241                                        };
7242
7243                                        if is_active_entry {
7244                                            snippet_edits.push((edit.range, snippet));
7245                                        } else {
7246                                            // Since this buffer is not focused, apply a normal edit.
7247                                            edits.push(TextEdit {
7248                                                range: edit.range,
7249                                                new_text: snippet.text,
7250                                            });
7251                                        }
7252                                    }
7253                                }
7254                            }
7255                            if !snippet_edits.is_empty() {
7256                                let buffer_id = buffer_to_edit.read(cx).remote_id();
7257                                let version = if let Some(buffer_version) = op.text_document.version
7258                                {
7259                                    this.buffer_snapshot_for_lsp_version(
7260                                        &buffer_to_edit,
7261                                        language_server.server_id(),
7262                                        Some(buffer_version),
7263                                        cx,
7264                                    )
7265                                    .ok()
7266                                    .map(|snapshot| snapshot.version)
7267                                } else {
7268                                    Some(buffer_to_edit.read(cx).saved_version().clone())
7269                                };
7270
7271                                let most_recent_edit = version.and_then(|version| {
7272                                    version.iter().max_by_key(|timestamp| timestamp.value)
7273                                });
7274                                // Check if the edit that triggered that edit has been made by this participant.
7275
7276                                if let Some(most_recent_edit) = most_recent_edit {
7277                                    cx.emit(LspStoreEvent::SnippetEdit {
7278                                        buffer_id,
7279                                        edits: snippet_edits,
7280                                        most_recent_edit,
7281                                    });
7282                                }
7283                            }
7284
7285                            this.edits_from_lsp(
7286                                &buffer_to_edit,
7287                                edits,
7288                                language_server.server_id(),
7289                                op.text_document.version,
7290                                cx,
7291                            )
7292                        })?
7293                        .await?;
7294
7295                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
7296                        buffer.finalize_last_transaction();
7297                        buffer.start_transaction();
7298                        for (range, text) in edits {
7299                            buffer.edit([(range, text)], None, cx);
7300                        }
7301                        let transaction = if buffer.end_transaction(cx).is_some() {
7302                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
7303                            if !push_to_history {
7304                                buffer.forget_transaction(transaction.id);
7305                            }
7306                            Some(transaction)
7307                        } else {
7308                            None
7309                        };
7310
7311                        transaction
7312                    })?;
7313                    if let Some(transaction) = transaction {
7314                        project_transaction.0.insert(buffer_to_edit, transaction);
7315                    }
7316                }
7317            }
7318        }
7319
7320        Ok(project_transaction)
7321    }
7322
7323    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
7324        proto::Symbol {
7325            language_server_name: symbol.language_server_name.0.to_string(),
7326            source_worktree_id: symbol.source_worktree_id.to_proto(),
7327            worktree_id: symbol.path.worktree_id.to_proto(),
7328            path: symbol.path.path.to_string_lossy().to_string(),
7329            name: symbol.name.clone(),
7330            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
7331            start: Some(proto::PointUtf16 {
7332                row: symbol.range.start.0.row,
7333                column: symbol.range.start.0.column,
7334            }),
7335            end: Some(proto::PointUtf16 {
7336                row: symbol.range.end.0.row,
7337                column: symbol.range.end.0.column,
7338            }),
7339            signature: symbol.signature.to_vec(),
7340        }
7341    }
7342
7343    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
7344        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
7345        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
7346        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
7347        let path = ProjectPath {
7348            worktree_id,
7349            path: PathBuf::from(serialized_symbol.path).into(),
7350        };
7351
7352        let start = serialized_symbol
7353            .start
7354            .ok_or_else(|| anyhow!("invalid start"))?;
7355        let end = serialized_symbol
7356            .end
7357            .ok_or_else(|| anyhow!("invalid end"))?;
7358        Ok(CoreSymbol {
7359            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
7360            source_worktree_id,
7361            path,
7362            name: serialized_symbol.name,
7363            range: Unclipped(PointUtf16::new(start.row, start.column))
7364                ..Unclipped(PointUtf16::new(end.row, end.column)),
7365            kind,
7366            signature: serialized_symbol
7367                .signature
7368                .try_into()
7369                .map_err(|_| anyhow!("invalid signature"))?,
7370        })
7371    }
7372
7373    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
7374        proto::Completion {
7375            old_start: Some(serialize_anchor(&completion.old_range.start)),
7376            old_end: Some(serialize_anchor(&completion.old_range.end)),
7377            new_text: completion.new_text.clone(),
7378            server_id: completion.server_id.0 as u64,
7379            lsp_completion: serde_json::to_vec(&completion.lsp_completion).unwrap(),
7380        }
7381    }
7382
7383    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
7384        let old_start = completion
7385            .old_start
7386            .and_then(deserialize_anchor)
7387            .ok_or_else(|| anyhow!("invalid old start"))?;
7388        let old_end = completion
7389            .old_end
7390            .and_then(deserialize_anchor)
7391            .ok_or_else(|| anyhow!("invalid old end"))?;
7392        let lsp_completion = serde_json::from_slice(&completion.lsp_completion)?;
7393
7394        Ok(CoreCompletion {
7395            old_range: old_start..old_end,
7396            new_text: completion.new_text,
7397            server_id: LanguageServerId(completion.server_id as usize),
7398            lsp_completion,
7399        })
7400    }
7401
7402    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
7403        proto::CodeAction {
7404            server_id: action.server_id.0 as u64,
7405            start: Some(serialize_anchor(&action.range.start)),
7406            end: Some(serialize_anchor(&action.range.end)),
7407            lsp_action: serde_json::to_vec(&action.lsp_action).unwrap(),
7408        }
7409    }
7410
7411    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
7412        let start = action
7413            .start
7414            .and_then(deserialize_anchor)
7415            .ok_or_else(|| anyhow!("invalid start"))?;
7416        let end = action
7417            .end
7418            .and_then(deserialize_anchor)
7419            .ok_or_else(|| anyhow!("invalid end"))?;
7420        let lsp_action = serde_json::from_slice(&action.lsp_action)?;
7421        Ok(CodeAction {
7422            server_id: LanguageServerId(action.server_id as usize),
7423            range: start..end,
7424            lsp_action,
7425        })
7426    }
7427}
7428
7429impl EventEmitter<LspStoreEvent> for LspStore {}
7430
7431fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
7432    hover
7433        .contents
7434        .retain(|hover_block| !hover_block.text.trim().is_empty());
7435    if hover.contents.is_empty() {
7436        None
7437    } else {
7438        Some(hover)
7439    }
7440}
7441
7442async fn populate_labels_for_completions(
7443    mut new_completions: Vec<CoreCompletion>,
7444    language_registry: &Arc<LanguageRegistry>,
7445    language: Option<Arc<Language>>,
7446    lsp_adapter: Option<Arc<CachedLspAdapter>>,
7447    completions: &mut Vec<Completion>,
7448) {
7449    let lsp_completions = new_completions
7450        .iter_mut()
7451        .map(|completion| mem::take(&mut completion.lsp_completion))
7452        .collect::<Vec<_>>();
7453
7454    let labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
7455        lsp_adapter
7456            .labels_for_completions(&lsp_completions, language)
7457            .await
7458            .log_err()
7459            .unwrap_or_default()
7460    } else {
7461        Vec::new()
7462    };
7463
7464    for ((completion, lsp_completion), label) in new_completions
7465        .into_iter()
7466        .zip(lsp_completions)
7467        .zip(labels.into_iter().chain(iter::repeat(None)))
7468    {
7469        let documentation = if let Some(docs) = &lsp_completion.documentation {
7470            Some(prepare_completion_documentation(docs, language_registry, language.clone()).await)
7471        } else {
7472            None
7473        };
7474
7475        completions.push(Completion {
7476            old_range: completion.old_range,
7477            new_text: completion.new_text,
7478            label: label.unwrap_or_else(|| {
7479                CodeLabel::plain(
7480                    lsp_completion.label.clone(),
7481                    lsp_completion.filter_text.as_deref(),
7482                )
7483            }),
7484            server_id: completion.server_id,
7485            documentation,
7486            lsp_completion,
7487            confirm: None,
7488        })
7489    }
7490}
7491
7492#[derive(Debug)]
7493pub enum LanguageServerToQuery {
7494    Primary,
7495    Other(LanguageServerId),
7496}
7497
7498#[derive(Default)]
7499struct LanguageServerWatchedPaths {
7500    worktree_paths: HashMap<WorktreeId, GlobSet>,
7501    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
7502}
7503
7504#[derive(Default)]
7505struct LanguageServerWatchedPathsBuilder {
7506    worktree_paths: HashMap<WorktreeId, GlobSet>,
7507    abs_paths: HashMap<Arc<Path>, GlobSet>,
7508}
7509
7510impl LanguageServerWatchedPathsBuilder {
7511    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
7512        self.worktree_paths.insert(worktree_id, glob_set);
7513    }
7514    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
7515        self.abs_paths.insert(path, glob_set);
7516    }
7517    fn build(
7518        self,
7519        fs: Arc<dyn Fs>,
7520        language_server_id: LanguageServerId,
7521        cx: &mut ModelContext<LspStore>,
7522    ) -> Model<LanguageServerWatchedPaths> {
7523        let project = cx.weak_model();
7524
7525        cx.new_model(|cx| {
7526            let this_id = cx.entity_id();
7527            const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
7528            let abs_paths = self
7529                .abs_paths
7530                .into_iter()
7531                .map(|(abs_path, globset)| {
7532                    let task = cx.spawn({
7533                        let abs_path = abs_path.clone();
7534                        let fs = fs.clone();
7535
7536                        let lsp_store = project.clone();
7537                        |_, mut cx| async move {
7538                            maybe!(async move {
7539                                let mut push_updates =
7540                                    fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
7541                                while let Some(update) = push_updates.0.next().await {
7542                                    let action = lsp_store
7543                                        .update(&mut cx, |this, cx| {
7544                                            let Some(local) = this.as_local() else {
7545                                                return ControlFlow::Break(());
7546                                            };
7547                                            let Some(watcher) = local
7548                                                .language_server_watched_paths
7549                                                .get(&language_server_id)
7550                                            else {
7551                                                return ControlFlow::Break(());
7552                                            };
7553                                            if watcher.entity_id() != this_id {
7554                                                // This watcher is no longer registered on the project, which means that we should
7555                                                // cease operations.
7556                                                return ControlFlow::Break(());
7557                                            }
7558                                            let (globs, _) = watcher
7559                                                .read(cx)
7560                                                .abs_paths
7561                                                .get(&abs_path)
7562                                                .expect(
7563                                                "Watched abs path is not registered with a watcher",
7564                                            );
7565                                            let matching_entries = update
7566                                                .into_iter()
7567                                                .filter(|event| globs.is_match(&event.path))
7568                                                .collect::<Vec<_>>();
7569                                            this.lsp_notify_abs_paths_changed(
7570                                                language_server_id,
7571                                                matching_entries,
7572                                            );
7573                                            ControlFlow::Continue(())
7574                                        })
7575                                        .ok()?;
7576
7577                                    if action.is_break() {
7578                                        break;
7579                                    }
7580                                }
7581                                Some(())
7582                            })
7583                            .await;
7584                        }
7585                    });
7586                    (abs_path, (globset, task))
7587                })
7588                .collect();
7589            LanguageServerWatchedPaths {
7590                worktree_paths: self.worktree_paths,
7591                abs_paths,
7592            }
7593        })
7594    }
7595}
7596
7597struct LspBufferSnapshot {
7598    version: i32,
7599    snapshot: TextBufferSnapshot,
7600}
7601
7602/// A prompt requested by LSP server.
7603#[derive(Clone, Debug)]
7604pub struct LanguageServerPromptRequest {
7605    pub level: PromptLevel,
7606    pub message: String,
7607    pub actions: Vec<MessageActionItem>,
7608    pub lsp_name: String,
7609    pub(crate) response_channel: Sender<MessageActionItem>,
7610}
7611
7612impl LanguageServerPromptRequest {
7613    pub async fn respond(self, index: usize) -> Option<()> {
7614        if let Some(response) = self.actions.into_iter().nth(index) {
7615            self.response_channel.send(response).await.ok()
7616        } else {
7617            None
7618        }
7619    }
7620}
7621impl PartialEq for LanguageServerPromptRequest {
7622    fn eq(&self, other: &Self) -> bool {
7623        self.message == other.message && self.actions == other.actions
7624    }
7625}
7626
7627#[derive(Clone, Debug, PartialEq)]
7628pub enum LanguageServerLogType {
7629    Log(MessageType),
7630    Trace(Option<String>),
7631}
7632
7633pub enum LanguageServerState {
7634    Starting(Task<Option<Arc<LanguageServer>>>),
7635
7636    Running {
7637        language: LanguageName,
7638        adapter: Arc<CachedLspAdapter>,
7639        server: Arc<LanguageServer>,
7640        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
7641    },
7642}
7643
7644impl std::fmt::Debug for LanguageServerState {
7645    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7646        match self {
7647            LanguageServerState::Starting(_) => {
7648                f.debug_struct("LanguageServerState::Starting").finish()
7649            }
7650            LanguageServerState::Running { language, .. } => f
7651                .debug_struct("LanguageServerState::Running")
7652                .field("language", &language)
7653                .finish(),
7654        }
7655    }
7656}
7657
7658#[derive(Clone, Debug, Serialize)]
7659pub struct LanguageServerProgress {
7660    pub is_disk_based_diagnostics_progress: bool,
7661    pub is_cancellable: bool,
7662    pub title: Option<String>,
7663    pub message: Option<String>,
7664    pub percentage: Option<usize>,
7665    #[serde(skip_serializing)]
7666    pub last_update_at: Instant,
7667}
7668
7669#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
7670pub struct DiagnosticSummary {
7671    pub error_count: usize,
7672    pub warning_count: usize,
7673}
7674
7675impl DiagnosticSummary {
7676    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
7677        let mut this = Self {
7678            error_count: 0,
7679            warning_count: 0,
7680        };
7681
7682        for entry in diagnostics {
7683            if entry.diagnostic.is_primary {
7684                match entry.diagnostic.severity {
7685                    DiagnosticSeverity::ERROR => this.error_count += 1,
7686                    DiagnosticSeverity::WARNING => this.warning_count += 1,
7687                    _ => {}
7688                }
7689            }
7690        }
7691
7692        this
7693    }
7694
7695    pub fn is_empty(&self) -> bool {
7696        self.error_count == 0 && self.warning_count == 0
7697    }
7698
7699    pub fn to_proto(
7700        &self,
7701        language_server_id: LanguageServerId,
7702        path: &Path,
7703    ) -> proto::DiagnosticSummary {
7704        proto::DiagnosticSummary {
7705            path: path.to_string_lossy().to_string(),
7706            language_server_id: language_server_id.0 as u64,
7707            error_count: self.error_count as u32,
7708            warning_count: self.warning_count as u32,
7709        }
7710    }
7711}
7712
7713fn glob_literal_prefix(glob: &str) -> &str {
7714    let is_absolute = glob.starts_with(path::MAIN_SEPARATOR);
7715
7716    let mut literal_end = is_absolute as usize;
7717    for (i, part) in glob.split(path::MAIN_SEPARATOR).enumerate() {
7718        if part.contains(['*', '?', '{', '}']) {
7719            break;
7720        } else {
7721            if i > 0 {
7722                // Account for separator prior to this part
7723                literal_end += path::MAIN_SEPARATOR.len_utf8();
7724            }
7725            literal_end += part.len();
7726        }
7727    }
7728    let literal_end = literal_end.min(glob.len());
7729    &glob[..literal_end]
7730}
7731
7732pub struct SshLspAdapter {
7733    name: LanguageServerName,
7734    binary: LanguageServerBinary,
7735    initialization_options: Option<String>,
7736    code_action_kinds: Option<Vec<CodeActionKind>>,
7737}
7738
7739impl SshLspAdapter {
7740    pub fn new(
7741        name: LanguageServerName,
7742        binary: LanguageServerBinary,
7743        initialization_options: Option<String>,
7744        code_action_kinds: Option<String>,
7745    ) -> Self {
7746        Self {
7747            name,
7748            binary,
7749            initialization_options,
7750            code_action_kinds: code_action_kinds
7751                .as_ref()
7752                .and_then(|c| serde_json::from_str(c).ok()),
7753        }
7754    }
7755}
7756
7757#[async_trait(?Send)]
7758impl LspAdapter for SshLspAdapter {
7759    fn name(&self) -> LanguageServerName {
7760        self.name.clone()
7761    }
7762
7763    async fn initialization_options(
7764        self: Arc<Self>,
7765        _: &Arc<dyn LspAdapterDelegate>,
7766    ) -> Result<Option<serde_json::Value>> {
7767        let Some(options) = &self.initialization_options else {
7768            return Ok(None);
7769        };
7770        let result = serde_json::from_str(options)?;
7771        Ok(result)
7772    }
7773
7774    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
7775        self.code_action_kinds.clone()
7776    }
7777
7778    async fn check_if_user_installed(
7779        &self,
7780        _: &dyn LspAdapterDelegate,
7781        _: &AsyncAppContext,
7782    ) -> Option<LanguageServerBinary> {
7783        Some(self.binary.clone())
7784    }
7785
7786    async fn cached_server_binary(
7787        &self,
7788        _: PathBuf,
7789        _: &dyn LspAdapterDelegate,
7790    ) -> Option<LanguageServerBinary> {
7791        None
7792    }
7793
7794    async fn fetch_latest_server_version(
7795        &self,
7796        _: &dyn LspAdapterDelegate,
7797    ) -> Result<Box<dyn 'static + Send + Any>> {
7798        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
7799    }
7800
7801    async fn fetch_server_binary(
7802        &self,
7803        _: Box<dyn 'static + Send + Any>,
7804        _: PathBuf,
7805        _: &dyn LspAdapterDelegate,
7806    ) -> Result<LanguageServerBinary> {
7807        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
7808    }
7809
7810    async fn installation_test_binary(&self, _: PathBuf) -> Option<LanguageServerBinary> {
7811        None
7812    }
7813}
7814pub fn language_server_settings<'a, 'b: 'a>(
7815    delegate: &'a dyn LspAdapterDelegate,
7816    language: &LanguageServerName,
7817    cx: &'b AppContext,
7818) -> Option<&'a LspSettings> {
7819    ProjectSettings::get(
7820        Some(SettingsLocation {
7821            worktree_id: delegate.worktree_id(),
7822            path: delegate.worktree_root_path(),
7823        }),
7824        cx,
7825    )
7826    .lsp
7827    .get(language)
7828}
7829
7830pub struct LocalLspAdapterDelegate {
7831    lsp_store: WeakModel<LspStore>,
7832    worktree: worktree::Snapshot,
7833    fs: Arc<dyn Fs>,
7834    http_client: Arc<dyn HttpClient>,
7835    language_registry: Arc<LanguageRegistry>,
7836    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
7837}
7838
7839impl LocalLspAdapterDelegate {
7840    fn for_local(
7841        lsp_store: &LspStore,
7842        worktree: &Model<Worktree>,
7843        cx: &mut ModelContext<LspStore>,
7844    ) -> Arc<Self> {
7845        let local = lsp_store
7846            .as_local()
7847            .expect("LocalLspAdapterDelegate cannot be constructed on a remote");
7848
7849        let http_client = local
7850            .http_client
7851            .clone()
7852            .unwrap_or_else(|| Arc::new(BlockedHttpClient));
7853
7854        Self::new(lsp_store, worktree, http_client, local.fs.clone(), cx)
7855    }
7856
7857    // fn for_ssh(
7858    //     lsp_store: &LspStore,
7859    //     worktree: &Model<Worktree>,
7860    //     upstream_client: AnyProtoClient,
7861    //     cx: &mut ModelContext<LspStore>,
7862    // ) -> Arc<Self> {
7863    //     Self::new(
7864    //         lsp_store,
7865    //         worktree,
7866    //         Arc::new(BlockedHttpClient),
7867    //         None,
7868    //         Some(upstream_client),
7869    //         cx,
7870    //     )
7871    // }
7872
7873    pub fn new(
7874        lsp_store: &LspStore,
7875        worktree: &Model<Worktree>,
7876        http_client: Arc<dyn HttpClient>,
7877        fs: Arc<dyn Fs>,
7878        cx: &mut ModelContext<LspStore>,
7879    ) -> Arc<Self> {
7880        let worktree_id = worktree.read(cx).id();
7881        let worktree_abs_path = worktree.read(cx).abs_path();
7882        let load_shell_env_task = if let Some(environment) =
7883            &lsp_store.as_local().map(|local| local.environment.clone())
7884        {
7885            environment.update(cx, |env, cx| {
7886                env.get_environment(Some(worktree_id), Some(worktree_abs_path), cx)
7887            })
7888        } else {
7889            Task::ready(None).shared()
7890        };
7891
7892        Arc::new(Self {
7893            lsp_store: cx.weak_model(),
7894            worktree: worktree.read(cx).snapshot(),
7895            fs,
7896            http_client,
7897            language_registry: lsp_store.languages.clone(),
7898            load_shell_env_task,
7899        })
7900    }
7901}
7902
7903#[async_trait]
7904impl LspAdapterDelegate for LocalLspAdapterDelegate {
7905    fn show_notification(&self, message: &str, cx: &mut AppContext) {
7906        self.lsp_store
7907            .update(cx, |_, cx| {
7908                cx.emit(LspStoreEvent::Notification(message.to_owned()))
7909            })
7910            .ok();
7911    }
7912
7913    fn http_client(&self) -> Arc<dyn HttpClient> {
7914        self.http_client.clone()
7915    }
7916
7917    fn worktree_id(&self) -> WorktreeId {
7918        self.worktree.id()
7919    }
7920
7921    fn worktree_root_path(&self) -> &Path {
7922        self.worktree.abs_path().as_ref()
7923    }
7924
7925    async fn shell_env(&self) -> HashMap<String, String> {
7926        let task = self.load_shell_env_task.clone();
7927        task.await.unwrap_or_default()
7928    }
7929
7930    #[cfg(not(target_os = "windows"))]
7931    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
7932        let worktree_abs_path = self.worktree.abs_path();
7933        let shell_path = self.shell_env().await.get("PATH").cloned();
7934        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
7935    }
7936
7937    #[cfg(target_os = "windows")]
7938    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
7939        // todo(windows) Getting the shell env variables in a current directory on Windows is more complicated than other platforms
7940        //               there isn't a 'default shell' necessarily. The closest would be the default profile on the windows terminal
7941        //               SEE: https://learn.microsoft.com/en-us/windows/terminal/customize-settings/startup
7942        which::which(command).ok()
7943    }
7944
7945    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
7946        let working_dir = self.worktree_root_path();
7947        let output = smol::process::Command::new(&command.path)
7948            .args(command.arguments)
7949            .envs(command.env.clone().unwrap_or_default())
7950            .current_dir(working_dir)
7951            .output()
7952            .await?;
7953
7954        if output.status.success() {
7955            return Ok(());
7956        }
7957        Err(anyhow!(
7958            "{}, stdout: {:?}, stderr: {:?}",
7959            output.status,
7960            String::from_utf8_lossy(&output.stdout),
7961            String::from_utf8_lossy(&output.stderr)
7962        ))
7963    }
7964
7965    fn update_status(
7966        &self,
7967        server_name: LanguageServerName,
7968        status: language::LanguageServerBinaryStatus,
7969    ) {
7970        self.language_registry
7971            .update_lsp_status(server_name, status);
7972    }
7973
7974    async fn read_text_file(&self, path: PathBuf) -> Result<String> {
7975        if self.worktree.entry_for_path(&path).is_none() {
7976            return Err(anyhow!("no such path {path:?}"));
7977        };
7978        self.fs.load(&path).await
7979    }
7980}
7981
7982struct SshLspAdapterDelegate {
7983    lsp_store: WeakModel<LspStore>,
7984    worktree: worktree::Snapshot,
7985    upstream_client: AnyProtoClient,
7986    language_registry: Arc<LanguageRegistry>,
7987}
7988
7989#[async_trait]
7990impl LspAdapterDelegate for SshLspAdapterDelegate {
7991    fn show_notification(&self, message: &str, cx: &mut AppContext) {
7992        self.lsp_store
7993            .update(cx, |_, cx| {
7994                cx.emit(LspStoreEvent::Notification(message.to_owned()))
7995            })
7996            .ok();
7997    }
7998
7999    fn http_client(&self) -> Arc<dyn HttpClient> {
8000        Arc::new(BlockedHttpClient)
8001    }
8002
8003    fn worktree_id(&self) -> WorktreeId {
8004        self.worktree.id()
8005    }
8006
8007    fn worktree_root_path(&self) -> &Path {
8008        self.worktree.abs_path().as_ref()
8009    }
8010
8011    async fn shell_env(&self) -> HashMap<String, String> {
8012        use rpc::proto::SSH_PROJECT_ID;
8013
8014        self.upstream_client
8015            .request(proto::ShellEnv {
8016                project_id: SSH_PROJECT_ID,
8017                worktree_id: self.worktree_id().to_proto(),
8018            })
8019            .await
8020            .map(|response| response.env.into_iter().collect())
8021            .unwrap_or_default()
8022    }
8023
8024    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
8025        use rpc::proto::SSH_PROJECT_ID;
8026
8027        self.upstream_client
8028            .request(proto::WhichCommand {
8029                project_id: SSH_PROJECT_ID,
8030                worktree_id: self.worktree_id().to_proto(),
8031                command: command.to_string_lossy().to_string(),
8032            })
8033            .await
8034            .log_err()
8035            .and_then(|response| response.path)
8036            .map(PathBuf::from)
8037    }
8038
8039    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
8040        self.upstream_client
8041            .request(proto::TryExec {
8042                project_id: rpc::proto::SSH_PROJECT_ID,
8043                worktree_id: self.worktree.id().to_proto(),
8044                binary: Some(proto::LanguageServerCommand {
8045                    path: command.path.to_string_lossy().to_string(),
8046                    arguments: command
8047                        .arguments
8048                        .into_iter()
8049                        .map(|s| s.to_string_lossy().to_string())
8050                        .collect(),
8051                    env: command.env.unwrap_or_default().into_iter().collect(),
8052                }),
8053            })
8054            .await?;
8055        Ok(())
8056    }
8057
8058    fn update_status(
8059        &self,
8060        server_name: LanguageServerName,
8061        status: language::LanguageServerBinaryStatus,
8062    ) {
8063        self.language_registry
8064            .update_lsp_status(server_name, status);
8065    }
8066
8067    async fn read_text_file(&self, path: PathBuf) -> Result<String> {
8068        self.upstream_client
8069            .request(proto::ReadTextFile {
8070                project_id: rpc::proto::SSH_PROJECT_ID,
8071                path: Some(proto::ProjectPath {
8072                    worktree_id: self.worktree.id().to_proto(),
8073                    path: path.to_string_lossy().to_string(),
8074                }),
8075            })
8076            .await
8077            .map(|r| r.text)
8078    }
8079}
8080
8081async fn populate_labels_for_symbols(
8082    symbols: Vec<CoreSymbol>,
8083    language_registry: &Arc<LanguageRegistry>,
8084    default_language: Option<LanguageName>,
8085    lsp_adapter: Option<Arc<CachedLspAdapter>>,
8086    output: &mut Vec<Symbol>,
8087) {
8088    #[allow(clippy::mutable_key_type)]
8089    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
8090
8091    let mut unknown_path = None;
8092    for symbol in symbols {
8093        let language = language_registry
8094            .language_for_file_path(&symbol.path.path)
8095            .await
8096            .ok()
8097            .or_else(|| {
8098                unknown_path.get_or_insert(symbol.path.path.clone());
8099                default_language.as_ref().and_then(|name| {
8100                    language_registry
8101                        .language_for_name(&name.0)
8102                        .now_or_never()?
8103                        .ok()
8104                })
8105            });
8106        symbols_by_language
8107            .entry(language)
8108            .or_default()
8109            .push(symbol);
8110    }
8111
8112    if let Some(unknown_path) = unknown_path {
8113        log::info!(
8114            "no language found for symbol path {}",
8115            unknown_path.display()
8116        );
8117    }
8118
8119    let mut label_params = Vec::new();
8120    for (language, mut symbols) in symbols_by_language {
8121        label_params.clear();
8122        label_params.extend(
8123            symbols
8124                .iter_mut()
8125                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
8126        );
8127
8128        let mut labels = Vec::new();
8129        if let Some(language) = language {
8130            let lsp_adapter = lsp_adapter.clone().or_else(|| {
8131                language_registry
8132                    .lsp_adapters(&language.name())
8133                    .first()
8134                    .cloned()
8135            });
8136            if let Some(lsp_adapter) = lsp_adapter {
8137                labels = lsp_adapter
8138                    .labels_for_symbols(&label_params, &language)
8139                    .await
8140                    .log_err()
8141                    .unwrap_or_default();
8142            }
8143        }
8144
8145        for ((symbol, (name, _)), label) in symbols
8146            .into_iter()
8147            .zip(label_params.drain(..))
8148            .zip(labels.into_iter().chain(iter::repeat(None)))
8149        {
8150            output.push(Symbol {
8151                language_server_name: symbol.language_server_name,
8152                source_worktree_id: symbol.source_worktree_id,
8153                path: symbol.path,
8154                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
8155                name,
8156                kind: symbol.kind,
8157                range: symbol.range,
8158                signature: symbol.signature,
8159            });
8160        }
8161    }
8162}
8163
8164fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
8165    match server.capabilities().text_document_sync.as_ref()? {
8166        lsp::TextDocumentSyncCapability::Kind(kind) => match *kind {
8167            lsp::TextDocumentSyncKind::NONE => None,
8168            lsp::TextDocumentSyncKind::FULL => Some(true),
8169            lsp::TextDocumentSyncKind::INCREMENTAL => Some(false),
8170            _ => None,
8171        },
8172        lsp::TextDocumentSyncCapability::Options(options) => match options.save.as_ref()? {
8173            lsp::TextDocumentSyncSaveOptions::Supported(supported) => {
8174                if *supported {
8175                    Some(true)
8176                } else {
8177                    None
8178                }
8179            }
8180            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
8181                Some(save_options.include_text.unwrap_or(false))
8182            }
8183        },
8184    }
8185}
8186
8187#[cfg(test)]
8188#[test]
8189fn test_glob_literal_prefix() {
8190    assert_eq!(glob_literal_prefix("**/*.js"), "");
8191    assert_eq!(glob_literal_prefix("node_modules/**/*.js"), "node_modules");
8192    assert_eq!(glob_literal_prefix("foo/{bar,baz}.js"), "foo");
8193    assert_eq!(glob_literal_prefix("foo/bar/baz.js"), "foo/bar/baz.js");
8194}