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            let buffer_store = self.buffer_store();
1605            cx.spawn(move |_, mut cx| async move {
1606                let response = upstream_client
1607                    .request(request)
1608                    .await?
1609                    .transaction
1610                    .ok_or_else(|| anyhow!("missing transaction"))?;
1611
1612                buffer_store
1613                    .update(&mut cx, |buffer_store, cx| {
1614                        buffer_store.deserialize_project_transaction(response, push_to_history, 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            // host
5066            let adapter = this.languages.get_or_register_lsp_adapter(
5067                language_name.clone(),
5068                server_name.clone(),
5069                || {
5070                    Arc::new(SshLspAdapter::new(
5071                        server_name,
5072                        binary,
5073                        envelope.payload.initialization_options,
5074                        envelope.payload.code_action_kinds,
5075                    ))
5076                },
5077            );
5078
5079            this.start_language_server(&worktree, adapter, language_name, cx);
5080            Ok(())
5081        })??;
5082        Ok(proto::Ack {})
5083    }
5084
5085    pub async fn handle_which_command(
5086        this: Model<Self>,
5087        envelope: TypedEnvelope<proto::WhichCommand>,
5088        mut cx: AsyncAppContext,
5089    ) -> Result<proto::WhichCommandResponse> {
5090        let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
5091        let command = PathBuf::from(envelope.payload.command);
5092        let response = this
5093            .update(&mut cx, |this, cx| {
5094                let worktree = this.worktree_for_id(worktree_id, cx)?;
5095                let delegate = LocalLspAdapterDelegate::for_local(this, &worktree, cx);
5096                anyhow::Ok(
5097                    cx.spawn(|_, _| async move { delegate.which(command.as_os_str()).await }),
5098                )
5099            })??
5100            .await;
5101
5102        Ok(proto::WhichCommandResponse {
5103            path: response.map(|path| path.to_string_lossy().to_string()),
5104        })
5105    }
5106
5107    pub async fn handle_shell_env(
5108        this: Model<Self>,
5109        envelope: TypedEnvelope<proto::ShellEnv>,
5110        mut cx: AsyncAppContext,
5111    ) -> Result<proto::ShellEnvResponse> {
5112        let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
5113        let response = this
5114            .update(&mut cx, |this, cx| {
5115                let worktree = this.worktree_for_id(worktree_id, cx)?;
5116                let delegate = LocalLspAdapterDelegate::for_local(this, &worktree, cx);
5117                anyhow::Ok(cx.spawn(|_, _| async move { delegate.shell_env().await }))
5118            })??
5119            .await;
5120
5121        Ok(proto::ShellEnvResponse {
5122            env: response.into_iter().collect(),
5123        })
5124    }
5125    pub async fn handle_try_exec(
5126        this: Model<Self>,
5127        envelope: TypedEnvelope<proto::TryExec>,
5128        mut cx: AsyncAppContext,
5129    ) -> Result<proto::Ack> {
5130        let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
5131        let binary = envelope
5132            .payload
5133            .binary
5134            .ok_or_else(|| anyhow!("missing binary"))?;
5135        let binary = LanguageServerBinary {
5136            path: PathBuf::from(binary.path),
5137            env: None,
5138            arguments: binary.arguments.into_iter().map(Into::into).collect(),
5139        };
5140        this.update(&mut cx, |this, cx| {
5141            let worktree = this.worktree_for_id(worktree_id, cx)?;
5142            let delegate = LocalLspAdapterDelegate::for_local(this, &worktree, cx);
5143            anyhow::Ok(cx.spawn(|_, _| async move { delegate.try_exec(binary).await }))
5144        })??
5145        .await?;
5146
5147        Ok(proto::Ack {})
5148    }
5149
5150    pub async fn handle_read_text_file(
5151        this: Model<Self>,
5152        envelope: TypedEnvelope<proto::ReadTextFile>,
5153        mut cx: AsyncAppContext,
5154    ) -> Result<proto::ReadTextFileResponse> {
5155        let path = envelope
5156            .payload
5157            .path
5158            .ok_or_else(|| anyhow!("missing path"))?;
5159        let worktree_id = WorktreeId::from_proto(path.worktree_id);
5160        let path = PathBuf::from(path.path);
5161        let response = this
5162            .update(&mut cx, |this, cx| {
5163                let worktree = this.worktree_for_id(worktree_id, cx)?;
5164                let delegate = LocalLspAdapterDelegate::for_local(this, &worktree, cx);
5165                anyhow::Ok(cx.spawn(|_, _| async move { delegate.read_text_file(path).await }))
5166            })??
5167            .await?;
5168
5169        Ok(proto::ReadTextFileResponse { text: response })
5170    }
5171
5172    async fn handle_apply_additional_edits_for_completion(
5173        this: Model<Self>,
5174        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
5175        mut cx: AsyncAppContext,
5176    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
5177        let (buffer, completion) = this.update(&mut cx, |this, cx| {
5178            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
5179            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
5180            let completion = Self::deserialize_completion(
5181                envelope
5182                    .payload
5183                    .completion
5184                    .ok_or_else(|| anyhow!("invalid completion"))?,
5185            )?;
5186            anyhow::Ok((buffer, completion))
5187        })??;
5188
5189        let apply_additional_edits = this.update(&mut cx, |this, cx| {
5190            this.apply_additional_edits_for_completion(
5191                buffer,
5192                Completion {
5193                    old_range: completion.old_range,
5194                    new_text: completion.new_text,
5195                    lsp_completion: completion.lsp_completion,
5196                    server_id: completion.server_id,
5197                    documentation: None,
5198                    label: CodeLabel {
5199                        text: Default::default(),
5200                        runs: Default::default(),
5201                        filter_range: Default::default(),
5202                    },
5203                    confirm: None,
5204                },
5205                false,
5206                cx,
5207            )
5208        })?;
5209
5210        Ok(proto::ApplyCompletionAdditionalEditsResponse {
5211            transaction: apply_additional_edits
5212                .await?
5213                .as_ref()
5214                .map(language::proto::serialize_transaction),
5215        })
5216    }
5217    pub fn last_formatting_failure(&self) -> Option<&str> {
5218        self.as_local()
5219            .and_then(|local| local.last_formatting_failure.as_deref())
5220    }
5221
5222    pub fn format(
5223        &mut self,
5224        buffers: HashSet<Model<Buffer>>,
5225        push_to_history: bool,
5226        trigger: FormatTrigger,
5227        cx: &mut ModelContext<Self>,
5228    ) -> Task<anyhow::Result<ProjectTransaction>> {
5229        if let Some(_) = self.as_local() {
5230            let buffers_with_paths = buffers
5231                .into_iter()
5232                .map(|buffer_handle| {
5233                    let buffer = buffer_handle.read(cx);
5234                    let buffer_abs_path = File::from_dyn(buffer.file())
5235                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
5236                    (buffer_handle, buffer_abs_path)
5237                })
5238                .collect::<Vec<_>>();
5239
5240            cx.spawn(move |lsp_store, mut cx| async move {
5241                let result = LocalLspStore::format_locally(
5242                    lsp_store.clone(),
5243                    buffers_with_paths,
5244                    push_to_history,
5245                    trigger,
5246                    cx.clone(),
5247                )
5248                .await;
5249
5250                lsp_store.update(&mut cx, |lsp_store, _| {
5251                    let local = lsp_store.as_local_mut().unwrap();
5252                    match &result {
5253                        Ok(_) => local.last_formatting_failure = None,
5254                        Err(error) => {
5255                            local.last_formatting_failure.replace(error.to_string());
5256                        }
5257                    }
5258                })?;
5259
5260                result
5261            })
5262        } else if let Some((client, project_id)) = self.upstream_client() {
5263            let buffer_store = self.buffer_store();
5264            cx.spawn(move |_, mut cx| async move {
5265                let response = client
5266                    .request(proto::FormatBuffers {
5267                        project_id,
5268                        trigger: trigger as i32,
5269                        buffer_ids: buffers
5270                            .iter()
5271                            .map(|buffer| {
5272                                buffer.update(&mut cx, |buffer, _| buffer.remote_id().into())
5273                            })
5274                            .collect::<Result<_>>()?,
5275                    })
5276                    .await?
5277                    .transaction
5278                    .ok_or_else(|| anyhow!("missing transaction"))?;
5279
5280                buffer_store
5281                    .update(&mut cx, |buffer_store, cx| {
5282                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
5283                    })?
5284                    .await
5285            })
5286        } else {
5287            Task::ready(Ok(ProjectTransaction::default()))
5288        }
5289    }
5290
5291    async fn handle_format_buffers(
5292        this: Model<Self>,
5293        envelope: TypedEnvelope<proto::FormatBuffers>,
5294        mut cx: AsyncAppContext,
5295    ) -> Result<proto::FormatBuffersResponse> {
5296        let sender_id = envelope.original_sender_id().unwrap_or_default();
5297        let format = this.update(&mut cx, |this, cx| {
5298            let mut buffers = HashSet::default();
5299            for buffer_id in &envelope.payload.buffer_ids {
5300                let buffer_id = BufferId::new(*buffer_id)?;
5301                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
5302            }
5303            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
5304            Ok::<_, anyhow::Error>(this.format(buffers, false, trigger, cx))
5305        })??;
5306
5307        let project_transaction = format.await?;
5308        let project_transaction = this.update(&mut cx, |this, cx| {
5309            this.buffer_store.update(cx, |buffer_store, cx| {
5310                buffer_store.serialize_project_transaction_for_peer(
5311                    project_transaction,
5312                    sender_id,
5313                    cx,
5314                )
5315            })
5316        })?;
5317        Ok(proto::FormatBuffersResponse {
5318            transaction: Some(project_transaction),
5319        })
5320    }
5321
5322    fn language_settings<'a>(
5323        &'a self,
5324        worktree: &'a Model<Worktree>,
5325        language: &LanguageName,
5326        cx: &'a mut ModelContext<Self>,
5327    ) -> &'a LanguageSettings {
5328        let root_file = worktree.update(cx, |tree, cx| tree.root_file(cx));
5329        all_language_settings(root_file.map(|f| f as _).as_ref(), cx).language(Some(language))
5330    }
5331
5332    pub fn start_language_servers(
5333        &mut self,
5334        worktree: &Model<Worktree>,
5335        language: LanguageName,
5336        cx: &mut ModelContext<Self>,
5337    ) {
5338        let settings = self.language_settings(worktree, &language, cx);
5339        if !settings.enable_language_server || self.mode.is_remote() {
5340            return;
5341        }
5342
5343        let available_lsp_adapters = self.languages.clone().lsp_adapters(&language);
5344        let available_language_servers = available_lsp_adapters
5345            .iter()
5346            .map(|lsp_adapter| lsp_adapter.name.clone())
5347            .collect::<Vec<_>>();
5348
5349        let desired_language_servers =
5350            settings.customized_language_servers(&available_language_servers);
5351
5352        let mut enabled_lsp_adapters: Vec<Arc<CachedLspAdapter>> = Vec::new();
5353        for desired_language_server in desired_language_servers {
5354            if let Some(adapter) = available_lsp_adapters
5355                .iter()
5356                .find(|adapter| adapter.name == desired_language_server)
5357            {
5358                enabled_lsp_adapters.push(adapter.clone());
5359                continue;
5360            }
5361
5362            if let Some(adapter) = self
5363                .languages
5364                .load_available_lsp_adapter(&desired_language_server)
5365            {
5366                self.languages
5367                    .register_lsp_adapter(language.clone(), adapter.adapter.clone());
5368                enabled_lsp_adapters.push(adapter);
5369                continue;
5370            }
5371
5372            log::warn!(
5373                "no language server found matching '{}'",
5374                desired_language_server.0
5375            );
5376        }
5377
5378        for adapter in &enabled_lsp_adapters {
5379            self.start_language_server(worktree, adapter.clone(), language.clone(), cx);
5380        }
5381
5382        // After starting all the language servers, reorder them to reflect the desired order
5383        // based on the settings.
5384        //
5385        // This is done, in part, to ensure that language servers loaded at different points
5386        // (e.g., native vs extension) still end up in the right order at the end, rather than
5387        // it being based on which language server happened to be loaded in first.
5388        self.languages
5389            .reorder_language_servers(&language, enabled_lsp_adapters);
5390    }
5391
5392    fn start_language_server_on_ssh_host(
5393        &mut self,
5394        worktree: &Model<Worktree>,
5395        adapter: Arc<CachedLspAdapter>,
5396        language: LanguageName,
5397        cx: &mut ModelContext<Self>,
5398    ) {
5399        let ssh = self.as_ssh().unwrap();
5400
5401        let delegate = Arc::new(SshLspAdapterDelegate {
5402            lsp_store: cx.handle().downgrade(),
5403            worktree: worktree.read(cx).snapshot(),
5404            upstream_client: ssh.upstream_client.clone(),
5405            language_registry: self.languages.clone(),
5406        }) as Arc<dyn LspAdapterDelegate>;
5407
5408        // TODO: We should use `adapter` here instead of reaching through the `CachedLspAdapter`.
5409        let lsp_adapter = adapter.adapter.clone();
5410
5411        let Some((upstream_client, project_id)) = self.upstream_client() else {
5412            return;
5413        };
5414        let worktree_id = worktree.read(cx).id().to_proto();
5415        let name = adapter.name().to_string();
5416
5417        let Some(available_language) = self.languages.available_language_for_name(&language) else {
5418            log::error!("failed to find available language {language}");
5419            return;
5420        };
5421
5422        let task = cx.spawn(|_, cx| async move {
5423            let user_binary_task = lsp_adapter.check_if_user_installed(delegate.as_ref(), &cx);
5424            let binary = match user_binary_task.await {
5425                Some(binary) => binary,
5426                None => {
5427                    return Err(anyhow!(
5428                        "Downloading language server for ssh host is not supported yet"
5429                    ))
5430                }
5431            };
5432
5433            let name = adapter.name();
5434            let code_action_kinds = adapter
5435                .adapter
5436                .code_action_kinds()
5437                .map(|kinds| serde_json::to_string(&kinds))
5438                .transpose()?;
5439            let get_options = adapter.adapter.clone().initialization_options(&delegate);
5440            let initialization_options = get_options
5441                .await?
5442                .map(|options| serde_json::to_string(&options))
5443                .transpose()?;
5444
5445            let language_server_command = proto::LanguageServerCommand {
5446                path: binary.path.to_string_lossy().to_string(),
5447                arguments: binary
5448                    .arguments
5449                    .iter()
5450                    .map(|args| args.to_string_lossy().to_string())
5451                    .collect(),
5452                env: binary.env.unwrap_or_default().into_iter().collect(),
5453            };
5454
5455            upstream_client
5456                .request(proto::CreateLanguageServer {
5457                    project_id,
5458                    worktree_id,
5459                    name: name.0.to_string(),
5460                    binary: Some(language_server_command),
5461                    initialization_options,
5462                    code_action_kinds,
5463                    language: Some(proto::AvailableLanguage {
5464                        name: language.to_proto(),
5465                        matcher: serde_json::to_string(&available_language.matcher())?,
5466                    }),
5467                })
5468                .await
5469        });
5470        cx.spawn(|this, mut cx| async move {
5471            if let Err(e) = task.await {
5472                this.update(&mut cx, |_this, cx| {
5473                    cx.emit(LspStoreEvent::Notification(format!(
5474                        "failed to start {}: {}",
5475                        name, e
5476                    )))
5477                })
5478                .ok();
5479            }
5480        })
5481        .detach();
5482    }
5483
5484    fn start_language_server(
5485        &mut self,
5486        worktree_handle: &Model<Worktree>,
5487        adapter: Arc<CachedLspAdapter>,
5488        language: LanguageName,
5489        cx: &mut ModelContext<Self>,
5490    ) {
5491        if self.mode.is_remote() {
5492            return;
5493        }
5494
5495        let worktree = worktree_handle.read(cx);
5496        let worktree_id = worktree.id();
5497        let worktree_path = worktree.abs_path();
5498        let key = (worktree_id, adapter.name.clone());
5499        if self.language_server_ids.contains_key(&key) {
5500            return;
5501        }
5502
5503        if self.mode.is_ssh() {
5504            self.start_language_server_on_ssh_host(worktree_handle, adapter, language, cx);
5505            return;
5506        }
5507
5508        if adapter.reinstall_attempt_count.load(SeqCst) > MAX_SERVER_REINSTALL_ATTEMPT_COUNT {
5509            return;
5510        }
5511
5512        let local = self.as_local().unwrap();
5513
5514        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
5515        let lsp_adapter_delegate = LocalLspAdapterDelegate::for_local(self, worktree_handle, cx);
5516        let project_environment = local.environment.update(cx, |environment, cx| {
5517            environment.get_environment(Some(worktree_id), Some(worktree_path.clone()), cx)
5518        });
5519
5520        let pending_server = match self.languages.create_pending_language_server(
5521            stderr_capture.clone(),
5522            language.clone(),
5523            adapter.clone(),
5524            Arc::clone(&worktree_path),
5525            lsp_adapter_delegate.clone(),
5526            project_environment,
5527            cx,
5528        ) {
5529            Some(pending_server) => pending_server,
5530            None => return,
5531        };
5532
5533        let project_settings = ProjectSettings::get(
5534            Some(SettingsLocation {
5535                worktree_id,
5536                path: Path::new(""),
5537            }),
5538            cx,
5539        );
5540
5541        // We need some on the SSH client, and some on SSH host
5542        let lsp = project_settings.lsp.get(&adapter.name);
5543        let override_options = lsp.and_then(|s| s.initialization_options.clone());
5544
5545        let server_id = pending_server.server_id;
5546        let container_dir = pending_server.container_dir.clone();
5547        let state = LanguageServerState::Starting({
5548            let adapter = adapter.clone();
5549            let server_name = adapter.name.0.clone();
5550            let language = language.clone();
5551            let key = key.clone();
5552
5553            cx.spawn(move |this, mut cx| async move {
5554                let result = Self::setup_and_insert_language_server(
5555                    this.clone(),
5556                    lsp_adapter_delegate,
5557                    override_options,
5558                    pending_server,
5559                    adapter.clone(),
5560                    language.clone(),
5561                    server_id,
5562                    key,
5563                    &mut cx,
5564                )
5565                .await;
5566
5567                match result {
5568                    Ok(server) => {
5569                        stderr_capture.lock().take();
5570                        server
5571                    }
5572
5573                    Err(err) => {
5574                        log::error!("failed to start language server {server_name:?}: {err}");
5575                        log::error!("server stderr: {:?}", stderr_capture.lock().take());
5576
5577                        let this = this.upgrade()?;
5578                        let container_dir = container_dir?;
5579
5580                        let attempt_count = adapter.reinstall_attempt_count.fetch_add(1, SeqCst);
5581                        if attempt_count >= MAX_SERVER_REINSTALL_ATTEMPT_COUNT {
5582                            let max = MAX_SERVER_REINSTALL_ATTEMPT_COUNT;
5583                            log::error!("Hit {max} reinstallation attempts for {server_name:?}");
5584                            return None;
5585                        }
5586
5587                        log::info!(
5588                            "retrying installation of language server {server_name:?} in {}s",
5589                            SERVER_REINSTALL_DEBOUNCE_TIMEOUT.as_secs()
5590                        );
5591                        cx.background_executor()
5592                            .timer(SERVER_REINSTALL_DEBOUNCE_TIMEOUT)
5593                            .await;
5594
5595                        let installation_test_binary = adapter
5596                            .installation_test_binary(container_dir.to_path_buf())
5597                            .await;
5598
5599                        this.update(&mut cx, |_, cx| {
5600                            Self::check_errored_server(
5601                                language,
5602                                adapter,
5603                                server_id,
5604                                installation_test_binary,
5605                                cx,
5606                            )
5607                        })
5608                        .ok();
5609
5610                        None
5611                    }
5612                }
5613            })
5614        });
5615
5616        self.as_local_mut()
5617            .unwrap()
5618            .language_servers
5619            .insert(server_id, state);
5620        self.language_server_ids.insert(key, server_id);
5621    }
5622
5623    #[allow(clippy::too_many_arguments)]
5624    async fn setup_and_insert_language_server(
5625        this: WeakModel<Self>,
5626        delegate: Arc<dyn LspAdapterDelegate>,
5627        override_initialization_options: Option<serde_json::Value>,
5628        pending_server: PendingLanguageServer,
5629        adapter: Arc<CachedLspAdapter>,
5630        language: LanguageName,
5631        server_id: LanguageServerId,
5632        key: (WorktreeId, LanguageServerName),
5633        cx: &mut AsyncAppContext,
5634    ) -> Result<Option<Arc<LanguageServer>>> {
5635        let language_server = Self::setup_pending_language_server(
5636            this.clone(),
5637            override_initialization_options,
5638            pending_server,
5639            delegate,
5640            adapter.clone(),
5641            server_id,
5642            cx,
5643        )
5644        .await?;
5645
5646        let this = match this.upgrade() {
5647            Some(this) => this,
5648            None => return Err(anyhow!("failed to upgrade project handle")),
5649        };
5650
5651        this.update(cx, |this, cx| {
5652            this.insert_newly_running_language_server(
5653                language,
5654                adapter,
5655                language_server.clone(),
5656                server_id,
5657                key,
5658                cx,
5659            )
5660        })??;
5661
5662        Ok(Some(language_server))
5663    }
5664
5665    fn reinstall_language_server(
5666        &mut self,
5667        language: LanguageName,
5668        adapter: Arc<CachedLspAdapter>,
5669        server_id: LanguageServerId,
5670        cx: &mut ModelContext<Self>,
5671    ) -> Option<Task<()>> {
5672        log::info!("beginning to reinstall server");
5673
5674        if let Some(local) = self.as_local_mut() {
5675            let existing_server = match local.language_servers.remove(&server_id) {
5676                Some(LanguageServerState::Running { server, .. }) => Some(server),
5677                _ => None,
5678            };
5679
5680            self.worktree_store.update(cx, |store, cx| {
5681                for worktree in store.worktrees() {
5682                    let key = (worktree.read(cx).id(), adapter.name.clone());
5683                    self.language_server_ids.remove(&key);
5684                }
5685            });
5686
5687            Some(cx.spawn(move |this, mut cx| async move {
5688                if let Some(task) = existing_server.and_then(|server| server.shutdown()) {
5689                    log::info!("shutting down existing server");
5690                    task.await;
5691                }
5692
5693                // TODO: This is race-safe with regards to preventing new instances from
5694                // starting while deleting, but existing instances in other projects are going
5695                // to be very confused and messed up
5696                let Some(task) = this
5697                    .update(&mut cx, |this, cx| {
5698                        this.languages.delete_server_container(adapter.clone(), cx)
5699                    })
5700                    .log_err()
5701                else {
5702                    return;
5703                };
5704                task.await;
5705
5706                this.update(&mut cx, |this, cx| {
5707                    for worktree in this.worktree_store.read(cx).worktrees().collect::<Vec<_>>() {
5708                        this.start_language_server(
5709                            &worktree,
5710                            adapter.clone(),
5711                            language.clone(),
5712                            cx,
5713                        );
5714                    }
5715                })
5716                .ok();
5717            }))
5718        } else if let Some(_ssh_store) = self.as_ssh() {
5719            // TODO
5720            None
5721        } else {
5722            None
5723        }
5724    }
5725
5726    async fn shutdown_language_server(
5727        server_state: Option<LanguageServerState>,
5728        name: LanguageServerName,
5729        cx: AsyncAppContext,
5730    ) {
5731        let server = match server_state {
5732            Some(LanguageServerState::Starting(task)) => {
5733                let mut timer = cx
5734                    .background_executor()
5735                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
5736                    .fuse();
5737
5738                select! {
5739                    server = task.fuse() => server,
5740                    _ = timer => {
5741                        log::info!(
5742                            "timeout waiting for language server {} to finish launching before stopping",
5743                            name
5744                        );
5745                        None
5746                    },
5747                }
5748            }
5749
5750            Some(LanguageServerState::Running { server, .. }) => Some(server),
5751
5752            None => None,
5753        };
5754
5755        if let Some(server) = server {
5756            if let Some(shutdown) = server.shutdown() {
5757                shutdown.await;
5758            }
5759        }
5760    }
5761
5762    // Returns a list of all of the worktrees which no longer have a language server and the root path
5763    // for the stopped server
5764    pub fn stop_language_server(
5765        &mut self,
5766        worktree_id: WorktreeId,
5767        adapter_name: LanguageServerName,
5768        cx: &mut ModelContext<Self>,
5769    ) -> Task<Vec<WorktreeId>> {
5770        let key = (worktree_id, adapter_name);
5771        if self.mode.is_local() {
5772            if let Some(server_id) = self.language_server_ids.remove(&key) {
5773                let name = key.1;
5774                log::info!("stopping language server {name}");
5775
5776                // Remove other entries for this language server as well
5777                let mut orphaned_worktrees = vec![worktree_id];
5778                let other_keys = self.language_server_ids.keys().cloned().collect::<Vec<_>>();
5779                for other_key in other_keys {
5780                    if self.language_server_ids.get(&other_key) == Some(&server_id) {
5781                        self.language_server_ids.remove(&other_key);
5782                        orphaned_worktrees.push(other_key.0);
5783                    }
5784                }
5785
5786                self.buffer_store.update(cx, |buffer_store, cx| {
5787                    for buffer in buffer_store.buffers() {
5788                        buffer.update(cx, |buffer, cx| {
5789                            buffer.update_diagnostics(
5790                                server_id,
5791                                DiagnosticSet::new([], buffer),
5792                                cx,
5793                            );
5794                        });
5795                    }
5796                });
5797
5798                for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
5799                    summaries.retain(|path, summaries_by_server_id| {
5800                        if summaries_by_server_id.remove(&server_id).is_some() {
5801                            if let Some((client, project_id)) = self.downstream_client.clone() {
5802                                client
5803                                    .send(proto::UpdateDiagnosticSummary {
5804                                        project_id,
5805                                        worktree_id: worktree_id.to_proto(),
5806                                        summary: Some(proto::DiagnosticSummary {
5807                                            path: path.to_string_lossy().to_string(),
5808                                            language_server_id: server_id.0 as u64,
5809                                            error_count: 0,
5810                                            warning_count: 0,
5811                                        }),
5812                                    })
5813                                    .log_err();
5814                            }
5815                            !summaries_by_server_id.is_empty()
5816                        } else {
5817                            true
5818                        }
5819                    });
5820                }
5821
5822                for diagnostics in self.diagnostics.values_mut() {
5823                    diagnostics.retain(|_, diagnostics_by_server_id| {
5824                        if let Ok(ix) =
5825                            diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0)
5826                        {
5827                            diagnostics_by_server_id.remove(ix);
5828                            !diagnostics_by_server_id.is_empty()
5829                        } else {
5830                            true
5831                        }
5832                    });
5833                }
5834
5835                self.as_local_mut()
5836                    .unwrap()
5837                    .language_server_watched_paths
5838                    .remove(&server_id);
5839                self.language_server_statuses.remove(&server_id);
5840                cx.notify();
5841
5842                let server_state = self
5843                    .as_local_mut()
5844                    .unwrap()
5845                    .language_servers
5846                    .remove(&server_id);
5847                cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
5848                cx.spawn(move |_, cx| async move {
5849                    Self::shutdown_language_server(server_state, name, cx).await;
5850                    orphaned_worktrees
5851                })
5852            } else {
5853                Task::ready(Vec::new())
5854            }
5855        } else if self.mode.is_ssh() {
5856            // TODO ssh
5857            Task::ready(Vec::new())
5858        } else {
5859            Task::ready(Vec::new())
5860        }
5861    }
5862
5863    pub fn restart_language_servers_for_buffers(
5864        &mut self,
5865        buffers: impl IntoIterator<Item = Model<Buffer>>,
5866        cx: &mut ModelContext<Self>,
5867    ) {
5868        if let Some((client, project_id)) = self.upstream_client() {
5869            let request = client.request(proto::RestartLanguageServers {
5870                project_id,
5871                buffer_ids: buffers
5872                    .into_iter()
5873                    .map(|b| b.read(cx).remote_id().to_proto())
5874                    .collect(),
5875            });
5876            cx.background_executor()
5877                .spawn(request)
5878                .detach_and_log_err(cx);
5879        } else {
5880            #[allow(clippy::mutable_key_type)]
5881            let language_server_lookup_info: HashSet<(Model<Worktree>, LanguageName)> = buffers
5882                .into_iter()
5883                .filter_map(|buffer| {
5884                    let buffer = buffer.read(cx);
5885                    let file = buffer.file()?;
5886                    let worktree = File::from_dyn(Some(file))?.worktree.clone();
5887                    let language =
5888                        self.languages
5889                            .language_for_file(file, Some(buffer.as_rope()), cx)?;
5890
5891                    Some((worktree, language.name()))
5892                })
5893                .collect();
5894
5895            for (worktree, language) in language_server_lookup_info {
5896                self.restart_language_servers(worktree, language, cx);
5897            }
5898        }
5899    }
5900
5901    pub fn restart_language_servers(
5902        &mut self,
5903        worktree: Model<Worktree>,
5904        language: LanguageName,
5905        cx: &mut ModelContext<Self>,
5906    ) {
5907        let worktree_id = worktree.read(cx).id();
5908
5909        let stop_tasks = self
5910            .languages
5911            .clone()
5912            .lsp_adapters(&language)
5913            .iter()
5914            .map(|adapter| {
5915                let stop_task = self.stop_language_server(worktree_id, adapter.name.clone(), cx);
5916                (stop_task, adapter.name.clone())
5917            })
5918            .collect::<Vec<_>>();
5919        if stop_tasks.is_empty() {
5920            return;
5921        }
5922
5923        cx.spawn(move |this, mut cx| async move {
5924            // For each stopped language server, record all of the worktrees with which
5925            // it was associated.
5926            let mut affected_worktrees = Vec::new();
5927            for (stop_task, language_server_name) in stop_tasks {
5928                for affected_worktree_id in stop_task.await {
5929                    affected_worktrees.push((affected_worktree_id, language_server_name.clone()));
5930                }
5931            }
5932
5933            this.update(&mut cx, |this, cx| {
5934                // Restart the language server for the given worktree.
5935                this.start_language_servers(&worktree, language.clone(), cx);
5936
5937                // Lookup new server ids and set them for each of the orphaned worktrees
5938                for (affected_worktree_id, language_server_name) in affected_worktrees {
5939                    if let Some(new_server_id) = this
5940                        .language_server_ids
5941                        .get(&(worktree_id, language_server_name.clone()))
5942                        .cloned()
5943                    {
5944                        this.language_server_ids
5945                            .insert((affected_worktree_id, language_server_name), new_server_id);
5946                    }
5947                }
5948            })
5949            .ok();
5950        })
5951        .detach();
5952    }
5953
5954    fn check_errored_server(
5955        language: LanguageName,
5956        adapter: Arc<CachedLspAdapter>,
5957        server_id: LanguageServerId,
5958        installation_test_binary: Option<LanguageServerBinary>,
5959        cx: &mut ModelContext<Self>,
5960    ) {
5961        if !adapter.can_be_reinstalled() {
5962            log::info!(
5963                "Validation check requested for {:?} but it cannot be reinstalled",
5964                adapter.name.0
5965            );
5966            return;
5967        }
5968
5969        cx.spawn(move |this, mut cx| async move {
5970            log::info!("About to spawn test binary");
5971
5972            // A lack of test binary counts as a failure
5973            let process = installation_test_binary.and_then(|binary| {
5974                smol::process::Command::new(&binary.path)
5975                    .current_dir(&binary.path)
5976                    .args(binary.arguments)
5977                    .stdin(Stdio::piped())
5978                    .stdout(Stdio::piped())
5979                    .stderr(Stdio::inherit())
5980                    .kill_on_drop(true)
5981                    .spawn()
5982                    .ok()
5983            });
5984
5985            const PROCESS_TIMEOUT: Duration = Duration::from_secs(5);
5986            let mut timeout = cx.background_executor().timer(PROCESS_TIMEOUT).fuse();
5987
5988            let mut errored = false;
5989            if let Some(mut process) = process {
5990                futures::select! {
5991                    status = process.status().fuse() => match status {
5992                        Ok(status) => errored = !status.success(),
5993                        Err(_) => errored = true,
5994                    },
5995
5996                    _ = timeout => {
5997                        log::info!("test binary time-ed out, this counts as a success");
5998                        _ = process.kill();
5999                    }
6000                }
6001            } else {
6002                log::warn!("test binary failed to launch");
6003                errored = true;
6004            }
6005
6006            if errored {
6007                log::warn!("test binary check failed");
6008                let task = this
6009                    .update(&mut cx, move |this, cx| {
6010                        this.reinstall_language_server(language, adapter, server_id, cx)
6011                    })
6012                    .ok()
6013                    .flatten();
6014
6015                if let Some(task) = task {
6016                    task.await;
6017                }
6018            }
6019        })
6020        .detach();
6021    }
6022
6023    async fn setup_pending_language_server(
6024        this: WeakModel<Self>,
6025        override_options: Option<serde_json::Value>,
6026        pending_server: PendingLanguageServer,
6027        delegate: Arc<dyn LspAdapterDelegate>,
6028        adapter: Arc<CachedLspAdapter>,
6029        server_id: LanguageServerId,
6030        cx: &mut AsyncAppContext,
6031    ) -> Result<Arc<LanguageServer>> {
6032        let workspace_config = adapter
6033            .adapter
6034            .clone()
6035            .workspace_configuration(&delegate, cx)
6036            .await?;
6037        // This has to come from the server
6038        let (language_server, mut initialization_options) = pending_server.task.await?;
6039
6040        let name = language_server.name();
6041        language_server
6042            .on_notification::<lsp::notification::PublishDiagnostics, _>({
6043                let adapter = adapter.clone();
6044                let this = this.clone();
6045                move |mut params, mut cx| {
6046                    let adapter = adapter.clone();
6047                    if let Some(this) = this.upgrade() {
6048                        adapter.process_diagnostics(&mut params);
6049                        // Everything else has to be on the server, Can we make it on the client?
6050                        this.update(&mut cx, |this, cx| {
6051                            this.update_diagnostics(
6052                                server_id,
6053                                params,
6054                                &adapter.disk_based_diagnostic_sources,
6055                                cx,
6056                            )
6057                            .log_err();
6058                        })
6059                        .ok();
6060                    }
6061                }
6062            })
6063            .detach();
6064
6065        language_server
6066            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
6067                let adapter = adapter.adapter.clone();
6068                let delegate = delegate.clone();
6069                move |params, mut cx| {
6070                    let adapter = adapter.clone();
6071                    let delegate = delegate.clone();
6072                    async move {
6073                        let workspace_config =
6074                            adapter.workspace_configuration(&delegate, &mut cx).await?;
6075                        Ok(params
6076                            .items
6077                            .into_iter()
6078                            .map(|item| {
6079                                if let Some(section) = &item.section {
6080                                    workspace_config
6081                                        .get(section)
6082                                        .cloned()
6083                                        .unwrap_or(serde_json::Value::Null)
6084                                } else {
6085                                    workspace_config.clone()
6086                                }
6087                            })
6088                            .collect())
6089                    }
6090                }
6091            })
6092            .detach();
6093
6094        let id = language_server.server_id();
6095        language_server
6096            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
6097                let this = this.clone();
6098                move |_, mut cx| {
6099                    let this = this.clone();
6100                    async move {
6101                        let Some(server) =
6102                            this.update(&mut cx, |this, _| this.language_server_for_id(id))?
6103                        else {
6104                            return Ok(None);
6105                        };
6106                        let root = server.root_path();
6107                        let Ok(uri) = Url::from_file_path(&root) else {
6108                            return Ok(None);
6109                        };
6110                        Ok(Some(vec![WorkspaceFolder {
6111                            uri,
6112                            name: Default::default(),
6113                        }]))
6114                    }
6115                }
6116            })
6117            .detach();
6118        // Even though we don't have handling for these requests, respond to them to
6119        // avoid stalling any language server like `gopls` which waits for a response
6120        // to these requests when initializing.
6121        language_server
6122            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
6123                let this = this.clone();
6124                move |params, mut cx| {
6125                    let this = this.clone();
6126                    async move {
6127                        this.update(&mut cx, |this, _| {
6128                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
6129                            {
6130                                if let lsp::NumberOrString::String(token) = params.token {
6131                                    status.progress_tokens.insert(token);
6132                                }
6133                            }
6134                        })?;
6135
6136                        Ok(())
6137                    }
6138                }
6139            })
6140            .detach();
6141
6142        language_server
6143            .on_request::<lsp::request::RegisterCapability, _, _>({
6144                let this = this.clone();
6145                move |params, mut cx| {
6146                    let this = this.clone();
6147                    async move {
6148                        for reg in params.registrations {
6149                            match reg.method.as_str() {
6150                                "workspace/didChangeWatchedFiles" => {
6151                                    if let Some(options) = reg.register_options {
6152                                        let options = serde_json::from_value(options)?;
6153                                        this.update(&mut cx, |this, cx| {
6154                                            this.on_lsp_did_change_watched_files(
6155                                                server_id, &reg.id, options, cx,
6156                                            );
6157                                        })?;
6158                                    }
6159                                }
6160                                "textDocument/rangeFormatting" => {
6161                                    this.update(&mut cx, |this, _| {
6162                                        if let Some(server) = this.language_server_for_id(server_id)
6163                                        {
6164                                            let options = reg
6165                                                .register_options
6166                                                .map(|options| {
6167                                                    serde_json::from_value::<
6168                                                        lsp::DocumentRangeFormattingOptions,
6169                                                    >(
6170                                                        options
6171                                                    )
6172                                                })
6173                                                .transpose()?;
6174                                            let provider = match options {
6175                                                None => OneOf::Left(true),
6176                                                Some(options) => OneOf::Right(options),
6177                                            };
6178                                            server.update_capabilities(|capabilities| {
6179                                                capabilities.document_range_formatting_provider =
6180                                                    Some(provider);
6181                                            })
6182                                        }
6183                                        anyhow::Ok(())
6184                                    })??;
6185                                }
6186                                "textDocument/onTypeFormatting" => {
6187                                    this.update(&mut cx, |this, _| {
6188                                        if let Some(server) = this.language_server_for_id(server_id)
6189                                        {
6190                                            let options = reg
6191                                                .register_options
6192                                                .map(|options| {
6193                                                    serde_json::from_value::<
6194                                                        lsp::DocumentOnTypeFormattingOptions,
6195                                                    >(
6196                                                        options
6197                                                    )
6198                                                })
6199                                                .transpose()?;
6200                                            if let Some(options) = options {
6201                                                server.update_capabilities(|capabilities| {
6202                                                    capabilities
6203                                                        .document_on_type_formatting_provider =
6204                                                        Some(options);
6205                                                })
6206                                            }
6207                                        }
6208                                        anyhow::Ok(())
6209                                    })??;
6210                                }
6211                                "textDocument/formatting" => {
6212                                    this.update(&mut cx, |this, _| {
6213                                        if let Some(server) = this.language_server_for_id(server_id)
6214                                        {
6215                                            let options = reg
6216                                                .register_options
6217                                                .map(|options| {
6218                                                    serde_json::from_value::<
6219                                                        lsp::DocumentFormattingOptions,
6220                                                    >(
6221                                                        options
6222                                                    )
6223                                                })
6224                                                .transpose()?;
6225                                            let provider = match options {
6226                                                None => OneOf::Left(true),
6227                                                Some(options) => OneOf::Right(options),
6228                                            };
6229                                            server.update_capabilities(|capabilities| {
6230                                                capabilities.document_formatting_provider =
6231                                                    Some(provider);
6232                                            })
6233                                        }
6234                                        anyhow::Ok(())
6235                                    })??;
6236                                }
6237                                _ => log::warn!("unhandled capability registration: {reg:?}"),
6238                            }
6239                        }
6240                        Ok(())
6241                    }
6242                }
6243            })
6244            .detach();
6245
6246        language_server
6247            .on_request::<lsp::request::UnregisterCapability, _, _>({
6248                let this = this.clone();
6249                move |params, mut cx| {
6250                    let this = this.clone();
6251                    async move {
6252                        for unreg in params.unregisterations.iter() {
6253                            match unreg.method.as_str() {
6254                                "workspace/didChangeWatchedFiles" => {
6255                                    this.update(&mut cx, |this, cx| {
6256                                        this.on_lsp_unregister_did_change_watched_files(
6257                                            server_id, &unreg.id, cx,
6258                                        );
6259                                    })?;
6260                                }
6261                                "textDocument/rangeFormatting" => {
6262                                    this.update(&mut cx, |this, _| {
6263                                        if let Some(server) = this.language_server_for_id(server_id)
6264                                        {
6265                                            server.update_capabilities(|capabilities| {
6266                                                capabilities.document_range_formatting_provider =
6267                                                    None
6268                                            })
6269                                        }
6270                                    })?;
6271                                }
6272                                "textDocument/onTypeFormatting" => {
6273                                    this.update(&mut cx, |this, _| {
6274                                        if let Some(server) = this.language_server_for_id(server_id)
6275                                        {
6276                                            server.update_capabilities(|capabilities| {
6277                                                capabilities.document_on_type_formatting_provider =
6278                                                    None;
6279                                            })
6280                                        }
6281                                    })?;
6282                                }
6283                                "textDocument/formatting" => {
6284                                    this.update(&mut cx, |this, _| {
6285                                        if let Some(server) = this.language_server_for_id(server_id)
6286                                        {
6287                                            server.update_capabilities(|capabilities| {
6288                                                capabilities.document_formatting_provider = None;
6289                                            })
6290                                        }
6291                                    })?;
6292                                }
6293                                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
6294                            }
6295                        }
6296                        Ok(())
6297                    }
6298                }
6299            })
6300            .detach();
6301
6302        language_server
6303            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
6304                let adapter = adapter.clone();
6305                let this = this.clone();
6306                move |params, cx| {
6307                    Self::on_lsp_workspace_edit(
6308                        this.clone(),
6309                        params,
6310                        server_id,
6311                        adapter.clone(),
6312                        cx,
6313                    )
6314                }
6315            })
6316            .detach();
6317
6318        language_server
6319            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
6320                let this = this.clone();
6321                move |(), mut cx| {
6322                    let this = this.clone();
6323                    async move {
6324                        this.update(&mut cx, |this, cx| {
6325                            cx.emit(LspStoreEvent::RefreshInlayHints);
6326                            this.downstream_client.as_ref().map(|(client, project_id)| {
6327                                client.send(proto::RefreshInlayHints {
6328                                    project_id: *project_id,
6329                                })
6330                            })
6331                        })?
6332                        .transpose()?;
6333                        Ok(())
6334                    }
6335                }
6336            })
6337            .detach();
6338
6339        language_server
6340            .on_request::<lsp::request::ShowMessageRequest, _, _>({
6341                let this = this.clone();
6342                let name = name.to_string();
6343                move |params, mut cx| {
6344                    let this = this.clone();
6345                    let name = name.to_string();
6346                    async move {
6347                        let actions = params.actions.unwrap_or_default();
6348                        let (tx, mut rx) = smol::channel::bounded(1);
6349                        let request = LanguageServerPromptRequest {
6350                            level: match params.typ {
6351                                lsp::MessageType::ERROR => PromptLevel::Critical,
6352                                lsp::MessageType::WARNING => PromptLevel::Warning,
6353                                _ => PromptLevel::Info,
6354                            },
6355                            message: params.message,
6356                            actions,
6357                            response_channel: tx,
6358                            lsp_name: name.clone(),
6359                        };
6360
6361                        let did_update = this
6362                            .update(&mut cx, |_, cx| {
6363                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
6364                            })
6365                            .is_ok();
6366                        if did_update {
6367                            let response = rx.next().await;
6368
6369                            Ok(response)
6370                        } else {
6371                            Ok(None)
6372                        }
6373                    }
6374                }
6375            })
6376            .detach();
6377
6378        let disk_based_diagnostics_progress_token =
6379            adapter.disk_based_diagnostics_progress_token.clone();
6380
6381        language_server
6382            .on_notification::<ServerStatus, _>({
6383                let this = this.clone();
6384                let name = name.to_string();
6385                move |params, mut cx| {
6386                    let this = this.clone();
6387                    let name = name.to_string();
6388                    if let Some(ref message) = params.message {
6389                        let message = message.trim();
6390                        if !message.is_empty() {
6391                            let formatted_message = format!(
6392                                "Language server {name} (id {server_id}) status update: {message}"
6393                            );
6394                            match params.health {
6395                                ServerHealthStatus::Ok => log::info!("{}", formatted_message),
6396                                ServerHealthStatus::Warning => log::warn!("{}", formatted_message),
6397                                ServerHealthStatus::Error => {
6398                                    log::error!("{}", formatted_message);
6399                                    let (tx, _rx) = smol::channel::bounded(1);
6400                                    let request = LanguageServerPromptRequest {
6401                                        level: PromptLevel::Critical,
6402                                        message: params.message.unwrap_or_default(),
6403                                        actions: Vec::new(),
6404                                        response_channel: tx,
6405                                        lsp_name: name.clone(),
6406                                    };
6407                                    let _ = this
6408                                        .update(&mut cx, |_, cx| {
6409                                            cx.emit(LspStoreEvent::LanguageServerPrompt(request));
6410                                        })
6411                                        .ok();
6412                                }
6413                                ServerHealthStatus::Other(status) => {
6414                                    log::info!(
6415                                        "Unknown server health: {status}\n{formatted_message}"
6416                                    )
6417                                }
6418                            }
6419                        }
6420                    }
6421                }
6422            })
6423            .detach();
6424        language_server
6425            .on_notification::<lsp::notification::ShowMessage, _>({
6426                let this = this.clone();
6427                let name = name.to_string();
6428                move |params, mut cx| {
6429                    let this = this.clone();
6430                    let name = name.to_string();
6431
6432                    let (tx, _) = smol::channel::bounded(1);
6433                    let request = LanguageServerPromptRequest {
6434                        level: match params.typ {
6435                            lsp::MessageType::ERROR => PromptLevel::Critical,
6436                            lsp::MessageType::WARNING => PromptLevel::Warning,
6437                            _ => PromptLevel::Info,
6438                        },
6439                        message: params.message,
6440                        actions: vec![],
6441                        response_channel: tx,
6442                        lsp_name: name.clone(),
6443                    };
6444
6445                    let _ = this.update(&mut cx, |_, cx| {
6446                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
6447                    });
6448                }
6449            })
6450            .detach();
6451        language_server
6452            .on_notification::<lsp::notification::Progress, _>({
6453                let this = this.clone();
6454                move |params, mut cx| {
6455                    if let Some(this) = this.upgrade() {
6456                        this.update(&mut cx, |this, cx| {
6457                            this.on_lsp_progress(
6458                                params,
6459                                server_id,
6460                                disk_based_diagnostics_progress_token.clone(),
6461                                cx,
6462                            );
6463                        })
6464                        .ok();
6465                    }
6466                }
6467            })
6468            .detach();
6469
6470        language_server
6471            .on_notification::<lsp::notification::LogMessage, _>({
6472                let this = this.clone();
6473                move |params, mut cx| {
6474                    if let Some(this) = this.upgrade() {
6475                        this.update(&mut cx, |_, cx| {
6476                            cx.emit(LspStoreEvent::LanguageServerLog(
6477                                server_id,
6478                                LanguageServerLogType::Log(params.typ),
6479                                params.message,
6480                            ));
6481                        })
6482                        .ok();
6483                    }
6484                }
6485            })
6486            .detach();
6487
6488        language_server
6489            .on_notification::<lsp::notification::LogTrace, _>({
6490                let this = this.clone();
6491                move |params, mut cx| {
6492                    if let Some(this) = this.upgrade() {
6493                        this.update(&mut cx, |_, cx| {
6494                            cx.emit(LspStoreEvent::LanguageServerLog(
6495                                server_id,
6496                                LanguageServerLogType::Trace(params.verbose),
6497                                params.message,
6498                            ));
6499                        })
6500                        .ok();
6501                    }
6502                }
6503            })
6504            .detach();
6505
6506        match (&mut initialization_options, override_options) {
6507            (Some(initialization_options), Some(override_options)) => {
6508                merge_json_value_into(override_options, initialization_options);
6509            }
6510            (None, override_options) => initialization_options = override_options,
6511            _ => {}
6512        }
6513
6514        let language_server = cx
6515            .update(|cx| language_server.initialize(initialization_options, cx))?
6516            .await
6517            .inspect_err(|_| {
6518                if let Some(this) = this.upgrade() {
6519                    this.update(cx, |_, cx| {
6520                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
6521                    })
6522                    .ok();
6523                }
6524            })?;
6525
6526        language_server
6527            .notify::<lsp::notification::DidChangeConfiguration>(
6528                lsp::DidChangeConfigurationParams {
6529                    settings: workspace_config,
6530                },
6531            )
6532            .ok();
6533
6534        Ok(language_server)
6535    }
6536
6537    pub fn update_diagnostics(
6538        &mut self,
6539        language_server_id: LanguageServerId,
6540        mut params: lsp::PublishDiagnosticsParams,
6541        disk_based_sources: &[String],
6542        cx: &mut ModelContext<Self>,
6543    ) -> Result<()> {
6544        let abs_path = params
6545            .uri
6546            .to_file_path()
6547            .map_err(|_| anyhow!("URI is not a file"))?;
6548        let mut diagnostics = Vec::default();
6549        let mut primary_diagnostic_group_ids = HashMap::default();
6550        let mut sources_by_group_id = HashMap::default();
6551        let mut supporting_diagnostics = HashMap::default();
6552
6553        // Ensure that primary diagnostics are always the most severe
6554        params.diagnostics.sort_by_key(|item| item.severity);
6555
6556        for diagnostic in &params.diagnostics {
6557            let source = diagnostic.source.as_ref();
6558            let code = diagnostic.code.as_ref().map(|code| match code {
6559                lsp::NumberOrString::Number(code) => code.to_string(),
6560                lsp::NumberOrString::String(code) => code.clone(),
6561            });
6562            let range = range_from_lsp(diagnostic.range);
6563            let is_supporting = diagnostic
6564                .related_information
6565                .as_ref()
6566                .map_or(false, |infos| {
6567                    infos.iter().any(|info| {
6568                        primary_diagnostic_group_ids.contains_key(&(
6569                            source,
6570                            code.clone(),
6571                            range_from_lsp(info.location.range),
6572                        ))
6573                    })
6574                });
6575
6576            let is_unnecessary = diagnostic.tags.as_ref().map_or(false, |tags| {
6577                tags.iter().any(|tag| *tag == DiagnosticTag::UNNECESSARY)
6578            });
6579
6580            if is_supporting {
6581                supporting_diagnostics.insert(
6582                    (source, code.clone(), range),
6583                    (diagnostic.severity, is_unnecessary),
6584                );
6585            } else {
6586                let group_id = post_inc(&mut self.next_diagnostic_group_id);
6587                let is_disk_based =
6588                    source.map_or(false, |source| disk_based_sources.contains(source));
6589
6590                sources_by_group_id.insert(group_id, source);
6591                primary_diagnostic_group_ids
6592                    .insert((source, code.clone(), range.clone()), group_id);
6593
6594                diagnostics.push(DiagnosticEntry {
6595                    range,
6596                    diagnostic: Diagnostic {
6597                        source: diagnostic.source.clone(),
6598                        code: code.clone(),
6599                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
6600                        message: diagnostic.message.trim().to_string(),
6601                        group_id,
6602                        is_primary: true,
6603                        is_disk_based,
6604                        is_unnecessary,
6605                        data: diagnostic.data.clone(),
6606                    },
6607                });
6608                if let Some(infos) = &diagnostic.related_information {
6609                    for info in infos {
6610                        if info.location.uri == params.uri && !info.message.is_empty() {
6611                            let range = range_from_lsp(info.location.range);
6612                            diagnostics.push(DiagnosticEntry {
6613                                range,
6614                                diagnostic: Diagnostic {
6615                                    source: diagnostic.source.clone(),
6616                                    code: code.clone(),
6617                                    severity: DiagnosticSeverity::INFORMATION,
6618                                    message: info.message.trim().to_string(),
6619                                    group_id,
6620                                    is_primary: false,
6621                                    is_disk_based,
6622                                    is_unnecessary: false,
6623                                    data: diagnostic.data.clone(),
6624                                },
6625                            });
6626                        }
6627                    }
6628                }
6629            }
6630        }
6631
6632        for entry in &mut diagnostics {
6633            let diagnostic = &mut entry.diagnostic;
6634            if !diagnostic.is_primary {
6635                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
6636                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
6637                    source,
6638                    diagnostic.code.clone(),
6639                    entry.range.clone(),
6640                )) {
6641                    if let Some(severity) = severity {
6642                        diagnostic.severity = severity;
6643                    }
6644                    diagnostic.is_unnecessary = is_unnecessary;
6645                }
6646            }
6647        }
6648
6649        self.update_diagnostic_entries(
6650            language_server_id,
6651            abs_path,
6652            params.version,
6653            diagnostics,
6654            cx,
6655        )?;
6656        Ok(())
6657    }
6658
6659    fn insert_newly_running_language_server(
6660        &mut self,
6661        language: LanguageName,
6662        adapter: Arc<CachedLspAdapter>,
6663        language_server: Arc<LanguageServer>,
6664        server_id: LanguageServerId,
6665        key: (WorktreeId, LanguageServerName),
6666        cx: &mut ModelContext<Self>,
6667    ) -> Result<()> {
6668        // If the language server for this key doesn't match the server id, don't store the
6669        // server. Which will cause it to be dropped, killing the process
6670        if self
6671            .language_server_ids
6672            .get(&key)
6673            .map(|id| id != &server_id)
6674            .unwrap_or(false)
6675        {
6676            return Ok(());
6677        }
6678
6679        // Update language_servers collection with Running variant of LanguageServerState
6680        // indicating that the server is up and running and ready
6681        if let Some(local) = self.as_local_mut() {
6682            local.language_servers.insert(
6683                server_id,
6684                LanguageServerState::Running {
6685                    adapter: adapter.clone(),
6686                    language: language.clone(),
6687                    server: language_server.clone(),
6688                    simulate_disk_based_diagnostics_completion: None,
6689                },
6690            );
6691        }
6692
6693        self.language_server_statuses.insert(
6694            server_id,
6695            LanguageServerStatus {
6696                name: language_server.name().to_string(),
6697                pending_work: Default::default(),
6698                has_pending_diagnostic_updates: false,
6699                progress_tokens: Default::default(),
6700            },
6701        );
6702
6703        cx.emit(LspStoreEvent::LanguageServerAdded(server_id));
6704
6705        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
6706            downstream_client.send(proto::StartLanguageServer {
6707                project_id: *project_id,
6708                server: Some(proto::LanguageServer {
6709                    id: server_id.0 as u64,
6710                    name: language_server.name().to_string(),
6711                }),
6712            })?;
6713        }
6714
6715        // Tell the language server about every open buffer in the worktree that matches the language.
6716        self.buffer_store.update(cx, |buffer_store, cx| {
6717            for buffer_handle in buffer_store.buffers() {
6718                let buffer = buffer_handle.read(cx);
6719                let file = match File::from_dyn(buffer.file()) {
6720                    Some(file) => file,
6721                    None => continue,
6722                };
6723                let language = match buffer.language() {
6724                    Some(language) => language,
6725                    None => continue,
6726                };
6727
6728                if file.worktree.read(cx).id() != key.0
6729                    || !self
6730                        .languages
6731                        .lsp_adapters(&language.name())
6732                        .iter()
6733                        .any(|a| a.name == key.1)
6734                {
6735                    continue;
6736                }
6737
6738                let file = match file.as_local() {
6739                    Some(file) => file,
6740                    None => continue,
6741                };
6742
6743                let versions = self
6744                    .buffer_snapshots
6745                    .entry(buffer.remote_id())
6746                    .or_default()
6747                    .entry(server_id)
6748                    .or_insert_with(|| {
6749                        vec![LspBufferSnapshot {
6750                            version: 0,
6751                            snapshot: buffer.text_snapshot(),
6752                        }]
6753                    });
6754
6755                let snapshot = versions.last().unwrap();
6756                let version = snapshot.version;
6757                let initial_snapshot = &snapshot.snapshot;
6758                let uri = lsp::Url::from_file_path(file.abs_path(cx)).unwrap();
6759                language_server.notify::<lsp::notification::DidOpenTextDocument>(
6760                    lsp::DidOpenTextDocumentParams {
6761                        text_document: lsp::TextDocumentItem::new(
6762                            uri,
6763                            adapter.language_id(&language.name()),
6764                            version,
6765                            initial_snapshot.text(),
6766                        ),
6767                    },
6768                )?;
6769
6770                buffer_handle.update(cx, |buffer, cx| {
6771                    buffer.set_completion_triggers(
6772                        language_server
6773                            .capabilities()
6774                            .completion_provider
6775                            .as_ref()
6776                            .and_then(|provider| provider.trigger_characters.clone())
6777                            .unwrap_or_default(),
6778                        cx,
6779                    )
6780                });
6781            }
6782            anyhow::Ok(())
6783        })?;
6784
6785        cx.notify();
6786        Ok(())
6787    }
6788
6789    fn buffer_snapshot_for_lsp_version(
6790        &mut self,
6791        buffer: &Model<Buffer>,
6792        server_id: LanguageServerId,
6793        version: Option<i32>,
6794        cx: &AppContext,
6795    ) -> Result<TextBufferSnapshot> {
6796        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
6797
6798        if let Some(version) = version {
6799            let buffer_id = buffer.read(cx).remote_id();
6800            let snapshots = self
6801                .buffer_snapshots
6802                .get_mut(&buffer_id)
6803                .and_then(|m| m.get_mut(&server_id))
6804                .ok_or_else(|| {
6805                    anyhow!("no snapshots found for buffer {buffer_id} and server {server_id}")
6806                })?;
6807
6808            let found_snapshot = snapshots
6809                .binary_search_by_key(&version, |e| e.version)
6810                .map(|ix| snapshots[ix].snapshot.clone())
6811                .map_err(|_| {
6812                    anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
6813                })?;
6814
6815            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
6816            Ok(found_snapshot)
6817        } else {
6818            Ok((buffer.read(cx)).text_snapshot())
6819        }
6820    }
6821
6822    pub fn language_servers_running_disk_based_diagnostics(
6823        &self,
6824    ) -> impl Iterator<Item = LanguageServerId> + '_ {
6825        self.language_server_statuses
6826            .iter()
6827            .filter_map(|(id, status)| {
6828                if status.has_pending_diagnostic_updates {
6829                    Some(*id)
6830                } else {
6831                    None
6832                }
6833            })
6834    }
6835
6836    pub(crate) fn language_servers_for_buffer<'a>(
6837        &'a self,
6838        buffer: &'a Buffer,
6839        cx: &'a AppContext,
6840    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
6841        self.language_server_ids_for_buffer(buffer, cx)
6842            .into_iter()
6843            .filter_map(
6844                |server_id| match self.as_local()?.language_servers.get(&server_id)? {
6845                    LanguageServerState::Running {
6846                        adapter, server, ..
6847                    } => Some((adapter, server)),
6848                    _ => None,
6849                },
6850            )
6851    }
6852
6853    pub(crate) fn cancel_language_server_work_for_buffers(
6854        &mut self,
6855        buffers: impl IntoIterator<Item = Model<Buffer>>,
6856        cx: &mut ModelContext<Self>,
6857    ) {
6858        let servers = buffers
6859            .into_iter()
6860            .flat_map(|buffer| {
6861                self.language_server_ids_for_buffer(buffer.read(cx), cx)
6862                    .into_iter()
6863            })
6864            .collect::<HashSet<_>>();
6865
6866        for server_id in servers {
6867            self.cancel_language_server_work(server_id, None, cx);
6868        }
6869    }
6870
6871    pub fn language_servers(
6872        &self,
6873    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName, WorktreeId)> {
6874        self.language_server_ids
6875            .iter()
6876            .map(|((worktree_id, server_name), server_id)| {
6877                (*server_id, server_name.clone(), *worktree_id)
6878            })
6879    }
6880
6881    pub fn register_supplementary_language_server(
6882        &mut self,
6883        id: LanguageServerId,
6884        name: LanguageServerName,
6885        server: Arc<LanguageServer>,
6886        cx: &mut ModelContext<Self>,
6887    ) {
6888        if let Some(local) = self.as_local_mut() {
6889            local
6890                .supplementary_language_servers
6891                .insert(id, (name, server));
6892            cx.emit(LspStoreEvent::LanguageServerAdded(id));
6893        }
6894    }
6895
6896    pub fn unregister_supplementary_language_server(
6897        &mut self,
6898        id: LanguageServerId,
6899        cx: &mut ModelContext<Self>,
6900    ) {
6901        if let Some(local) = self.as_local_mut() {
6902            local.supplementary_language_servers.remove(&id);
6903            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
6904        }
6905    }
6906
6907    pub fn supplementary_language_servers(
6908        &self,
6909    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
6910        self.as_local().into_iter().flat_map(|local| {
6911            local
6912                .supplementary_language_servers
6913                .iter()
6914                .map(|(id, (name, _))| (*id, name.clone()))
6915        })
6916    }
6917
6918    pub fn language_server_adapter_for_id(
6919        &self,
6920        id: LanguageServerId,
6921    ) -> Option<Arc<CachedLspAdapter>> {
6922        self.as_local()
6923            .and_then(|local| local.language_servers.get(&id))
6924            .and_then(|language_server_state| match language_server_state {
6925                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
6926                _ => None,
6927            })
6928    }
6929
6930    pub(super) fn update_local_worktree_language_servers(
6931        &mut self,
6932        worktree_handle: &Model<Worktree>,
6933        changes: &[(Arc<Path>, ProjectEntryId, PathChange)],
6934        cx: &mut ModelContext<Self>,
6935    ) {
6936        if changes.is_empty() {
6937            return;
6938        }
6939
6940        let Some(local) = self.as_local() else { return };
6941
6942        local.prettier_store.update(cx, |prettier_store, cx| {
6943            prettier_store.update_prettier_settings(&worktree_handle, changes, cx)
6944        });
6945
6946        let worktree_id = worktree_handle.read(cx).id();
6947        let mut language_server_ids = self
6948            .language_server_ids
6949            .iter()
6950            .filter_map(|((server_worktree_id, _), server_id)| {
6951                (*server_worktree_id == worktree_id).then_some(*server_id)
6952            })
6953            .collect::<Vec<_>>();
6954        language_server_ids.sort();
6955        language_server_ids.dedup();
6956
6957        let abs_path = worktree_handle.read(cx).abs_path();
6958        for server_id in &language_server_ids {
6959            if let Some(LanguageServerState::Running { server, .. }) =
6960                local.language_servers.get(server_id)
6961            {
6962                if let Some(watched_paths) = local
6963                    .language_server_watched_paths
6964                    .get(server_id)
6965                    .and_then(|paths| paths.read(cx).worktree_paths.get(&worktree_id))
6966                {
6967                    let params = lsp::DidChangeWatchedFilesParams {
6968                        changes: changes
6969                            .iter()
6970                            .filter_map(|(path, _, change)| {
6971                                if !watched_paths.is_match(path) {
6972                                    return None;
6973                                }
6974                                let typ = match change {
6975                                    PathChange::Loaded => return None,
6976                                    PathChange::Added => lsp::FileChangeType::CREATED,
6977                                    PathChange::Removed => lsp::FileChangeType::DELETED,
6978                                    PathChange::Updated => lsp::FileChangeType::CHANGED,
6979                                    PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
6980                                };
6981                                Some(lsp::FileEvent {
6982                                    uri: lsp::Url::from_file_path(abs_path.join(path)).unwrap(),
6983                                    typ,
6984                                })
6985                            })
6986                            .collect(),
6987                    };
6988                    if !params.changes.is_empty() {
6989                        server
6990                            .notify::<lsp::notification::DidChangeWatchedFiles>(params)
6991                            .log_err();
6992                    }
6993                }
6994            }
6995        }
6996    }
6997
6998    pub(crate) fn cancel_language_server_work(
6999        &mut self,
7000        server_id: LanguageServerId,
7001        token_to_cancel: Option<String>,
7002        _cx: &mut ModelContext<Self>,
7003    ) {
7004        let Some(local) = self.as_local() else {
7005            return;
7006        };
7007        let status = self.language_server_statuses.get(&server_id);
7008        let server = local.language_servers.get(&server_id);
7009        if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status) {
7010            for (token, progress) in &status.pending_work {
7011                if let Some(token_to_cancel) = token_to_cancel.as_ref() {
7012                    if token != token_to_cancel {
7013                        continue;
7014                    }
7015                }
7016                if progress.is_cancellable {
7017                    server
7018                        .notify::<lsp::notification::WorkDoneProgressCancel>(
7019                            WorkDoneProgressCancelParams {
7020                                token: lsp::NumberOrString::String(token.clone()),
7021                            },
7022                        )
7023                        .ok();
7024                }
7025
7026                if progress.is_cancellable {
7027                    server
7028                        .notify::<lsp::notification::WorkDoneProgressCancel>(
7029                            WorkDoneProgressCancelParams {
7030                                token: lsp::NumberOrString::String(token.clone()),
7031                            },
7032                        )
7033                        .ok();
7034                }
7035            }
7036        }
7037    }
7038
7039    pub fn wait_for_remote_buffer(
7040        &mut self,
7041        id: BufferId,
7042        cx: &mut ModelContext<Self>,
7043    ) -> Task<Result<Model<Buffer>>> {
7044        self.buffer_store.update(cx, |buffer_store, cx| {
7045            buffer_store.wait_for_remote_buffer(id, cx)
7046        })
7047    }
7048
7049    pub(crate) fn language_server_ids_for_buffer(
7050        &self,
7051        buffer: &Buffer,
7052        cx: &AppContext,
7053    ) -> Vec<LanguageServerId> {
7054        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
7055            let worktree_id = file.worktree_id(cx);
7056            self.languages
7057                .lsp_adapters(&language.name())
7058                .iter()
7059                .flat_map(|adapter| {
7060                    let key = (worktree_id, adapter.name.clone());
7061                    self.language_server_ids.get(&key).copied()
7062                })
7063                .collect()
7064        } else {
7065            Vec::new()
7066        }
7067    }
7068
7069    pub async fn deserialize_text_edits(
7070        this: Model<Self>,
7071        buffer_to_edit: Model<Buffer>,
7072        edits: Vec<lsp::TextEdit>,
7073        push_to_history: bool,
7074        _: Arc<CachedLspAdapter>,
7075        language_server: Arc<LanguageServer>,
7076        cx: &mut AsyncAppContext,
7077    ) -> Result<Option<Transaction>> {
7078        let edits = this
7079            .update(cx, |this, cx| {
7080                this.edits_from_lsp(
7081                    &buffer_to_edit,
7082                    edits,
7083                    language_server.server_id(),
7084                    None,
7085                    cx,
7086                )
7087            })?
7088            .await?;
7089
7090        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
7091            buffer.finalize_last_transaction();
7092            buffer.start_transaction();
7093            for (range, text) in edits {
7094                buffer.edit([(range, text)], None, cx);
7095            }
7096
7097            if buffer.end_transaction(cx).is_some() {
7098                let transaction = buffer.finalize_last_transaction().unwrap().clone();
7099                if !push_to_history {
7100                    buffer.forget_transaction(transaction.id);
7101                }
7102                Some(transaction)
7103            } else {
7104                None
7105            }
7106        })?;
7107
7108        Ok(transaction)
7109    }
7110
7111    pub async fn deserialize_workspace_edit(
7112        this: Model<Self>,
7113        edit: lsp::WorkspaceEdit,
7114        push_to_history: bool,
7115        lsp_adapter: Arc<CachedLspAdapter>,
7116        language_server: Arc<LanguageServer>,
7117        cx: &mut AsyncAppContext,
7118    ) -> Result<ProjectTransaction> {
7119        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
7120
7121        let mut operations = Vec::new();
7122        if let Some(document_changes) = edit.document_changes {
7123            match document_changes {
7124                lsp::DocumentChanges::Edits(edits) => {
7125                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
7126                }
7127                lsp::DocumentChanges::Operations(ops) => operations = ops,
7128            }
7129        } else if let Some(changes) = edit.changes {
7130            operations.extend(changes.into_iter().map(|(uri, edits)| {
7131                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
7132                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
7133                        uri,
7134                        version: None,
7135                    },
7136                    edits: edits.into_iter().map(Edit::Plain).collect(),
7137                })
7138            }));
7139        }
7140
7141        let mut project_transaction = ProjectTransaction::default();
7142        for operation in operations {
7143            match operation {
7144                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
7145                    let abs_path = op
7146                        .uri
7147                        .to_file_path()
7148                        .map_err(|_| anyhow!("can't convert URI to path"))?;
7149
7150                    if let Some(parent_path) = abs_path.parent() {
7151                        fs.create_dir(parent_path).await?;
7152                    }
7153                    if abs_path.ends_with("/") {
7154                        fs.create_dir(&abs_path).await?;
7155                    } else {
7156                        fs.create_file(
7157                            &abs_path,
7158                            op.options
7159                                .map(|options| fs::CreateOptions {
7160                                    overwrite: options.overwrite.unwrap_or(false),
7161                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
7162                                })
7163                                .unwrap_or_default(),
7164                        )
7165                        .await?;
7166                    }
7167                }
7168
7169                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
7170                    let source_abs_path = op
7171                        .old_uri
7172                        .to_file_path()
7173                        .map_err(|_| anyhow!("can't convert URI to path"))?;
7174                    let target_abs_path = op
7175                        .new_uri
7176                        .to_file_path()
7177                        .map_err(|_| anyhow!("can't convert URI to path"))?;
7178                    fs.rename(
7179                        &source_abs_path,
7180                        &target_abs_path,
7181                        op.options
7182                            .map(|options| fs::RenameOptions {
7183                                overwrite: options.overwrite.unwrap_or(false),
7184                                ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
7185                            })
7186                            .unwrap_or_default(),
7187                    )
7188                    .await?;
7189                }
7190
7191                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
7192                    let abs_path = op
7193                        .uri
7194                        .to_file_path()
7195                        .map_err(|_| anyhow!("can't convert URI to path"))?;
7196                    let options = op
7197                        .options
7198                        .map(|options| fs::RemoveOptions {
7199                            recursive: options.recursive.unwrap_or(false),
7200                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
7201                        })
7202                        .unwrap_or_default();
7203                    if abs_path.ends_with("/") {
7204                        fs.remove_dir(&abs_path, options).await?;
7205                    } else {
7206                        fs.remove_file(&abs_path, options).await?;
7207                    }
7208                }
7209
7210                lsp::DocumentChangeOperation::Edit(op) => {
7211                    let buffer_to_edit = this
7212                        .update(cx, |this, cx| {
7213                            this.open_local_buffer_via_lsp(
7214                                op.text_document.uri.clone(),
7215                                language_server.server_id(),
7216                                lsp_adapter.name.clone(),
7217                                cx,
7218                            )
7219                        })?
7220                        .await?;
7221
7222                    let edits = this
7223                        .update(cx, |this, cx| {
7224                            let path = buffer_to_edit.read(cx).project_path(cx);
7225                            let active_entry = this.active_entry;
7226                            let is_active_entry = path.clone().map_or(false, |project_path| {
7227                                this.worktree_store
7228                                    .read(cx)
7229                                    .entry_for_path(&project_path, cx)
7230                                    .map_or(false, |entry| Some(entry.id) == active_entry)
7231                            });
7232
7233                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
7234                            for edit in op.edits {
7235                                match edit {
7236                                    Edit::Plain(edit) => edits.push(edit),
7237                                    Edit::Annotated(edit) => edits.push(edit.text_edit),
7238                                    Edit::Snippet(edit) => {
7239                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
7240                                        else {
7241                                            continue;
7242                                        };
7243
7244                                        if is_active_entry {
7245                                            snippet_edits.push((edit.range, snippet));
7246                                        } else {
7247                                            // Since this buffer is not focused, apply a normal edit.
7248                                            edits.push(TextEdit {
7249                                                range: edit.range,
7250                                                new_text: snippet.text,
7251                                            });
7252                                        }
7253                                    }
7254                                }
7255                            }
7256                            if !snippet_edits.is_empty() {
7257                                let buffer_id = buffer_to_edit.read(cx).remote_id();
7258                                let version = if let Some(buffer_version) = op.text_document.version
7259                                {
7260                                    this.buffer_snapshot_for_lsp_version(
7261                                        &buffer_to_edit,
7262                                        language_server.server_id(),
7263                                        Some(buffer_version),
7264                                        cx,
7265                                    )
7266                                    .ok()
7267                                    .map(|snapshot| snapshot.version)
7268                                } else {
7269                                    Some(buffer_to_edit.read(cx).saved_version().clone())
7270                                };
7271
7272                                let most_recent_edit = version.and_then(|version| {
7273                                    version.iter().max_by_key(|timestamp| timestamp.value)
7274                                });
7275                                // Check if the edit that triggered that edit has been made by this participant.
7276
7277                                if let Some(most_recent_edit) = most_recent_edit {
7278                                    cx.emit(LspStoreEvent::SnippetEdit {
7279                                        buffer_id,
7280                                        edits: snippet_edits,
7281                                        most_recent_edit,
7282                                    });
7283                                }
7284                            }
7285
7286                            this.edits_from_lsp(
7287                                &buffer_to_edit,
7288                                edits,
7289                                language_server.server_id(),
7290                                op.text_document.version,
7291                                cx,
7292                            )
7293                        })?
7294                        .await?;
7295
7296                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
7297                        buffer.finalize_last_transaction();
7298                        buffer.start_transaction();
7299                        for (range, text) in edits {
7300                            buffer.edit([(range, text)], None, cx);
7301                        }
7302                        let transaction = if buffer.end_transaction(cx).is_some() {
7303                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
7304                            if !push_to_history {
7305                                buffer.forget_transaction(transaction.id);
7306                            }
7307                            Some(transaction)
7308                        } else {
7309                            None
7310                        };
7311
7312                        transaction
7313                    })?;
7314                    if let Some(transaction) = transaction {
7315                        project_transaction.0.insert(buffer_to_edit, transaction);
7316                    }
7317                }
7318            }
7319        }
7320
7321        Ok(project_transaction)
7322    }
7323
7324    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
7325        proto::Symbol {
7326            language_server_name: symbol.language_server_name.0.to_string(),
7327            source_worktree_id: symbol.source_worktree_id.to_proto(),
7328            worktree_id: symbol.path.worktree_id.to_proto(),
7329            path: symbol.path.path.to_string_lossy().to_string(),
7330            name: symbol.name.clone(),
7331            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
7332            start: Some(proto::PointUtf16 {
7333                row: symbol.range.start.0.row,
7334                column: symbol.range.start.0.column,
7335            }),
7336            end: Some(proto::PointUtf16 {
7337                row: symbol.range.end.0.row,
7338                column: symbol.range.end.0.column,
7339            }),
7340            signature: symbol.signature.to_vec(),
7341        }
7342    }
7343
7344    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
7345        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
7346        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
7347        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
7348        let path = ProjectPath {
7349            worktree_id,
7350            path: PathBuf::from(serialized_symbol.path).into(),
7351        };
7352
7353        let start = serialized_symbol
7354            .start
7355            .ok_or_else(|| anyhow!("invalid start"))?;
7356        let end = serialized_symbol
7357            .end
7358            .ok_or_else(|| anyhow!("invalid end"))?;
7359        Ok(CoreSymbol {
7360            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
7361            source_worktree_id,
7362            path,
7363            name: serialized_symbol.name,
7364            range: Unclipped(PointUtf16::new(start.row, start.column))
7365                ..Unclipped(PointUtf16::new(end.row, end.column)),
7366            kind,
7367            signature: serialized_symbol
7368                .signature
7369                .try_into()
7370                .map_err(|_| anyhow!("invalid signature"))?,
7371        })
7372    }
7373
7374    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
7375        proto::Completion {
7376            old_start: Some(serialize_anchor(&completion.old_range.start)),
7377            old_end: Some(serialize_anchor(&completion.old_range.end)),
7378            new_text: completion.new_text.clone(),
7379            server_id: completion.server_id.0 as u64,
7380            lsp_completion: serde_json::to_vec(&completion.lsp_completion).unwrap(),
7381        }
7382    }
7383
7384    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
7385        let old_start = completion
7386            .old_start
7387            .and_then(deserialize_anchor)
7388            .ok_or_else(|| anyhow!("invalid old start"))?;
7389        let old_end = completion
7390            .old_end
7391            .and_then(deserialize_anchor)
7392            .ok_or_else(|| anyhow!("invalid old end"))?;
7393        let lsp_completion = serde_json::from_slice(&completion.lsp_completion)?;
7394
7395        Ok(CoreCompletion {
7396            old_range: old_start..old_end,
7397            new_text: completion.new_text,
7398            server_id: LanguageServerId(completion.server_id as usize),
7399            lsp_completion,
7400        })
7401    }
7402
7403    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
7404        proto::CodeAction {
7405            server_id: action.server_id.0 as u64,
7406            start: Some(serialize_anchor(&action.range.start)),
7407            end: Some(serialize_anchor(&action.range.end)),
7408            lsp_action: serde_json::to_vec(&action.lsp_action).unwrap(),
7409        }
7410    }
7411
7412    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
7413        let start = action
7414            .start
7415            .and_then(deserialize_anchor)
7416            .ok_or_else(|| anyhow!("invalid start"))?;
7417        let end = action
7418            .end
7419            .and_then(deserialize_anchor)
7420            .ok_or_else(|| anyhow!("invalid end"))?;
7421        let lsp_action = serde_json::from_slice(&action.lsp_action)?;
7422        Ok(CodeAction {
7423            server_id: LanguageServerId(action.server_id as usize),
7424            range: start..end,
7425            lsp_action,
7426        })
7427    }
7428}
7429
7430impl EventEmitter<LspStoreEvent> for LspStore {}
7431
7432fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
7433    hover
7434        .contents
7435        .retain(|hover_block| !hover_block.text.trim().is_empty());
7436    if hover.contents.is_empty() {
7437        None
7438    } else {
7439        Some(hover)
7440    }
7441}
7442
7443async fn populate_labels_for_completions(
7444    mut new_completions: Vec<CoreCompletion>,
7445    language_registry: &Arc<LanguageRegistry>,
7446    language: Option<Arc<Language>>,
7447    lsp_adapter: Option<Arc<CachedLspAdapter>>,
7448    completions: &mut Vec<Completion>,
7449) {
7450    let lsp_completions = new_completions
7451        .iter_mut()
7452        .map(|completion| mem::take(&mut completion.lsp_completion))
7453        .collect::<Vec<_>>();
7454
7455    let labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
7456        lsp_adapter
7457            .labels_for_completions(&lsp_completions, language)
7458            .await
7459            .log_err()
7460            .unwrap_or_default()
7461    } else {
7462        Vec::new()
7463    };
7464
7465    for ((completion, lsp_completion), label) in new_completions
7466        .into_iter()
7467        .zip(lsp_completions)
7468        .zip(labels.into_iter().chain(iter::repeat(None)))
7469    {
7470        let documentation = if let Some(docs) = &lsp_completion.documentation {
7471            Some(prepare_completion_documentation(docs, language_registry, language.clone()).await)
7472        } else {
7473            None
7474        };
7475
7476        completions.push(Completion {
7477            old_range: completion.old_range,
7478            new_text: completion.new_text,
7479            label: label.unwrap_or_else(|| {
7480                CodeLabel::plain(
7481                    lsp_completion.label.clone(),
7482                    lsp_completion.filter_text.as_deref(),
7483                )
7484            }),
7485            server_id: completion.server_id,
7486            documentation,
7487            lsp_completion,
7488            confirm: None,
7489        })
7490    }
7491}
7492
7493#[derive(Debug)]
7494pub enum LanguageServerToQuery {
7495    Primary,
7496    Other(LanguageServerId),
7497}
7498
7499#[derive(Default)]
7500struct LanguageServerWatchedPaths {
7501    worktree_paths: HashMap<WorktreeId, GlobSet>,
7502    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
7503}
7504
7505#[derive(Default)]
7506struct LanguageServerWatchedPathsBuilder {
7507    worktree_paths: HashMap<WorktreeId, GlobSet>,
7508    abs_paths: HashMap<Arc<Path>, GlobSet>,
7509}
7510
7511impl LanguageServerWatchedPathsBuilder {
7512    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
7513        self.worktree_paths.insert(worktree_id, glob_set);
7514    }
7515    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
7516        self.abs_paths.insert(path, glob_set);
7517    }
7518    fn build(
7519        self,
7520        fs: Arc<dyn Fs>,
7521        language_server_id: LanguageServerId,
7522        cx: &mut ModelContext<LspStore>,
7523    ) -> Model<LanguageServerWatchedPaths> {
7524        let project = cx.weak_model();
7525
7526        cx.new_model(|cx| {
7527            let this_id = cx.entity_id();
7528            const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
7529            let abs_paths = self
7530                .abs_paths
7531                .into_iter()
7532                .map(|(abs_path, globset)| {
7533                    let task = cx.spawn({
7534                        let abs_path = abs_path.clone();
7535                        let fs = fs.clone();
7536
7537                        let lsp_store = project.clone();
7538                        |_, mut cx| async move {
7539                            maybe!(async move {
7540                                let mut push_updates =
7541                                    fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
7542                                while let Some(update) = push_updates.0.next().await {
7543                                    let action = lsp_store
7544                                        .update(&mut cx, |this, cx| {
7545                                            let Some(local) = this.as_local() else {
7546                                                return ControlFlow::Break(());
7547                                            };
7548                                            let Some(watcher) = local
7549                                                .language_server_watched_paths
7550                                                .get(&language_server_id)
7551                                            else {
7552                                                return ControlFlow::Break(());
7553                                            };
7554                                            if watcher.entity_id() != this_id {
7555                                                // This watcher is no longer registered on the project, which means that we should
7556                                                // cease operations.
7557                                                return ControlFlow::Break(());
7558                                            }
7559                                            let (globs, _) = watcher
7560                                                .read(cx)
7561                                                .abs_paths
7562                                                .get(&abs_path)
7563                                                .expect(
7564                                                "Watched abs path is not registered with a watcher",
7565                                            );
7566                                            let matching_entries = update
7567                                                .into_iter()
7568                                                .filter(|event| globs.is_match(&event.path))
7569                                                .collect::<Vec<_>>();
7570                                            this.lsp_notify_abs_paths_changed(
7571                                                language_server_id,
7572                                                matching_entries,
7573                                            );
7574                                            ControlFlow::Continue(())
7575                                        })
7576                                        .ok()?;
7577
7578                                    if action.is_break() {
7579                                        break;
7580                                    }
7581                                }
7582                                Some(())
7583                            })
7584                            .await;
7585                        }
7586                    });
7587                    (abs_path, (globset, task))
7588                })
7589                .collect();
7590            LanguageServerWatchedPaths {
7591                worktree_paths: self.worktree_paths,
7592                abs_paths,
7593            }
7594        })
7595    }
7596}
7597
7598struct LspBufferSnapshot {
7599    version: i32,
7600    snapshot: TextBufferSnapshot,
7601}
7602
7603/// A prompt requested by LSP server.
7604#[derive(Clone, Debug)]
7605pub struct LanguageServerPromptRequest {
7606    pub level: PromptLevel,
7607    pub message: String,
7608    pub actions: Vec<MessageActionItem>,
7609    pub lsp_name: String,
7610    pub(crate) response_channel: Sender<MessageActionItem>,
7611}
7612
7613impl LanguageServerPromptRequest {
7614    pub async fn respond(self, index: usize) -> Option<()> {
7615        if let Some(response) = self.actions.into_iter().nth(index) {
7616            self.response_channel.send(response).await.ok()
7617        } else {
7618            None
7619        }
7620    }
7621}
7622impl PartialEq for LanguageServerPromptRequest {
7623    fn eq(&self, other: &Self) -> bool {
7624        self.message == other.message && self.actions == other.actions
7625    }
7626}
7627
7628#[derive(Clone, Debug, PartialEq)]
7629pub enum LanguageServerLogType {
7630    Log(MessageType),
7631    Trace(Option<String>),
7632}
7633
7634pub enum LanguageServerState {
7635    Starting(Task<Option<Arc<LanguageServer>>>),
7636
7637    Running {
7638        language: LanguageName,
7639        adapter: Arc<CachedLspAdapter>,
7640        server: Arc<LanguageServer>,
7641        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
7642    },
7643}
7644
7645impl std::fmt::Debug for LanguageServerState {
7646    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7647        match self {
7648            LanguageServerState::Starting(_) => {
7649                f.debug_struct("LanguageServerState::Starting").finish()
7650            }
7651            LanguageServerState::Running { language, .. } => f
7652                .debug_struct("LanguageServerState::Running")
7653                .field("language", &language)
7654                .finish(),
7655        }
7656    }
7657}
7658
7659#[derive(Clone, Debug, Serialize)]
7660pub struct LanguageServerProgress {
7661    pub is_disk_based_diagnostics_progress: bool,
7662    pub is_cancellable: bool,
7663    pub title: Option<String>,
7664    pub message: Option<String>,
7665    pub percentage: Option<usize>,
7666    #[serde(skip_serializing)]
7667    pub last_update_at: Instant,
7668}
7669
7670#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
7671pub struct DiagnosticSummary {
7672    pub error_count: usize,
7673    pub warning_count: usize,
7674}
7675
7676impl DiagnosticSummary {
7677    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
7678        let mut this = Self {
7679            error_count: 0,
7680            warning_count: 0,
7681        };
7682
7683        for entry in diagnostics {
7684            if entry.diagnostic.is_primary {
7685                match entry.diagnostic.severity {
7686                    DiagnosticSeverity::ERROR => this.error_count += 1,
7687                    DiagnosticSeverity::WARNING => this.warning_count += 1,
7688                    _ => {}
7689                }
7690            }
7691        }
7692
7693        this
7694    }
7695
7696    pub fn is_empty(&self) -> bool {
7697        self.error_count == 0 && self.warning_count == 0
7698    }
7699
7700    pub fn to_proto(
7701        &self,
7702        language_server_id: LanguageServerId,
7703        path: &Path,
7704    ) -> proto::DiagnosticSummary {
7705        proto::DiagnosticSummary {
7706            path: path.to_string_lossy().to_string(),
7707            language_server_id: language_server_id.0 as u64,
7708            error_count: self.error_count as u32,
7709            warning_count: self.warning_count as u32,
7710        }
7711    }
7712}
7713
7714fn glob_literal_prefix(glob: &str) -> &str {
7715    let is_absolute = glob.starts_with(path::MAIN_SEPARATOR);
7716
7717    let mut literal_end = is_absolute as usize;
7718    for (i, part) in glob.split(path::MAIN_SEPARATOR).enumerate() {
7719        if part.contains(['*', '?', '{', '}']) {
7720            break;
7721        } else {
7722            if i > 0 {
7723                // Account for separator prior to this part
7724                literal_end += path::MAIN_SEPARATOR.len_utf8();
7725            }
7726            literal_end += part.len();
7727        }
7728    }
7729    let literal_end = literal_end.min(glob.len());
7730    &glob[..literal_end]
7731}
7732
7733pub struct SshLspAdapter {
7734    name: LanguageServerName,
7735    binary: LanguageServerBinary,
7736    initialization_options: Option<String>,
7737    code_action_kinds: Option<Vec<CodeActionKind>>,
7738}
7739
7740impl SshLspAdapter {
7741    pub fn new(
7742        name: LanguageServerName,
7743        binary: LanguageServerBinary,
7744        initialization_options: Option<String>,
7745        code_action_kinds: Option<String>,
7746    ) -> Self {
7747        Self {
7748            name,
7749            binary,
7750            initialization_options,
7751            code_action_kinds: code_action_kinds
7752                .as_ref()
7753                .and_then(|c| serde_json::from_str(c).ok()),
7754        }
7755    }
7756}
7757
7758#[async_trait(?Send)]
7759impl LspAdapter for SshLspAdapter {
7760    fn name(&self) -> LanguageServerName {
7761        self.name.clone()
7762    }
7763
7764    async fn initialization_options(
7765        self: Arc<Self>,
7766        _: &Arc<dyn LspAdapterDelegate>,
7767    ) -> Result<Option<serde_json::Value>> {
7768        let Some(options) = &self.initialization_options else {
7769            return Ok(None);
7770        };
7771        let result = serde_json::from_str(options)?;
7772        Ok(result)
7773    }
7774
7775    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
7776        self.code_action_kinds.clone()
7777    }
7778
7779    async fn check_if_user_installed(
7780        &self,
7781        _: &dyn LspAdapterDelegate,
7782        _: &AsyncAppContext,
7783    ) -> Option<LanguageServerBinary> {
7784        Some(self.binary.clone())
7785    }
7786
7787    async fn cached_server_binary(
7788        &self,
7789        _: PathBuf,
7790        _: &dyn LspAdapterDelegate,
7791    ) -> Option<LanguageServerBinary> {
7792        None
7793    }
7794
7795    async fn fetch_latest_server_version(
7796        &self,
7797        _: &dyn LspAdapterDelegate,
7798    ) -> Result<Box<dyn 'static + Send + Any>> {
7799        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
7800    }
7801
7802    async fn fetch_server_binary(
7803        &self,
7804        _: Box<dyn 'static + Send + Any>,
7805        _: PathBuf,
7806        _: &dyn LspAdapterDelegate,
7807    ) -> Result<LanguageServerBinary> {
7808        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
7809    }
7810
7811    async fn installation_test_binary(&self, _: PathBuf) -> Option<LanguageServerBinary> {
7812        None
7813    }
7814}
7815pub fn language_server_settings<'a, 'b: 'a>(
7816    delegate: &'a dyn LspAdapterDelegate,
7817    language: &LanguageServerName,
7818    cx: &'b AppContext,
7819) -> Option<&'a LspSettings> {
7820    ProjectSettings::get(
7821        Some(SettingsLocation {
7822            worktree_id: delegate.worktree_id(),
7823            path: delegate.worktree_root_path(),
7824        }),
7825        cx,
7826    )
7827    .lsp
7828    .get(language)
7829}
7830
7831pub struct LocalLspAdapterDelegate {
7832    lsp_store: WeakModel<LspStore>,
7833    worktree: worktree::Snapshot,
7834    fs: Arc<dyn Fs>,
7835    http_client: Arc<dyn HttpClient>,
7836    language_registry: Arc<LanguageRegistry>,
7837    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
7838}
7839
7840impl LocalLspAdapterDelegate {
7841    fn for_local(
7842        lsp_store: &LspStore,
7843        worktree: &Model<Worktree>,
7844        cx: &mut ModelContext<LspStore>,
7845    ) -> Arc<Self> {
7846        let local = lsp_store
7847            .as_local()
7848            .expect("LocalLspAdapterDelegate cannot be constructed on a remote");
7849
7850        let http_client = local
7851            .http_client
7852            .clone()
7853            .unwrap_or_else(|| Arc::new(BlockedHttpClient));
7854
7855        Self::new(lsp_store, worktree, http_client, local.fs.clone(), cx)
7856    }
7857
7858    // fn for_ssh(
7859    //     lsp_store: &LspStore,
7860    //     worktree: &Model<Worktree>,
7861    //     upstream_client: AnyProtoClient,
7862    //     cx: &mut ModelContext<LspStore>,
7863    // ) -> Arc<Self> {
7864    //     Self::new(
7865    //         lsp_store,
7866    //         worktree,
7867    //         Arc::new(BlockedHttpClient),
7868    //         None,
7869    //         Some(upstream_client),
7870    //         cx,
7871    //     )
7872    // }
7873
7874    pub fn new(
7875        lsp_store: &LspStore,
7876        worktree: &Model<Worktree>,
7877        http_client: Arc<dyn HttpClient>,
7878        fs: Arc<dyn Fs>,
7879        cx: &mut ModelContext<LspStore>,
7880    ) -> Arc<Self> {
7881        let worktree_id = worktree.read(cx).id();
7882        let worktree_abs_path = worktree.read(cx).abs_path();
7883        let load_shell_env_task = if let Some(environment) =
7884            &lsp_store.as_local().map(|local| local.environment.clone())
7885        {
7886            environment.update(cx, |env, cx| {
7887                env.get_environment(Some(worktree_id), Some(worktree_abs_path), cx)
7888            })
7889        } else {
7890            Task::ready(None).shared()
7891        };
7892
7893        Arc::new(Self {
7894            lsp_store: cx.weak_model(),
7895            worktree: worktree.read(cx).snapshot(),
7896            fs,
7897            http_client,
7898            language_registry: lsp_store.languages.clone(),
7899            load_shell_env_task,
7900        })
7901    }
7902}
7903
7904#[async_trait]
7905impl LspAdapterDelegate for LocalLspAdapterDelegate {
7906    fn show_notification(&self, message: &str, cx: &mut AppContext) {
7907        self.lsp_store
7908            .update(cx, |_, cx| {
7909                cx.emit(LspStoreEvent::Notification(message.to_owned()))
7910            })
7911            .ok();
7912    }
7913
7914    fn http_client(&self) -> Arc<dyn HttpClient> {
7915        self.http_client.clone()
7916    }
7917
7918    fn worktree_id(&self) -> WorktreeId {
7919        self.worktree.id()
7920    }
7921
7922    fn worktree_root_path(&self) -> &Path {
7923        self.worktree.abs_path().as_ref()
7924    }
7925
7926    async fn shell_env(&self) -> HashMap<String, String> {
7927        let task = self.load_shell_env_task.clone();
7928        task.await.unwrap_or_default()
7929    }
7930
7931    #[cfg(not(target_os = "windows"))]
7932    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
7933        let worktree_abs_path = self.worktree.abs_path();
7934        let shell_path = self.shell_env().await.get("PATH").cloned();
7935        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
7936    }
7937
7938    #[cfg(target_os = "windows")]
7939    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
7940        // todo(windows) Getting the shell env variables in a current directory on Windows is more complicated than other platforms
7941        //               there isn't a 'default shell' necessarily. The closest would be the default profile on the windows terminal
7942        //               SEE: https://learn.microsoft.com/en-us/windows/terminal/customize-settings/startup
7943        which::which(command).ok()
7944    }
7945
7946    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
7947        let working_dir = self.worktree_root_path();
7948        let output = smol::process::Command::new(&command.path)
7949            .args(command.arguments)
7950            .envs(command.env.clone().unwrap_or_default())
7951            .current_dir(working_dir)
7952            .output()
7953            .await?;
7954
7955        if output.status.success() {
7956            return Ok(());
7957        }
7958        Err(anyhow!(
7959            "{}, stdout: {:?}, stderr: {:?}",
7960            output.status,
7961            String::from_utf8_lossy(&output.stdout),
7962            String::from_utf8_lossy(&output.stderr)
7963        ))
7964    }
7965
7966    fn update_status(
7967        &self,
7968        server_name: LanguageServerName,
7969        status: language::LanguageServerBinaryStatus,
7970    ) {
7971        self.language_registry
7972            .update_lsp_status(server_name, status);
7973    }
7974
7975    async fn read_text_file(&self, path: PathBuf) -> Result<String> {
7976        if self.worktree.entry_for_path(&path).is_none() {
7977            return Err(anyhow!("no such path {path:?}"));
7978        };
7979        self.fs.load(&path).await
7980    }
7981}
7982
7983struct SshLspAdapterDelegate {
7984    lsp_store: WeakModel<LspStore>,
7985    worktree: worktree::Snapshot,
7986    upstream_client: AnyProtoClient,
7987    language_registry: Arc<LanguageRegistry>,
7988}
7989
7990#[async_trait]
7991impl LspAdapterDelegate for SshLspAdapterDelegate {
7992    fn show_notification(&self, message: &str, cx: &mut AppContext) {
7993        self.lsp_store
7994            .update(cx, |_, cx| {
7995                cx.emit(LspStoreEvent::Notification(message.to_owned()))
7996            })
7997            .ok();
7998    }
7999
8000    fn http_client(&self) -> Arc<dyn HttpClient> {
8001        Arc::new(BlockedHttpClient)
8002    }
8003
8004    fn worktree_id(&self) -> WorktreeId {
8005        self.worktree.id()
8006    }
8007
8008    fn worktree_root_path(&self) -> &Path {
8009        self.worktree.abs_path().as_ref()
8010    }
8011
8012    async fn shell_env(&self) -> HashMap<String, String> {
8013        use rpc::proto::SSH_PROJECT_ID;
8014
8015        self.upstream_client
8016            .request(proto::ShellEnv {
8017                project_id: SSH_PROJECT_ID,
8018                worktree_id: self.worktree_id().to_proto(),
8019            })
8020            .await
8021            .map(|response| response.env.into_iter().collect())
8022            .unwrap_or_default()
8023    }
8024
8025    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
8026        use rpc::proto::SSH_PROJECT_ID;
8027
8028        self.upstream_client
8029            .request(proto::WhichCommand {
8030                project_id: SSH_PROJECT_ID,
8031                worktree_id: self.worktree_id().to_proto(),
8032                command: command.to_string_lossy().to_string(),
8033            })
8034            .await
8035            .log_err()
8036            .and_then(|response| response.path)
8037            .map(PathBuf::from)
8038    }
8039
8040    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
8041        self.upstream_client
8042            .request(proto::TryExec {
8043                project_id: rpc::proto::SSH_PROJECT_ID,
8044                worktree_id: self.worktree.id().to_proto(),
8045                binary: Some(proto::LanguageServerCommand {
8046                    path: command.path.to_string_lossy().to_string(),
8047                    arguments: command
8048                        .arguments
8049                        .into_iter()
8050                        .map(|s| s.to_string_lossy().to_string())
8051                        .collect(),
8052                    env: command.env.unwrap_or_default().into_iter().collect(),
8053                }),
8054            })
8055            .await?;
8056        Ok(())
8057    }
8058
8059    fn update_status(
8060        &self,
8061        server_name: LanguageServerName,
8062        status: language::LanguageServerBinaryStatus,
8063    ) {
8064        self.language_registry
8065            .update_lsp_status(server_name, status);
8066    }
8067
8068    async fn read_text_file(&self, path: PathBuf) -> Result<String> {
8069        self.upstream_client
8070            .request(proto::ReadTextFile {
8071                project_id: rpc::proto::SSH_PROJECT_ID,
8072                path: Some(proto::ProjectPath {
8073                    worktree_id: self.worktree.id().to_proto(),
8074                    path: path.to_string_lossy().to_string(),
8075                }),
8076            })
8077            .await
8078            .map(|r| r.text)
8079    }
8080}
8081
8082async fn populate_labels_for_symbols(
8083    symbols: Vec<CoreSymbol>,
8084    language_registry: &Arc<LanguageRegistry>,
8085    default_language: Option<LanguageName>,
8086    lsp_adapter: Option<Arc<CachedLspAdapter>>,
8087    output: &mut Vec<Symbol>,
8088) {
8089    #[allow(clippy::mutable_key_type)]
8090    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
8091
8092    let mut unknown_path = None;
8093    for symbol in symbols {
8094        let language = language_registry
8095            .language_for_file_path(&symbol.path.path)
8096            .await
8097            .ok()
8098            .or_else(|| {
8099                unknown_path.get_or_insert(symbol.path.path.clone());
8100                default_language.as_ref().and_then(|name| {
8101                    language_registry
8102                        .language_for_name(&name.0)
8103                        .now_or_never()?
8104                        .ok()
8105                })
8106            });
8107        symbols_by_language
8108            .entry(language)
8109            .or_default()
8110            .push(symbol);
8111    }
8112
8113    if let Some(unknown_path) = unknown_path {
8114        log::info!(
8115            "no language found for symbol path {}",
8116            unknown_path.display()
8117        );
8118    }
8119
8120    let mut label_params = Vec::new();
8121    for (language, mut symbols) in symbols_by_language {
8122        label_params.clear();
8123        label_params.extend(
8124            symbols
8125                .iter_mut()
8126                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
8127        );
8128
8129        let mut labels = Vec::new();
8130        if let Some(language) = language {
8131            let lsp_adapter = lsp_adapter.clone().or_else(|| {
8132                language_registry
8133                    .lsp_adapters(&language.name())
8134                    .first()
8135                    .cloned()
8136            });
8137            if let Some(lsp_adapter) = lsp_adapter {
8138                labels = lsp_adapter
8139                    .labels_for_symbols(&label_params, &language)
8140                    .await
8141                    .log_err()
8142                    .unwrap_or_default();
8143            }
8144        }
8145
8146        for ((symbol, (name, _)), label) in symbols
8147            .into_iter()
8148            .zip(label_params.drain(..))
8149            .zip(labels.into_iter().chain(iter::repeat(None)))
8150        {
8151            output.push(Symbol {
8152                language_server_name: symbol.language_server_name,
8153                source_worktree_id: symbol.source_worktree_id,
8154                path: symbol.path,
8155                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
8156                name,
8157                kind: symbol.kind,
8158                range: symbol.range,
8159                signature: symbol.signature,
8160            });
8161        }
8162    }
8163}
8164
8165fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
8166    match server.capabilities().text_document_sync.as_ref()? {
8167        lsp::TextDocumentSyncCapability::Kind(kind) => match *kind {
8168            lsp::TextDocumentSyncKind::NONE => None,
8169            lsp::TextDocumentSyncKind::FULL => Some(true),
8170            lsp::TextDocumentSyncKind::INCREMENTAL => Some(false),
8171            _ => None,
8172        },
8173        lsp::TextDocumentSyncCapability::Options(options) => match options.save.as_ref()? {
8174            lsp::TextDocumentSyncSaveOptions::Supported(supported) => {
8175                if *supported {
8176                    Some(true)
8177                } else {
8178                    None
8179                }
8180            }
8181            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
8182                Some(save_options.include_text.unwrap_or(false))
8183            }
8184        },
8185    }
8186}
8187
8188#[cfg(test)]
8189#[test]
8190fn test_glob_literal_prefix() {
8191    assert_eq!(glob_literal_prefix("**/*.js"), "");
8192    assert_eq!(glob_literal_prefix("node_modules/**/*.js"), "node_modules");
8193    assert_eq!(glob_literal_prefix("foo/{bar,baz}.js"), "foo");
8194    assert_eq!(glob_literal_prefix("foo/bar/baz.js"), "foo/bar/baz.js");
8195}