lsp_store.rs

   1pub mod clangd_ext;
   2pub mod lsp_ext_command;
   3pub mod rust_analyzer_ext;
   4
   5use crate::{
   6    buffer_store::{BufferStore, BufferStoreEvent},
   7    environment::ProjectEnvironment,
   8    lsp_command::{self, *},
   9    manifest_tree::{AdapterQuery, LanguageServerTree, LaunchDisposition, ManifestTree},
  10    prettier_store::{self, PrettierStore, PrettierStoreEvent},
  11    project_settings::{LspSettings, ProjectSettings},
  12    relativize_path, resolve_path,
  13    toolchain_store::{EmptyToolchainStore, ToolchainStoreEvent},
  14    worktree_store::{WorktreeStore, WorktreeStoreEvent},
  15    yarn::YarnPathStore,
  16    CodeAction, Completion, CompletionSource, CoreCompletion, Hover, InlayHint, LspAction,
  17    ProjectItem, ProjectPath, ProjectTransaction, ResolveState, Symbol, ToolchainStore,
  18};
  19use anyhow::{anyhow, Context as _, Result};
  20use async_trait::async_trait;
  21use client::{proto, TypedEnvelope};
  22use collections::{btree_map, BTreeMap, BTreeSet, HashMap, HashSet};
  23use futures::{
  24    future::{join_all, Shared},
  25    select, select_biased,
  26    stream::FuturesUnordered,
  27    AsyncWriteExt, Future, FutureExt, StreamExt,
  28};
  29use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
  30use gpui::{
  31    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString, Task,
  32    WeakEntity,
  33};
  34use http_client::HttpClient;
  35use itertools::Itertools as _;
  36use language::{
  37    language_settings::{
  38        language_settings, FormatOnSave, Formatter, LanguageSettings, SelectedFormatter,
  39    },
  40    point_to_lsp,
  41    proto::{deserialize_anchor, deserialize_version, serialize_anchor, serialize_version},
  42    range_from_lsp, range_to_lsp, Bias, BinaryStatus, Buffer, BufferSnapshot, CachedLspAdapter,
  43    CodeLabel, Diagnostic, DiagnosticEntry, DiagnosticSet, Diff, File as _, Language,
  44    LanguageRegistry, LanguageToolchainStore, LocalFile, LspAdapter, LspAdapterDelegate, Patch,
  45    PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Transaction, Unclipped,
  46};
  47use lsp::{
  48    notification::DidRenameFiles, CodeActionKind, CompletionContext, DiagnosticSeverity,
  49    DiagnosticTag, DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter,
  50    FileOperationPatternKind, FileOperationRegistrationOptions, FileRename, FileSystemWatcher,
  51    LanguageServer, LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId,
  52    LanguageServerName, LspRequestFuture, MessageActionItem, MessageType, OneOf, RenameFilesParams,
  53    SymbolKind, TextEdit, WillRenameFiles, WorkDoneProgressCancelParams, WorkspaceFolder,
  54};
  55use node_runtime::read_package_installed_version;
  56use parking_lot::Mutex;
  57use postage::watch;
  58use rand::prelude::*;
  59
  60use rpc::{
  61    proto::{FromProto, ToProto},
  62    AnyProtoClient,
  63};
  64use serde::Serialize;
  65use settings::{Settings, SettingsLocation, SettingsStore};
  66use sha2::{Digest, Sha256};
  67use smol::channel::Sender;
  68use snippet::Snippet;
  69use std::{
  70    any::Any,
  71    borrow::Cow,
  72    cell::RefCell,
  73    cmp::Ordering,
  74    convert::TryInto,
  75    ffi::OsStr,
  76    iter, mem,
  77    ops::{ControlFlow, Range},
  78    path::{self, Path, PathBuf},
  79    rc::Rc,
  80    str,
  81    sync::Arc,
  82    time::{Duration, Instant},
  83};
  84use text::{Anchor, BufferId, LineEnding, OffsetRangeExt};
  85use url::Url;
  86use util::{
  87    debug_panic, defer, maybe, merge_json_value_into, paths::SanitizedPath, post_inc, ResultExt,
  88    TryFutureExt as _,
  89};
  90
  91pub use fs::*;
  92pub use language::Location;
  93#[cfg(any(test, feature = "test-support"))]
  94pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  95pub use worktree::{
  96    Entry, EntryKind, File, LocalWorktree, PathChange, ProjectEntryId, UpdatedEntriesSet,
  97    UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings, FS_WATCH_LATENCY,
  98};
  99
 100const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
 101pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
 102
 103#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 104pub enum FormatTrigger {
 105    Save,
 106    Manual,
 107}
 108
 109pub enum LspFormatTarget {
 110    Buffers,
 111    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
 112}
 113
 114pub type OpenLspBufferHandle = Entity<Entity<Buffer>>;
 115
 116impl FormatTrigger {
 117    fn from_proto(value: i32) -> FormatTrigger {
 118        match value {
 119            0 => FormatTrigger::Save,
 120            1 => FormatTrigger::Manual,
 121            _ => FormatTrigger::Save,
 122        }
 123    }
 124}
 125
 126pub struct LocalLspStore {
 127    weak: WeakEntity<LspStore>,
 128    worktree_store: Entity<WorktreeStore>,
 129    toolchain_store: Entity<ToolchainStore>,
 130    http_client: Arc<dyn HttpClient>,
 131    environment: Entity<ProjectEnvironment>,
 132    fs: Arc<dyn Fs>,
 133    languages: Arc<LanguageRegistry>,
 134    language_server_ids: HashMap<(WorktreeId, LanguageServerName), BTreeSet<LanguageServerId>>,
 135    yarn: Entity<YarnPathStore>,
 136    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
 137    buffers_being_formatted: HashSet<BufferId>,
 138    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
 139    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
 140    language_server_paths_watched_for_rename:
 141        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
 142    language_server_watcher_registrations:
 143        HashMap<LanguageServerId, HashMap<String, Vec<FileSystemWatcher>>>,
 144    supplementary_language_servers:
 145        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
 146    prettier_store: Entity<PrettierStore>,
 147    next_diagnostic_group_id: usize,
 148    diagnostics: HashMap<
 149        WorktreeId,
 150        HashMap<
 151            Arc<Path>,
 152            Vec<(
 153                LanguageServerId,
 154                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 155            )>,
 156        >,
 157    >,
 158    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
 159    _subscription: gpui::Subscription,
 160    lsp_tree: Entity<LanguageServerTree>,
 161    registered_buffers: HashMap<BufferId, usize>,
 162}
 163
 164impl LocalLspStore {
 165    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
 166    pub fn running_language_server_for_id(
 167        &self,
 168        id: LanguageServerId,
 169    ) -> Option<&Arc<LanguageServer>> {
 170        let language_server_state = self.language_servers.get(&id)?;
 171
 172        match language_server_state {
 173            LanguageServerState::Running { server, .. } => Some(server),
 174            LanguageServerState::Starting { .. } => None,
 175        }
 176    }
 177
 178    fn start_language_server(
 179        &mut self,
 180        worktree_handle: &Entity<Worktree>,
 181        delegate: Arc<LocalLspAdapterDelegate>,
 182        adapter: Arc<CachedLspAdapter>,
 183        settings: Arc<LspSettings>,
 184        cx: &mut App,
 185    ) -> LanguageServerId {
 186        let worktree = worktree_handle.read(cx);
 187        let worktree_id = worktree.id();
 188        let root_path = worktree.abs_path();
 189        let key = (worktree_id, adapter.name.clone());
 190
 191        let override_options = settings.initialization_options.clone();
 192
 193        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
 194
 195        let server_id = self.languages.next_language_server_id();
 196        log::info!(
 197            "attempting to start language server {:?}, path: {root_path:?}, id: {server_id}",
 198            adapter.name.0
 199        );
 200
 201        let binary = self.get_language_server_binary(adapter.clone(), delegate.clone(), true, cx);
 202        let pending_workspace_folders: Arc<Mutex<BTreeSet<Url>>> = Default::default();
 203        let pending_server = cx.spawn({
 204            let adapter = adapter.clone();
 205            let server_name = adapter.name.clone();
 206            let stderr_capture = stderr_capture.clone();
 207            #[cfg(any(test, feature = "test-support"))]
 208            let lsp_store = self.weak.clone();
 209            let pending_workspace_folders = pending_workspace_folders.clone();
 210            async move |cx| {
 211                let binary = binary.await?;
 212                #[cfg(any(test, feature = "test-support"))]
 213                if let Some(server) = lsp_store
 214                    .update(&mut cx.clone(), |this, cx| {
 215                        this.languages.create_fake_language_server(
 216                            server_id,
 217                            &server_name,
 218                            binary.clone(),
 219                            &mut cx.to_async(),
 220                        )
 221                    })
 222                    .ok()
 223                    .flatten()
 224                {
 225                    return Ok(server);
 226                }
 227
 228                lsp::LanguageServer::new(
 229                    stderr_capture,
 230                    server_id,
 231                    server_name,
 232                    binary,
 233                    &root_path,
 234                    adapter.code_action_kinds(),
 235                    pending_workspace_folders,
 236                    cx,
 237                )
 238            }
 239        });
 240
 241        let startup = {
 242            let server_name = adapter.name.0.clone();
 243            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
 244            let key = key.clone();
 245            let adapter = adapter.clone();
 246            let this = self.weak.clone();
 247            let pending_workspace_folders = pending_workspace_folders.clone();
 248            let fs = self.fs.clone();
 249            cx.spawn(async move |cx| {
 250                let result = async {
 251                    let toolchains = this.update(cx, |this, cx| this.toolchain_store(cx))?;
 252                    let language_server = pending_server.await?;
 253
 254                    let workspace_config = adapter
 255                        .adapter
 256                        .clone()
 257                        .workspace_configuration(fs.as_ref(), &delegate, toolchains.clone(), cx)
 258                        .await?;
 259
 260                    let mut initialization_options = adapter
 261                        .adapter
 262                        .clone()
 263                        .initialization_options(fs.as_ref(), &(delegate))
 264                        .await?;
 265
 266                    match (&mut initialization_options, override_options) {
 267                        (Some(initialization_options), Some(override_options)) => {
 268                            merge_json_value_into(override_options, initialization_options);
 269                        }
 270                        (None, override_options) => initialization_options = override_options,
 271                        _ => {}
 272                    }
 273
 274                    let initialization_params = cx.update(|cx| {
 275                        let mut params = language_server.default_initialize_params(cx);
 276                        params.initialization_options = initialization_options;
 277                        adapter.adapter.prepare_initialize_params(params)
 278                    })??;
 279
 280                    Self::setup_lsp_messages(
 281                        this.clone(),
 282                        fs,
 283                        &language_server,
 284                        delegate.clone(),
 285                        adapter.clone(),
 286                    );
 287
 288                    let did_change_configuration_params =
 289                        Arc::new(lsp::DidChangeConfigurationParams {
 290                            settings: workspace_config,
 291                        });
 292                    let language_server = cx
 293                        .update(|cx| {
 294                            language_server.initialize(
 295                                initialization_params,
 296                                did_change_configuration_params.clone(),
 297                                cx,
 298                            )
 299                        })?
 300                        .await
 301                        .inspect_err(|_| {
 302                            if let Some(this) = this.upgrade() {
 303                                this.update(cx, |_, cx| {
 304                                    cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
 305                                })
 306                                .ok();
 307                            }
 308                        })?;
 309
 310                    language_server
 311                        .notify::<lsp::notification::DidChangeConfiguration>(
 312                            &did_change_configuration_params,
 313                        )
 314                        .ok();
 315
 316                    anyhow::Ok(language_server)
 317                }
 318                .await;
 319
 320                match result {
 321                    Ok(server) => {
 322                        this.update(cx, |this, mut cx| {
 323                            this.insert_newly_running_language_server(
 324                                adapter,
 325                                server.clone(),
 326                                server_id,
 327                                key,
 328                                pending_workspace_folders,
 329                                &mut cx,
 330                            );
 331                        })
 332                        .ok();
 333                        stderr_capture.lock().take();
 334                        Some(server)
 335                    }
 336
 337                    Err(err) => {
 338                        let log = stderr_capture.lock().take().unwrap_or_default();
 339                        delegate.update_status(
 340                            adapter.name(),
 341                            BinaryStatus::Failed {
 342                                error: format!("{err}\n-- stderr--\n{}", log),
 343                            },
 344                        );
 345                        log::error!("Failed to start language server {server_name:?}: {err}");
 346                        log::error!("server stderr: {:?}", log);
 347                        None
 348                    }
 349                }
 350            })
 351        };
 352        let state = LanguageServerState::Starting {
 353            startup,
 354            pending_workspace_folders,
 355        };
 356
 357        self.language_servers.insert(server_id, state);
 358        self.language_server_ids
 359            .entry(key)
 360            .or_default()
 361            .insert(server_id);
 362        server_id
 363    }
 364
 365    fn get_language_server_binary(
 366        &self,
 367        adapter: Arc<CachedLspAdapter>,
 368        delegate: Arc<dyn LspAdapterDelegate>,
 369        allow_binary_download: bool,
 370        cx: &mut App,
 371    ) -> Task<Result<LanguageServerBinary>> {
 372        let settings = ProjectSettings::get(
 373            Some(SettingsLocation {
 374                worktree_id: delegate.worktree_id(),
 375                path: Path::new(""),
 376            }),
 377            cx,
 378        )
 379        .lsp
 380        .get(&adapter.name)
 381        .and_then(|s| s.binary.clone());
 382
 383        if settings.as_ref().is_some_and(|b| b.path.is_some()) {
 384            let settings = settings.unwrap();
 385
 386            return cx.spawn(async move |_| {
 387                let mut env = delegate.shell_env().await;
 388                env.extend(settings.env.unwrap_or_default());
 389
 390                Ok(LanguageServerBinary {
 391                    path: PathBuf::from(&settings.path.unwrap()),
 392                    env: Some(env),
 393                    arguments: settings
 394                        .arguments
 395                        .unwrap_or_default()
 396                        .iter()
 397                        .map(Into::into)
 398                        .collect(),
 399                })
 400            });
 401        }
 402        let lsp_binary_options = LanguageServerBinaryOptions {
 403            allow_path_lookup: !settings
 404                .as_ref()
 405                .and_then(|b| b.ignore_system_version)
 406                .unwrap_or_default(),
 407            allow_binary_download,
 408        };
 409        let toolchains = self.toolchain_store.read(cx).as_language_toolchain_store();
 410        cx.spawn(async move |cx| {
 411            let binary_result = adapter
 412                .clone()
 413                .get_language_server_command(delegate.clone(), toolchains, lsp_binary_options, cx)
 414                .await;
 415
 416            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
 417
 418            let mut binary = binary_result?;
 419            let mut shell_env = delegate.shell_env().await;
 420
 421            if let Some(settings) = settings {
 422                if let Some(arguments) = settings.arguments {
 423                    binary.arguments = arguments.into_iter().map(Into::into).collect();
 424                }
 425                if let Some(env) = settings.env {
 426                    shell_env.extend(env);
 427                }
 428            }
 429
 430            binary.env = Some(shell_env);
 431            Ok(binary)
 432        })
 433    }
 434
 435    fn setup_lsp_messages(
 436        this: WeakEntity<LspStore>,
 437        fs: Arc<dyn Fs>,
 438        language_server: &LanguageServer,
 439        delegate: Arc<dyn LspAdapterDelegate>,
 440        adapter: Arc<CachedLspAdapter>,
 441    ) {
 442        let name = language_server.name();
 443        let server_id = language_server.server_id();
 444        language_server
 445            .on_notification::<lsp::notification::PublishDiagnostics, _>({
 446                let adapter = adapter.clone();
 447                let this = this.clone();
 448                move |mut params, cx| {
 449                    let adapter = adapter.clone();
 450                    if let Some(this) = this.upgrade() {
 451                        adapter.process_diagnostics(&mut params);
 452                        this.update(cx, |this, cx| {
 453                            this.update_diagnostics(
 454                                server_id,
 455                                params,
 456                                &adapter.disk_based_diagnostic_sources,
 457                                cx,
 458                            )
 459                            .log_err();
 460                        })
 461                        .ok();
 462                    }
 463                }
 464            })
 465            .detach();
 466        language_server
 467            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
 468                let adapter = adapter.adapter.clone();
 469                let delegate = delegate.clone();
 470                let this = this.clone();
 471                let fs = fs.clone();
 472                move |params, cx| {
 473                    let adapter = adapter.clone();
 474                    let delegate = delegate.clone();
 475                    let this = this.clone();
 476                    let fs = fs.clone();
 477                    let mut cx = cx.clone();
 478                    async move {
 479                        let toolchains =
 480                            this.update(&mut cx, |this, cx| this.toolchain_store(cx))?;
 481                        let workspace_config = adapter
 482                            .workspace_configuration(fs.as_ref(), &delegate, toolchains, &mut cx)
 483                            .await?;
 484                        Ok(params
 485                            .items
 486                            .into_iter()
 487                            .map(|item| {
 488                                if let Some(section) = &item.section {
 489                                    workspace_config
 490                                        .get(section)
 491                                        .cloned()
 492                                        .unwrap_or(serde_json::Value::Null)
 493                                } else {
 494                                    workspace_config.clone()
 495                                }
 496                            })
 497                            .collect())
 498                    }
 499                }
 500            })
 501            .detach();
 502
 503        language_server
 504            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
 505                let this = this.clone();
 506                move |_, cx| {
 507                    let this = this.clone();
 508                    let mut cx = cx.clone();
 509                    async move {
 510                        let Some(server) =
 511                            this.update(&mut cx, |this, _| this.language_server_for_id(server_id))?
 512                        else {
 513                            return Ok(None);
 514                        };
 515                        let root = server.workspace_folders();
 516                        Ok(Some(
 517                            root.iter()
 518                                .cloned()
 519                                .map(|uri| WorkspaceFolder {
 520                                    uri,
 521                                    name: Default::default(),
 522                                })
 523                                .collect(),
 524                        ))
 525                    }
 526                }
 527            })
 528            .detach();
 529        // Even though we don't have handling for these requests, respond to them to
 530        // avoid stalling any language server like `gopls` which waits for a response
 531        // to these requests when initializing.
 532        language_server
 533            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
 534                let this = this.clone();
 535                move |params, cx| {
 536                    let this = this.clone();
 537                    let mut cx = cx.clone();
 538                    async move {
 539                        this.update(&mut cx, |this, _| {
 540                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
 541                            {
 542                                if let lsp::NumberOrString::String(token) = params.token {
 543                                    status.progress_tokens.insert(token);
 544                                }
 545                            }
 546                        })?;
 547
 548                        Ok(())
 549                    }
 550                }
 551            })
 552            .detach();
 553
 554        language_server
 555            .on_request::<lsp::request::RegisterCapability, _, _>({
 556                let this = this.clone();
 557                move |params, cx| {
 558                    let this = this.clone();
 559                    let mut cx = cx.clone();
 560                    async move {
 561                        for reg in params.registrations {
 562                            match reg.method.as_str() {
 563                                "workspace/didChangeWatchedFiles" => {
 564                                    if let Some(options) = reg.register_options {
 565                                        let options = serde_json::from_value(options)?;
 566                                        this.update(&mut cx, |this, cx| {
 567                                            this.as_local_mut()?.on_lsp_did_change_watched_files(
 568                                                server_id, &reg.id, options, cx,
 569                                            );
 570                                            Some(())
 571                                        })?;
 572                                    }
 573                                }
 574                                "textDocument/rangeFormatting" => {
 575                                    this.update(&mut cx, |this, _| {
 576                                        if let Some(server) = this.language_server_for_id(server_id)
 577                                        {
 578                                            let options = reg
 579                                                .register_options
 580                                                .map(|options| {
 581                                                    serde_json::from_value::<
 582                                                        lsp::DocumentRangeFormattingOptions,
 583                                                    >(
 584                                                        options
 585                                                    )
 586                                                })
 587                                                .transpose()?;
 588                                            let provider = match options {
 589                                                None => OneOf::Left(true),
 590                                                Some(options) => OneOf::Right(options),
 591                                            };
 592                                            server.update_capabilities(|capabilities| {
 593                                                capabilities.document_range_formatting_provider =
 594                                                    Some(provider);
 595                                            })
 596                                        }
 597                                        anyhow::Ok(())
 598                                    })??;
 599                                }
 600                                "textDocument/onTypeFormatting" => {
 601                                    this.update(&mut cx, |this, _| {
 602                                        if let Some(server) = this.language_server_for_id(server_id)
 603                                        {
 604                                            let options = reg
 605                                                .register_options
 606                                                .map(|options| {
 607                                                    serde_json::from_value::<
 608                                                        lsp::DocumentOnTypeFormattingOptions,
 609                                                    >(
 610                                                        options
 611                                                    )
 612                                                })
 613                                                .transpose()?;
 614                                            if let Some(options) = options {
 615                                                server.update_capabilities(|capabilities| {
 616                                                    capabilities
 617                                                        .document_on_type_formatting_provider =
 618                                                        Some(options);
 619                                                })
 620                                            }
 621                                        }
 622                                        anyhow::Ok(())
 623                                    })??;
 624                                }
 625                                "textDocument/formatting" => {
 626                                    this.update(&mut cx, |this, _| {
 627                                        if let Some(server) = this.language_server_for_id(server_id)
 628                                        {
 629                                            let options = reg
 630                                                .register_options
 631                                                .map(|options| {
 632                                                    serde_json::from_value::<
 633                                                        lsp::DocumentFormattingOptions,
 634                                                    >(
 635                                                        options
 636                                                    )
 637                                                })
 638                                                .transpose()?;
 639                                            let provider = match options {
 640                                                None => OneOf::Left(true),
 641                                                Some(options) => OneOf::Right(options),
 642                                            };
 643                                            server.update_capabilities(|capabilities| {
 644                                                capabilities.document_formatting_provider =
 645                                                    Some(provider);
 646                                            })
 647                                        }
 648                                        anyhow::Ok(())
 649                                    })??;
 650                                }
 651                                "workspace/didChangeConfiguration" => {
 652                                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
 653                                }
 654                                "textDocument/rename" => {
 655                                    this.update(&mut cx, |this, _| {
 656                                        if let Some(server) = this.language_server_for_id(server_id)
 657                                        {
 658                                            let options = reg
 659                                                .register_options
 660                                                .map(|options| {
 661                                                    serde_json::from_value::<lsp::RenameOptions>(
 662                                                        options,
 663                                                    )
 664                                                })
 665                                                .transpose()?;
 666                                            let options = match options {
 667                                                None => OneOf::Left(true),
 668                                                Some(options) => OneOf::Right(options),
 669                                            };
 670
 671                                            server.update_capabilities(|capabilities| {
 672                                                capabilities.rename_provider = Some(options);
 673                                            })
 674                                        }
 675                                        anyhow::Ok(())
 676                                    })??;
 677                                }
 678                                _ => log::warn!("unhandled capability registration: {reg:?}"),
 679                            }
 680                        }
 681                        Ok(())
 682                    }
 683                }
 684            })
 685            .detach();
 686
 687        language_server
 688            .on_request::<lsp::request::UnregisterCapability, _, _>({
 689                let this = this.clone();
 690                move |params, cx| {
 691                    let this = this.clone();
 692                    let mut cx = cx.clone();
 693                    async move {
 694                        for unreg in params.unregisterations.iter() {
 695                            match unreg.method.as_str() {
 696                                "workspace/didChangeWatchedFiles" => {
 697                                    this.update(&mut cx, |this, cx| {
 698                                        this.as_local_mut()?
 699                                            .on_lsp_unregister_did_change_watched_files(
 700                                                server_id, &unreg.id, cx,
 701                                            );
 702                                        Some(())
 703                                    })?;
 704                                }
 705                                "workspace/didChangeConfiguration" => {
 706                                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
 707                                }
 708                                "textDocument/rename" => {
 709                                    this.update(&mut cx, |this, _| {
 710                                        if let Some(server) = this.language_server_for_id(server_id)
 711                                        {
 712                                            server.update_capabilities(|capabilities| {
 713                                                capabilities.rename_provider = None
 714                                            })
 715                                        }
 716                                    })?;
 717                                }
 718                                "textDocument/rangeFormatting" => {
 719                                    this.update(&mut cx, |this, _| {
 720                                        if let Some(server) = this.language_server_for_id(server_id)
 721                                        {
 722                                            server.update_capabilities(|capabilities| {
 723                                                capabilities.document_range_formatting_provider =
 724                                                    None
 725                                            })
 726                                        }
 727                                    })?;
 728                                }
 729                                "textDocument/onTypeFormatting" => {
 730                                    this.update(&mut cx, |this, _| {
 731                                        if let Some(server) = this.language_server_for_id(server_id)
 732                                        {
 733                                            server.update_capabilities(|capabilities| {
 734                                                capabilities.document_on_type_formatting_provider =
 735                                                    None;
 736                                            })
 737                                        }
 738                                    })?;
 739                                }
 740                                "textDocument/formatting" => {
 741                                    this.update(&mut cx, |this, _| {
 742                                        if let Some(server) = this.language_server_for_id(server_id)
 743                                        {
 744                                            server.update_capabilities(|capabilities| {
 745                                                capabilities.document_formatting_provider = None;
 746                                            })
 747                                        }
 748                                    })?;
 749                                }
 750                                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
 751                            }
 752                        }
 753                        Ok(())
 754                    }
 755                }
 756            })
 757            .detach();
 758
 759        language_server
 760            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
 761                let adapter = adapter.clone();
 762                let this = this.clone();
 763                move |params, cx| {
 764                    let mut cx = cx.clone();
 765                    let this = this.clone();
 766                    let adapter = adapter.clone();
 767                    async move {
 768                        LocalLspStore::on_lsp_workspace_edit(
 769                            this.clone(),
 770                            params,
 771                            server_id,
 772                            adapter.clone(),
 773                            &mut cx,
 774                        )
 775                        .await
 776                    }
 777                }
 778            })
 779            .detach();
 780
 781        language_server
 782            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
 783                let this = this.clone();
 784                move |(), cx| {
 785                    let this = this.clone();
 786                    let mut cx = cx.clone();
 787                    async move {
 788                        this.update(&mut cx, |this, cx| {
 789                            cx.emit(LspStoreEvent::RefreshInlayHints);
 790                            this.downstream_client.as_ref().map(|(client, project_id)| {
 791                                client.send(proto::RefreshInlayHints {
 792                                    project_id: *project_id,
 793                                })
 794                            })
 795                        })?
 796                        .transpose()?;
 797                        Ok(())
 798                    }
 799                }
 800            })
 801            .detach();
 802
 803        language_server
 804            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 805                let this = this.clone();
 806                move |(), cx| {
 807                    let this = this.clone();
 808                    let mut cx = cx.clone();
 809                    async move {
 810                        this.update(&mut cx, |this, cx| {
 811                            cx.emit(LspStoreEvent::RefreshCodeLens);
 812                            this.downstream_client.as_ref().map(|(client, project_id)| {
 813                                client.send(proto::RefreshCodeLens {
 814                                    project_id: *project_id,
 815                                })
 816                            })
 817                        })?
 818                        .transpose()?;
 819                        Ok(())
 820                    }
 821                }
 822            })
 823            .detach();
 824
 825        language_server
 826            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 827                let this = this.clone();
 828                let name = name.to_string();
 829                move |params, cx| {
 830                    let this = this.clone();
 831                    let name = name.to_string();
 832                    let mut cx = cx.clone();
 833                    async move {
 834                        let actions = params.actions.unwrap_or_default();
 835                        let (tx, rx) = smol::channel::bounded(1);
 836                        let request = LanguageServerPromptRequest {
 837                            level: match params.typ {
 838                                lsp::MessageType::ERROR => PromptLevel::Critical,
 839                                lsp::MessageType::WARNING => PromptLevel::Warning,
 840                                _ => PromptLevel::Info,
 841                            },
 842                            message: params.message,
 843                            actions,
 844                            response_channel: tx,
 845                            lsp_name: name.clone(),
 846                        };
 847
 848                        let did_update = this
 849                            .update(&mut cx, |_, cx| {
 850                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 851                            })
 852                            .is_ok();
 853                        if did_update {
 854                            let response = rx.recv().await.ok();
 855                            Ok(response)
 856                        } else {
 857                            Ok(None)
 858                        }
 859                    }
 860                }
 861            })
 862            .detach();
 863        language_server
 864            .on_notification::<lsp::notification::ShowMessage, _>({
 865                let this = this.clone();
 866                let name = name.to_string();
 867                move |params, cx| {
 868                    let this = this.clone();
 869                    let name = name.to_string();
 870                    let mut cx = cx.clone();
 871
 872                    let (tx, _) = smol::channel::bounded(1);
 873                    let request = LanguageServerPromptRequest {
 874                        level: match params.typ {
 875                            lsp::MessageType::ERROR => PromptLevel::Critical,
 876                            lsp::MessageType::WARNING => PromptLevel::Warning,
 877                            _ => PromptLevel::Info,
 878                        },
 879                        message: params.message,
 880                        actions: vec![],
 881                        response_channel: tx,
 882                        lsp_name: name.clone(),
 883                    };
 884
 885                    let _ = this.update(&mut cx, |_, cx| {
 886                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 887                    });
 888                }
 889            })
 890            .detach();
 891
 892        let disk_based_diagnostics_progress_token =
 893            adapter.disk_based_diagnostics_progress_token.clone();
 894
 895        language_server
 896            .on_notification::<lsp::notification::Progress, _>({
 897                let this = this.clone();
 898                move |params, cx| {
 899                    if let Some(this) = this.upgrade() {
 900                        this.update(cx, |this, cx| {
 901                            this.on_lsp_progress(
 902                                params,
 903                                server_id,
 904                                disk_based_diagnostics_progress_token.clone(),
 905                                cx,
 906                            );
 907                        })
 908                        .ok();
 909                    }
 910                }
 911            })
 912            .detach();
 913
 914        language_server
 915            .on_notification::<lsp::notification::LogMessage, _>({
 916                let this = this.clone();
 917                move |params, cx| {
 918                    if let Some(this) = this.upgrade() {
 919                        this.update(cx, |_, cx| {
 920                            cx.emit(LspStoreEvent::LanguageServerLog(
 921                                server_id,
 922                                LanguageServerLogType::Log(params.typ),
 923                                params.message,
 924                            ));
 925                        })
 926                        .ok();
 927                    }
 928                }
 929            })
 930            .detach();
 931
 932        language_server
 933            .on_notification::<lsp::notification::LogTrace, _>({
 934                let this = this.clone();
 935                move |params, cx| {
 936                    let mut cx = cx.clone();
 937                    if let Some(this) = this.upgrade() {
 938                        this.update(&mut cx, |_, cx| {
 939                            cx.emit(LspStoreEvent::LanguageServerLog(
 940                                server_id,
 941                                LanguageServerLogType::Trace(params.verbose),
 942                                params.message,
 943                            ));
 944                        })
 945                        .ok();
 946                    }
 947                }
 948            })
 949            .detach();
 950
 951        rust_analyzer_ext::register_notifications(this.clone(), language_server);
 952        clangd_ext::register_notifications(this, language_server, adapter);
 953    }
 954
 955    fn shutdown_language_servers(
 956        &mut self,
 957        _cx: &mut Context<LspStore>,
 958    ) -> impl Future<Output = ()> {
 959        let shutdown_futures = self
 960            .language_servers
 961            .drain()
 962            .map(|(_, server_state)| async {
 963                use LanguageServerState::*;
 964                match server_state {
 965                    Running { server, .. } => server.shutdown()?.await,
 966                    Starting { startup, .. } => startup.await?.shutdown()?.await,
 967                }
 968            })
 969            .collect::<Vec<_>>();
 970
 971        async move {
 972            futures::future::join_all(shutdown_futures).await;
 973        }
 974    }
 975
 976    fn language_servers_for_worktree(
 977        &self,
 978        worktree_id: WorktreeId,
 979    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 980        self.language_server_ids
 981            .iter()
 982            .flat_map(move |((language_server_path, _), ids)| {
 983                ids.iter().filter_map(move |id| {
 984                    if *language_server_path != worktree_id {
 985                        return None;
 986                    }
 987                    if let Some(LanguageServerState::Running { server, .. }) =
 988                        self.language_servers.get(id)
 989                    {
 990                        return Some(server);
 991                    } else {
 992                        None
 993                    }
 994                })
 995            })
 996    }
 997
 998    fn language_server_ids_for_project_path(
 999        &self,
1000        project_path: ProjectPath,
1001        language: &Language,
1002        cx: &mut App,
1003    ) -> Vec<LanguageServerId> {
1004        let Some(worktree) = self
1005            .worktree_store
1006            .read(cx)
1007            .worktree_for_id(project_path.worktree_id, cx)
1008        else {
1009            return vec![];
1010        };
1011        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
1012        let root = self.lsp_tree.update(cx, |this, cx| {
1013            this.get(
1014                project_path,
1015                AdapterQuery::Language(&language.name()),
1016                delegate,
1017                cx,
1018            )
1019            .filter_map(|node| node.server_id())
1020            .collect::<Vec<_>>()
1021        });
1022
1023        root
1024    }
1025
1026    fn language_server_ids_for_buffer(
1027        &self,
1028        buffer: &Buffer,
1029        cx: &mut App,
1030    ) -> Vec<LanguageServerId> {
1031        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
1032            let worktree_id = file.worktree_id(cx);
1033
1034            let path: Arc<Path> = file
1035                .path()
1036                .parent()
1037                .map(Arc::from)
1038                .unwrap_or_else(|| file.path().clone());
1039            let worktree_path = ProjectPath { worktree_id, path };
1040            self.language_server_ids_for_project_path(worktree_path, language, cx)
1041        } else {
1042            Vec::new()
1043        }
1044    }
1045
1046    fn language_servers_for_buffer<'a>(
1047        &'a self,
1048        buffer: &'a Buffer,
1049        cx: &'a mut App,
1050    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
1051        self.language_server_ids_for_buffer(buffer, cx)
1052            .into_iter()
1053            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
1054                LanguageServerState::Running {
1055                    adapter, server, ..
1056                } => Some((adapter, server)),
1057                _ => None,
1058            })
1059    }
1060
1061    fn primary_language_server_for_buffer<'a>(
1062        &'a self,
1063        buffer: &'a Buffer,
1064        cx: &'a mut App,
1065    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
1066        // The list of language servers is ordered based on the `language_servers` setting
1067        // for each language, thus we can consider the first one in the list to be the
1068        // primary one.
1069        self.language_servers_for_buffer(buffer, cx).next()
1070    }
1071
1072    async fn execute_code_action_kind_locally(
1073        lsp_store: WeakEntity<LspStore>,
1074        mut buffers: Vec<Entity<Buffer>>,
1075        kind: CodeActionKind,
1076        push_to_history: bool,
1077        cx: &mut AsyncApp,
1078    ) -> anyhow::Result<ProjectTransaction> {
1079        // Do not allow multiple concurrent code actions requests for the
1080        // same buffer.
1081        lsp_store.update(cx, |this, cx| {
1082            let this = this.as_local_mut().unwrap();
1083            buffers.retain(|buffer| {
1084                this.buffers_being_formatted
1085                    .insert(buffer.read(cx).remote_id())
1086            });
1087        })?;
1088        let _cleanup = defer({
1089            let this = lsp_store.clone();
1090            let mut cx = cx.clone();
1091            let buffers = &buffers;
1092            move || {
1093                this.update(&mut cx, |this, cx| {
1094                    let this = this.as_local_mut().unwrap();
1095                    for buffer in buffers {
1096                        this.buffers_being_formatted
1097                            .remove(&buffer.read(cx).remote_id());
1098                    }
1099                })
1100                .ok();
1101            }
1102        });
1103        let mut project_transaction = ProjectTransaction::default();
1104
1105        for buffer in &buffers {
1106            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
1107                buffer.update(cx, |buffer, cx| {
1108                    lsp_store
1109                        .as_local()
1110                        .unwrap()
1111                        .language_servers_for_buffer(buffer, cx)
1112                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
1113                        .collect::<Vec<_>>()
1114                })
1115            })?;
1116            for (lsp_adapter, language_server) in adapters_and_servers.iter() {
1117                let actions = Self::get_server_code_actions_from_action_kinds(
1118                    &lsp_store,
1119                    language_server.server_id(),
1120                    vec![kind.clone()],
1121                    buffer,
1122                    cx,
1123                )
1124                .await?;
1125                Self::execute_code_actions_on_server(
1126                    &lsp_store,
1127                    language_server,
1128                    lsp_adapter,
1129                    actions,
1130                    push_to_history,
1131                    &mut project_transaction,
1132                    cx,
1133                )
1134                .await?;
1135            }
1136        }
1137        Ok(project_transaction)
1138    }
1139
1140    async fn format_locally(
1141        lsp_store: WeakEntity<LspStore>,
1142        mut buffers: Vec<FormattableBuffer>,
1143        push_to_history: bool,
1144        trigger: FormatTrigger,
1145        cx: &mut AsyncApp,
1146    ) -> anyhow::Result<ProjectTransaction> {
1147        // Do not allow multiple concurrent formatting requests for the
1148        // same buffer.
1149        lsp_store.update(cx, |this, cx| {
1150            let this = this.as_local_mut().unwrap();
1151            buffers.retain(|buffer| {
1152                this.buffers_being_formatted
1153                    .insert(buffer.handle.read(cx).remote_id())
1154            });
1155        })?;
1156
1157        let _cleanup = defer({
1158            let this = lsp_store.clone();
1159            let mut cx = cx.clone();
1160            let buffers = &buffers;
1161            move || {
1162                this.update(&mut cx, |this, cx| {
1163                    let this = this.as_local_mut().unwrap();
1164                    for buffer in buffers {
1165                        this.buffers_being_formatted
1166                            .remove(&buffer.handle.read(cx).remote_id());
1167                    }
1168                })
1169                .ok();
1170            }
1171        });
1172
1173        let mut project_transaction = ProjectTransaction::default();
1174
1175        for buffer in &buffers {
1176            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
1177                buffer.handle.update(cx, |buffer, cx| {
1178                    lsp_store
1179                        .as_local()
1180                        .unwrap()
1181                        .language_servers_for_buffer(buffer, cx)
1182                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
1183                        .collect::<Vec<_>>()
1184                })
1185            })?;
1186
1187            let settings = buffer.handle.read_with(cx, |buffer, cx| {
1188                language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
1189                    .into_owned()
1190            })?;
1191
1192            let mut transaction_id_format = None;
1193
1194            // ensure no transactions created while formatting are
1195            // grouped with the previous transaction in the history
1196            // based on the transaction group interval
1197            buffer.handle.update(cx, |buffer, _| {
1198                buffer.finalize_last_transaction();
1199            })?;
1200
1201            // handle whitespace formatting
1202            {
1203                if settings.remove_trailing_whitespace_on_save {
1204                    let diff = buffer
1205                        .handle
1206                        .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))?
1207                        .await;
1208                    buffer.handle.update(cx, |buffer, cx| {
1209                        buffer.start_transaction();
1210                        buffer.apply_diff(diff, cx);
1211                        transaction_id_format =
1212                            transaction_id_format.or(buffer.end_transaction(cx));
1213                        if let Some(transaction_id) = transaction_id_format {
1214                            buffer.group_until_transaction(transaction_id);
1215                        }
1216                    })?;
1217                }
1218
1219                if settings.ensure_final_newline_on_save {
1220                    buffer.handle.update(cx, |buffer, cx| {
1221                        buffer.start_transaction();
1222                        buffer.ensure_final_newline(cx);
1223                        transaction_id_format =
1224                            transaction_id_format.or(buffer.end_transaction(cx));
1225                        if let Some(transaction_id) = transaction_id_format {
1226                            buffer.group_until_transaction(transaction_id);
1227                        }
1228                    })?;
1229                }
1230            }
1231
1232            // Formatter for `code_actions_on_format` that runs before
1233            // the rest of the formatters
1234            let code_actions_on_format_formatter = 'ca_formatter: {
1235                let should_run_code_actions_on_format = !matches!(
1236                    (trigger, &settings.format_on_save),
1237                    (FormatTrigger::Save, &FormatOnSave::Off)
1238                );
1239                let have_code_actions_to_run_on_format = settings
1240                    .code_actions_on_format
1241                    .values()
1242                    .any(|enabled| *enabled);
1243
1244                if should_run_code_actions_on_format {
1245                    if have_code_actions_to_run_on_format {
1246                        break 'ca_formatter Some(Formatter::CodeActions(
1247                            settings.code_actions_on_format.clone(),
1248                        ));
1249                    }
1250                }
1251                break 'ca_formatter None;
1252            };
1253
1254            let formatters = match (trigger, &settings.format_on_save) {
1255                (FormatTrigger::Save, FormatOnSave::Off) => &[],
1256                (FormatTrigger::Save, FormatOnSave::List(formatters)) => formatters.as_ref(),
1257                (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
1258                    match &settings.formatter {
1259                        SelectedFormatter::Auto => {
1260                            if settings.prettier.allowed {
1261                                std::slice::from_ref(&Formatter::Prettier)
1262                            } else {
1263                                std::slice::from_ref(&Formatter::LanguageServer { name: None })
1264                            }
1265                        }
1266                        SelectedFormatter::List(formatter_list) => formatter_list.as_ref(),
1267                    }
1268                }
1269            };
1270
1271            let formatters = code_actions_on_format_formatter.iter().chain(formatters);
1272
1273            // helper function to avoid duplicate logic between formatter handlers below
1274            // We want to avoid continuing to format the buffer if it has been edited since the start
1275            // so we check that the last transaction id on the undo stack matches the one we expect
1276            // This check should be done after each "gather" step where we generate a diff or edits to apply,
1277            // and before applying them to the buffer to avoid messing up the user's buffer
1278            fn err_if_buffer_edited_since_start(
1279                buffer: &FormattableBuffer,
1280                transaction_id_format: Option<text::TransactionId>,
1281                cx: &AsyncApp,
1282            ) -> Option<anyhow::Error> {
1283                let transaction_id_last = buffer
1284                    .handle
1285                    .read_with(cx, |buffer, _| {
1286                        buffer.peek_undo_stack().map(|t| t.transaction_id())
1287                    })
1288                    .ok()
1289                    .flatten();
1290                let should_continue_formatting = match (transaction_id_format, transaction_id_last)
1291                {
1292                    (Some(format), Some(last)) => format == last,
1293                    (Some(_), None) => false,
1294                    (_, _) => true,
1295                };
1296                if !should_continue_formatting {
1297                    return Some(anyhow::anyhow!("Buffer edited while formatting. Aborting"));
1298                }
1299                return None;
1300            }
1301
1302            // variable used to track errors that occur during the formatting process below,
1303            // but that need to not be returned right away (with `?` for example) because we
1304            // still need to clean up the transaction history and update the project transaction
1305            let mut result = anyhow::Ok(());
1306
1307            'formatters: for formatter in formatters {
1308                match formatter {
1309                    Formatter::Prettier => {
1310                        let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
1311                            lsp_store.prettier_store().unwrap().downgrade()
1312                        })?;
1313                        let diff_result =
1314                            prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
1315                                .await
1316                                .transpose();
1317                        let Ok(diff) = diff_result else {
1318                            result = Err(diff_result.unwrap_err());
1319                            break 'formatters;
1320                        };
1321                        let Some(diff) = diff else {
1322                            continue 'formatters;
1323                        };
1324                        if let Some(err) =
1325                            err_if_buffer_edited_since_start(buffer, transaction_id_format, &cx)
1326                        {
1327                            result = Err(err);
1328                            break 'formatters;
1329                        }
1330                        buffer.handle.update(cx, |buffer, cx| {
1331                            buffer.start_transaction();
1332                            buffer.apply_diff(diff, cx);
1333                            transaction_id_format =
1334                                transaction_id_format.or(buffer.end_transaction(cx));
1335                            if let Some(transaction_id) = transaction_id_format {
1336                                buffer.group_until_transaction(transaction_id);
1337                            }
1338                        })?;
1339                    }
1340                    Formatter::External { command, arguments } => {
1341                        let diff_result = Self::format_via_external_command(
1342                            buffer,
1343                            command.as_ref(),
1344                            arguments.as_deref(),
1345                            cx,
1346                        )
1347                        .await
1348                        .with_context(|| {
1349                            format!("Failed to format buffer via external command: {}", command)
1350                        });
1351                        let Ok(diff) = diff_result else {
1352                            result = Err(diff_result.unwrap_err());
1353                            break 'formatters;
1354                        };
1355                        let Some(diff) = diff else {
1356                            continue 'formatters;
1357                        };
1358                        if let Some(err) =
1359                            err_if_buffer_edited_since_start(buffer, transaction_id_format, &cx)
1360                        {
1361                            result = Err(err);
1362                            break 'formatters;
1363                        }
1364                        buffer.handle.update(cx, |buffer, cx| {
1365                            buffer.start_transaction();
1366                            buffer.apply_diff(diff, cx);
1367                            transaction_id_format =
1368                                transaction_id_format.or(buffer.end_transaction(cx));
1369                            if let Some(transaction_id) = transaction_id_format {
1370                                buffer.group_until_transaction(transaction_id);
1371                            }
1372                        })?;
1373                    }
1374                    Formatter::LanguageServer { name } => {
1375                        let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
1376                            log::warn!("Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
1377                            continue 'formatters;
1378                        };
1379
1380                        let language_server = 'language_server: {
1381                            // if a name was provided, try to find the server with that name
1382                            if let Some(name) = name.as_deref() {
1383                                for (adapter, server) in &adapters_and_servers {
1384                                    if adapter.name.0.as_ref() == name {
1385                                        break 'language_server server.clone();
1386                                    }
1387                                }
1388                            }
1389
1390                            // otherwise, fall back to the primary language server for the buffer if one exists
1391                            let default_lsp = lsp_store.update(cx, |lsp_store, cx| {
1392                                buffer.handle.update(cx, |buffer, cx| {
1393                                    lsp_store
1394                                        .as_local()
1395                                        .unwrap()
1396                                        .primary_language_server_for_buffer(buffer, cx)
1397                                        .map(|(_, lsp)| lsp.clone())
1398                                })
1399                            })?;
1400
1401                            if let Some(default_lsp) = default_lsp {
1402                                break 'language_server default_lsp;
1403                            } else {
1404                                log::warn!(
1405                                    "No language server found to format buffer '{:?}'. Skipping",
1406                                    buffer_path_abs.as_path().to_string_lossy()
1407                                );
1408                                continue 'formatters;
1409                            }
1410                        };
1411
1412                        let edits_result = if let Some(ranges) = buffer.ranges.as_ref() {
1413                            Self::format_ranges_via_lsp(
1414                                &lsp_store,
1415                                &buffer.handle,
1416                                ranges,
1417                                buffer_path_abs,
1418                                &language_server,
1419                                &settings,
1420                                cx,
1421                            )
1422                            .await
1423                            .context("Failed to format ranges via language server")
1424                        } else {
1425                            Self::format_via_lsp(
1426                                &lsp_store,
1427                                &buffer.handle,
1428                                buffer_path_abs,
1429                                &language_server,
1430                                &settings,
1431                                cx,
1432                            )
1433                            .await
1434                            .context("failed to format via language server")
1435                        };
1436
1437                        let Ok(edits) = edits_result else {
1438                            result = Err(edits_result.unwrap_err());
1439                            break 'formatters;
1440                        };
1441
1442                        if edits.is_empty() {
1443                            continue 'formatters;
1444                        }
1445                        if let Some(err) =
1446                            err_if_buffer_edited_since_start(buffer, transaction_id_format, &cx)
1447                        {
1448                            result = Err(err);
1449                            break 'formatters;
1450                        }
1451
1452                        buffer.handle.update(cx, |buffer, cx| {
1453                            buffer.start_transaction();
1454                            buffer.edit(edits, None, cx);
1455                            transaction_id_format =
1456                                transaction_id_format.or(buffer.end_transaction(cx));
1457                            if let Some(transaction_id) = transaction_id_format {
1458                                buffer.group_until_transaction(transaction_id);
1459                            }
1460                        })?;
1461                    }
1462                    Formatter::CodeActions(code_actions) => {
1463                        let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
1464                            log::warn!("Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
1465                            continue 'formatters;
1466                        };
1467                        let code_action_kinds = code_actions
1468                            .iter()
1469                            .filter_map(|(action_kind, enabled)| {
1470                                enabled.then_some(action_kind.clone().into())
1471                            })
1472                            .collect::<Vec<_>>();
1473                        if code_action_kinds.is_empty() {
1474                            continue 'formatters;
1475                        }
1476
1477                        let mut actions_and_servers = Vec::new();
1478
1479                        for (index, (_, language_server)) in adapters_and_servers.iter().enumerate()
1480                        {
1481                            let actions_result = Self::get_server_code_actions_from_action_kinds(
1482                                        &lsp_store,
1483                                        language_server.server_id(),
1484                                        code_action_kinds.clone(),
1485                                        &buffer.handle,
1486                                        cx,
1487                                    )
1488                                    .await
1489                                    .with_context(
1490                                        || format!("Failed to resolve code actions with kinds {:?} for language server {}",
1491                                            code_action_kinds.iter().map(|kind| kind.as_str()).join(", "),
1492                                            language_server.name())
1493                                    );
1494                            let Ok(actions) = actions_result else {
1495                                // note: it may be better to set result to the error and break formatters here
1496                                // but for now we try to execute the actions that we can resolve and skip the rest
1497                                log::error!(
1498                                    "Failed to resolve code actions with kinds {:?} with language server {}",
1499                                    code_action_kinds.iter().map(|kind| kind.as_str()).join(", "),
1500                                    language_server.name()
1501                                );
1502                                continue;
1503                            };
1504                            for action in actions {
1505                                actions_and_servers.push((action, index));
1506                            }
1507                        }
1508
1509                        if actions_and_servers.is_empty() {
1510                            continue 'formatters;
1511                        }
1512
1513                        'actions: for (mut action, server_index) in actions_and_servers {
1514                            let server = &adapters_and_servers[server_index].1;
1515
1516                            let describe_code_action = |action: &CodeAction| {
1517                                format!(
1518                                    "code action '{}' with title \"{}\"",
1519                                    action
1520                                        .lsp_action
1521                                        .action_kind()
1522                                        .unwrap_or("unknown".into())
1523                                        .as_str(),
1524                                    action.lsp_action.title()
1525                                )
1526                            };
1527
1528                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
1529                            // but filters out and logs warnings for code actions that cause unreasonably
1530                            // difficult handling on our part, such as:
1531                            // - applying edits that call commands
1532                            //   which can result in arbitrary workspace edits being sent from the server that
1533                            //   have no way of being tied back to the command that initiated them (i.e. we
1534                            //   can't know which edits are part of the format request, or if the server is done sending
1535                            //   actions in response to the command)
1536                            // - actions that create/delete/modify/rename files other than the one we are formatting
1537                            //   as we then would need to handle such changes correctly in the local history as well
1538                            //   as the remote history through the ProjectTransaction
1539                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
1540                            // Supporting these actions is not impossible, but not supported as of yet.
1541
1542                            if let Err(err) =
1543                                Self::try_resolve_code_action(server, &mut action).await
1544                            {
1545                                log::error!(
1546                                    "Failed to resolve {}. Error: {}",
1547                                    describe_code_action(&action),
1548                                    err
1549                                );
1550                                continue 'actions;
1551                            }
1552                            if let Some(_) = action.lsp_action.command() {
1553                                log::warn!(
1554                                    "Code actions with commands are not supported while formatting. Skipping {}",
1555                                    describe_code_action(&action),
1556                                );
1557                                continue 'actions;
1558                            }
1559                            let Some(edit) = action.lsp_action.edit().cloned() else {
1560                                log::warn!(
1561                                    "No edit found for while formatting. Skipping {}",
1562                                    describe_code_action(&action),
1563                                );
1564                                continue 'actions;
1565                            };
1566
1567                            if edit.changes.is_none() && edit.document_changes.is_none() {
1568                                continue 'actions;
1569                            }
1570
1571                            let mut operations = Vec::new();
1572                            if let Some(document_changes) = edit.document_changes {
1573                                match document_changes {
1574                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
1575                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
1576                                    ),
1577                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
1578                                }
1579                            } else if let Some(changes) = edit.changes {
1580                                operations.extend(changes.into_iter().map(|(uri, edits)| {
1581                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
1582                                        text_document:
1583                                            lsp::OptionalVersionedTextDocumentIdentifier {
1584                                                uri,
1585                                                version: None,
1586                                            },
1587                                        edits: edits.into_iter().map(Edit::Plain).collect(),
1588                                    })
1589                                }));
1590                            }
1591
1592                            let mut edits = Vec::with_capacity(operations.len());
1593
1594                            for operation in operations {
1595                                let op = match operation {
1596                                    lsp::DocumentChangeOperation::Edit(op) => op,
1597                                    lsp::DocumentChangeOperation::Op(_) => {
1598                                        log::warn!(
1599                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
1600                                            describe_code_action(&action),
1601                                        );
1602                                        continue 'actions;
1603                                    }
1604                                };
1605                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
1606                                    log::warn!(
1607                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
1608                                        &op.text_document.uri,
1609                                        describe_code_action(&action),
1610                                    );
1611                                    continue 'actions;
1612                                };
1613                                if &file_path != buffer_path_abs {
1614                                    log::warn!(
1615                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
1616                                        file_path,
1617                                        buffer_path_abs,
1618                                        describe_code_action(&action),
1619                                    );
1620                                    continue 'actions;
1621                                }
1622
1623                                let mut lsp_edits = Vec::new();
1624                                for edit in op.edits {
1625                                    match edit {
1626                                        Edit::Plain(edit) => {
1627                                            if !lsp_edits.contains(&edit) {
1628                                                lsp_edits.push(edit);
1629                                            }
1630                                        }
1631                                        Edit::Annotated(edit) => {
1632                                            if !lsp_edits.contains(&edit.text_edit) {
1633                                                lsp_edits.push(edit.text_edit);
1634                                            }
1635                                        }
1636                                        Edit::Snippet(_) => {
1637                                            log::warn!(
1638                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
1639                                                describe_code_action(&action),
1640                                            );
1641                                            continue 'actions;
1642                                        }
1643                                    }
1644                                }
1645                                let edits_result = lsp_store
1646                                        .update(cx, |lsp_store, cx| {
1647                                            lsp_store.as_local_mut().unwrap().edits_from_lsp(
1648                                                &buffer.handle,
1649                                                lsp_edits,
1650                                                server.server_id(),
1651                                                op.text_document.version,
1652                                                cx,
1653                                            )
1654                                        })?
1655                                        .await
1656                                        .with_context(
1657                                            || format!(
1658                                                "Failed to resolve edits from LSP for buffer {:?} while handling {}",
1659                                                buffer_path_abs.as_path(),
1660                                                describe_code_action(&action),
1661                                            )
1662                                    ).log_err();
1663                                let Some(resolved_edits) = edits_result else {
1664                                    continue 'actions;
1665                                };
1666                                edits.extend(resolved_edits);
1667                            }
1668
1669                            if let Some(err) =
1670                                err_if_buffer_edited_since_start(buffer, transaction_id_format, &cx)
1671                            {
1672                                result = Err(err);
1673                                break 'formatters;
1674                            }
1675                            buffer.handle.update(cx, |buffer, cx| {
1676                                buffer.start_transaction();
1677                                buffer.edit(edits, None, cx);
1678                                transaction_id_format =
1679                                    transaction_id_format.or(buffer.end_transaction(cx));
1680                                if let Some(transaction_id) = transaction_id_format {
1681                                    buffer.group_until_transaction(transaction_id);
1682                                }
1683                            })?;
1684                        }
1685                    }
1686                }
1687            }
1688
1689            let buffer_handle = buffer.handle.clone();
1690            buffer.handle.update(cx, |buffer, _| {
1691                let Some(transaction_id) = transaction_id_format else {
1692                    return result;
1693                };
1694                let Some(transaction_id_last) =
1695                    buffer.peek_undo_stack().map(|t| t.transaction_id())
1696                else {
1697                    // unwrapping should work here, how would we get a transaction id
1698                    // with no transaction on the undo stack?
1699                    // *but* it occasionally panics. Avoiding panics for now...
1700                    return result;
1701                };
1702                if transaction_id_last != transaction_id {
1703                    return result;
1704                }
1705                let transaction = buffer
1706                    .finalize_last_transaction()
1707                    .cloned()
1708                    .expect("There is a transaction on the undo stack if we were able to peek it");
1709                // debug_assert_eq!(transaction.id, transaction_id);
1710                if !push_to_history {
1711                    buffer.forget_transaction(transaction.id);
1712                }
1713                project_transaction
1714                    .0
1715                    .insert(buffer_handle.clone(), transaction);
1716                return result;
1717            })??;
1718        }
1719
1720        return Ok(project_transaction);
1721    }
1722
1723    pub async fn format_ranges_via_lsp(
1724        this: &WeakEntity<LspStore>,
1725        buffer_handle: &Entity<Buffer>,
1726        ranges: &[Range<Anchor>],
1727        abs_path: &Path,
1728        language_server: &Arc<LanguageServer>,
1729        settings: &LanguageSettings,
1730        cx: &mut AsyncApp,
1731    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
1732        let capabilities = &language_server.capabilities();
1733        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
1734        if range_formatting_provider.map_or(false, |provider| provider == &OneOf::Left(false)) {
1735            return Err(anyhow!(
1736                "{} language server does not support range formatting",
1737                language_server.name()
1738            ));
1739        }
1740
1741        let uri = lsp::Url::from_file_path(abs_path)
1742            .map_err(|_| anyhow!("failed to convert abs path to uri"))?;
1743        let text_document = lsp::TextDocumentIdentifier::new(uri);
1744
1745        let lsp_edits = {
1746            let mut lsp_ranges = Vec::new();
1747            this.update(cx, |_this, cx| {
1748                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
1749                // not have been sent to the language server. This seems like a fairly systemic
1750                // issue, though, the resolution probably is not specific to formatting.
1751                //
1752                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
1753                // LSP.
1754                let snapshot = buffer_handle.read(cx).snapshot();
1755                for range in ranges {
1756                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
1757                }
1758                anyhow::Ok(())
1759            })??;
1760
1761            let mut edits = None;
1762            for range in lsp_ranges {
1763                if let Some(mut edit) = language_server
1764                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
1765                        text_document: text_document.clone(),
1766                        range,
1767                        options: lsp_command::lsp_formatting_options(settings),
1768                        work_done_progress_params: Default::default(),
1769                    })
1770                    .await?
1771                {
1772                    edits.get_or_insert_with(Vec::new).append(&mut edit);
1773                }
1774            }
1775            edits
1776        };
1777
1778        if let Some(lsp_edits) = lsp_edits {
1779            this.update(cx, |this, cx| {
1780                this.as_local_mut().unwrap().edits_from_lsp(
1781                    &buffer_handle,
1782                    lsp_edits,
1783                    language_server.server_id(),
1784                    None,
1785                    cx,
1786                )
1787            })?
1788            .await
1789        } else {
1790            Ok(Vec::with_capacity(0))
1791        }
1792    }
1793
1794    async fn format_via_lsp(
1795        this: &WeakEntity<LspStore>,
1796        buffer: &Entity<Buffer>,
1797        abs_path: &Path,
1798        language_server: &Arc<LanguageServer>,
1799        settings: &LanguageSettings,
1800        cx: &mut AsyncApp,
1801    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
1802        let uri = lsp::Url::from_file_path(abs_path)
1803            .map_err(|_| anyhow!("failed to convert abs path to uri"))?;
1804        let text_document = lsp::TextDocumentIdentifier::new(uri);
1805        let capabilities = &language_server.capabilities();
1806
1807        let formatting_provider = capabilities.document_formatting_provider.as_ref();
1808        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
1809
1810        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
1811            language_server
1812                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
1813                    text_document,
1814                    options: lsp_command::lsp_formatting_options(settings),
1815                    work_done_progress_params: Default::default(),
1816                })
1817                .await?
1818        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
1819            let buffer_start = lsp::Position::new(0, 0);
1820            let buffer_end = buffer.update(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
1821            language_server
1822                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
1823                    text_document: text_document.clone(),
1824                    range: lsp::Range::new(buffer_start, buffer_end),
1825                    options: lsp_command::lsp_formatting_options(settings),
1826                    work_done_progress_params: Default::default(),
1827                })
1828                .await?
1829        } else {
1830            None
1831        };
1832
1833        if let Some(lsp_edits) = lsp_edits {
1834            this.update(cx, |this, cx| {
1835                this.as_local_mut().unwrap().edits_from_lsp(
1836                    buffer,
1837                    lsp_edits,
1838                    language_server.server_id(),
1839                    None,
1840                    cx,
1841                )
1842            })?
1843            .await
1844        } else {
1845            Ok(Vec::with_capacity(0))
1846        }
1847    }
1848
1849    async fn format_via_external_command(
1850        buffer: &FormattableBuffer,
1851        command: &str,
1852        arguments: Option<&[String]>,
1853        cx: &mut AsyncApp,
1854    ) -> Result<Option<Diff>> {
1855        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
1856            let file = File::from_dyn(buffer.file())?;
1857            let worktree = file.worktree.read(cx);
1858            let mut worktree_path = worktree.abs_path().to_path_buf();
1859            if worktree.root_entry()?.is_file() {
1860                worktree_path.pop();
1861            }
1862            Some(worktree_path)
1863        })?;
1864
1865        let mut child = util::command::new_smol_command(command);
1866
1867        if let Some(buffer_env) = buffer.env.as_ref() {
1868            child.envs(buffer_env);
1869        }
1870
1871        if let Some(working_dir_path) = working_dir_path {
1872            child.current_dir(working_dir_path);
1873        }
1874
1875        if let Some(arguments) = arguments {
1876            child.args(arguments.iter().map(|arg| {
1877                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
1878                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
1879                } else {
1880                    arg.replace("{buffer_path}", "Untitled")
1881                }
1882            }));
1883        }
1884
1885        let mut child = child
1886            .stdin(smol::process::Stdio::piped())
1887            .stdout(smol::process::Stdio::piped())
1888            .stderr(smol::process::Stdio::piped())
1889            .spawn()?;
1890
1891        let stdin = child
1892            .stdin
1893            .as_mut()
1894            .ok_or_else(|| anyhow!("failed to acquire stdin"))?;
1895        let text = buffer
1896            .handle
1897            .update(cx, |buffer, _| buffer.as_rope().clone())?;
1898        for chunk in text.chunks() {
1899            stdin.write_all(chunk.as_bytes()).await?;
1900        }
1901        stdin.flush().await?;
1902
1903        let output = child.output().await?;
1904        if !output.status.success() {
1905            return Err(anyhow!(
1906                "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
1907                output.status.code(),
1908                String::from_utf8_lossy(&output.stdout),
1909                String::from_utf8_lossy(&output.stderr),
1910            ));
1911        }
1912
1913        let stdout = String::from_utf8(output.stdout)?;
1914        Ok(Some(
1915            buffer
1916                .handle
1917                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
1918                .await,
1919        ))
1920    }
1921
1922    async fn try_resolve_code_action(
1923        lang_server: &LanguageServer,
1924        action: &mut CodeAction,
1925    ) -> anyhow::Result<()> {
1926        match &mut action.lsp_action {
1927            LspAction::Action(lsp_action) => {
1928                if !action.resolved
1929                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
1930                    && lsp_action.data.is_some()
1931                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
1932                {
1933                    *lsp_action = Box::new(
1934                        lang_server
1935                            .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
1936                            .await?,
1937                    );
1938                }
1939            }
1940            LspAction::CodeLens(lens) => {
1941                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
1942                    *lens = lang_server
1943                        .request::<lsp::request::CodeLensResolve>(lens.clone())
1944                        .await?;
1945                }
1946            }
1947            LspAction::Command(_) => {}
1948        }
1949
1950        action.resolved = true;
1951        anyhow::Ok(())
1952    }
1953
1954    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
1955        let buffer = buffer_handle.read(cx);
1956
1957        let file = buffer.file().cloned();
1958        let Some(file) = File::from_dyn(file.as_ref()) else {
1959            return;
1960        };
1961        if !file.is_local() {
1962            return;
1963        }
1964
1965        let worktree_id = file.worktree_id(cx);
1966        let language = buffer.language().cloned();
1967
1968        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
1969            for (server_id, diagnostics) in
1970                diagnostics.get(file.path()).cloned().unwrap_or_default()
1971            {
1972                self.update_buffer_diagnostics(buffer_handle, server_id, None, diagnostics, cx)
1973                    .log_err();
1974            }
1975        }
1976        let Some(language) = language else {
1977            return;
1978        };
1979        for adapter in self.languages.lsp_adapters(&language.name()) {
1980            let servers = self
1981                .language_server_ids
1982                .get(&(worktree_id, adapter.name.clone()));
1983            if let Some(server_ids) = servers {
1984                for server_id in server_ids {
1985                    let server = self
1986                        .language_servers
1987                        .get(server_id)
1988                        .and_then(|server_state| {
1989                            if let LanguageServerState::Running { server, .. } = server_state {
1990                                Some(server.clone())
1991                            } else {
1992                                None
1993                            }
1994                        });
1995                    let server = match server {
1996                        Some(server) => server,
1997                        None => continue,
1998                    };
1999
2000                    buffer_handle.update(cx, |buffer, cx| {
2001                        buffer.set_completion_triggers(
2002                            server.server_id(),
2003                            server
2004                                .capabilities()
2005                                .completion_provider
2006                                .as_ref()
2007                                .and_then(|provider| {
2008                                    provider
2009                                        .trigger_characters
2010                                        .as_ref()
2011                                        .map(|characters| characters.iter().cloned().collect())
2012                                })
2013                                .unwrap_or_default(),
2014                            cx,
2015                        );
2016                    });
2017                }
2018            }
2019        }
2020    }
2021
2022    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
2023        buffer.update(cx, |buffer, cx| {
2024            let Some(language) = buffer.language() else {
2025                return;
2026            };
2027            let path = ProjectPath {
2028                worktree_id: old_file.worktree_id(cx),
2029                path: old_file.path.clone(),
2030            };
2031            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
2032                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
2033                buffer.set_completion_triggers(server_id, Default::default(), cx);
2034            }
2035        });
2036    }
2037
2038    fn update_buffer_diagnostics(
2039        &mut self,
2040        buffer: &Entity<Buffer>,
2041        server_id: LanguageServerId,
2042        version: Option<i32>,
2043        mut diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
2044        cx: &mut Context<LspStore>,
2045    ) -> Result<()> {
2046        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
2047            Ordering::Equal
2048                .then_with(|| b.is_primary.cmp(&a.is_primary))
2049                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
2050                .then_with(|| a.severity.cmp(&b.severity))
2051                .then_with(|| a.message.cmp(&b.message))
2052        }
2053
2054        diagnostics.sort_unstable_by(|a, b| {
2055            Ordering::Equal
2056                .then_with(|| a.range.start.cmp(&b.range.start))
2057                .then_with(|| b.range.end.cmp(&a.range.end))
2058                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
2059        });
2060
2061        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
2062
2063        let edits_since_save = std::cell::LazyCell::new(|| {
2064            let saved_version = buffer.read(cx).saved_version();
2065            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
2066        });
2067
2068        let mut sanitized_diagnostics = Vec::new();
2069
2070        for entry in diagnostics {
2071            let start;
2072            let end;
2073            if entry.diagnostic.is_disk_based {
2074                // Some diagnostics are based on files on disk instead of buffers'
2075                // current contents. Adjust these diagnostics' ranges to reflect
2076                // any unsaved edits.
2077                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
2078                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
2079            } else {
2080                start = entry.range.start;
2081                end = entry.range.end;
2082            }
2083
2084            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
2085                ..snapshot.clip_point_utf16(end, Bias::Right);
2086
2087            // Expand empty ranges by one codepoint
2088            if range.start == range.end {
2089                // This will be go to the next boundary when being clipped
2090                range.end.column += 1;
2091                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
2092                if range.start == range.end && range.end.column > 0 {
2093                    range.start.column -= 1;
2094                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
2095                }
2096            }
2097
2098            sanitized_diagnostics.push(DiagnosticEntry {
2099                range,
2100                diagnostic: entry.diagnostic,
2101            });
2102        }
2103        drop(edits_since_save);
2104
2105        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
2106        buffer.update(cx, |buffer, cx| {
2107            buffer.update_diagnostics(server_id, set, cx)
2108        });
2109        Ok(())
2110    }
2111
2112    fn register_buffer_with_language_servers(
2113        &mut self,
2114        buffer_handle: &Entity<Buffer>,
2115        cx: &mut Context<LspStore>,
2116    ) {
2117        let buffer = buffer_handle.read(cx);
2118        let buffer_id = buffer.remote_id();
2119
2120        let Some(file) = File::from_dyn(buffer.file()) else {
2121            return;
2122        };
2123        if !file.is_local() {
2124            return;
2125        }
2126
2127        let abs_path = file.abs_path(cx);
2128        let Some(uri) = lsp::Url::from_file_path(&abs_path).log_err() else {
2129            return;
2130        };
2131        let initial_snapshot = buffer.text_snapshot();
2132        let worktree_id = file.worktree_id(cx);
2133
2134        let Some(language) = buffer.language().cloned() else {
2135            return;
2136        };
2137        let path: Arc<Path> = file
2138            .path()
2139            .parent()
2140            .map(Arc::from)
2141            .unwrap_or_else(|| file.path().clone());
2142        let Some(worktree) = self
2143            .worktree_store
2144            .read(cx)
2145            .worktree_for_id(worktree_id, cx)
2146        else {
2147            return;
2148        };
2149        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
2150        let servers = self.lsp_tree.clone().update(cx, |this, cx| {
2151            this.get(
2152                ProjectPath { worktree_id, path },
2153                AdapterQuery::Language(&language.name()),
2154                delegate.clone(),
2155                cx,
2156            )
2157            .collect::<Vec<_>>()
2158        });
2159        let servers = servers
2160            .into_iter()
2161            .filter_map(|server_node| {
2162                let server_id = server_node.server_id_or_init(
2163                    |LaunchDisposition {
2164                         server_name,
2165                         attach,
2166                         path,
2167                         settings,
2168                     }| match attach {
2169                        language::Attach::InstancePerRoot => {
2170                            // todo: handle instance per root proper.
2171                            if let Some(server_ids) = self
2172                                .language_server_ids
2173                                .get(&(worktree_id, server_name.clone()))
2174                            {
2175                                server_ids.iter().cloned().next().unwrap()
2176                            } else {
2177                                let language_name = language.name();
2178
2179                                self.start_language_server(
2180                                    &worktree,
2181                                    delegate.clone(),
2182                                    self.languages
2183                                        .lsp_adapters(&language_name)
2184                                        .into_iter()
2185                                        .find(|adapter| &adapter.name() == server_name)
2186                                        .expect("To find LSP adapter"),
2187                                    settings,
2188                                    cx,
2189                                )
2190                            }
2191                        }
2192                        language::Attach::Shared => {
2193                            let uri = Url::from_file_path(
2194                                worktree.read(cx).abs_path().join(&path.path),
2195                            );
2196                            let key = (worktree_id, server_name.clone());
2197                            if !self.language_server_ids.contains_key(&key) {
2198                                let language_name = language.name();
2199                                self.start_language_server(
2200                                    &worktree,
2201                                    delegate.clone(),
2202                                    self.languages
2203                                        .lsp_adapters(&language_name)
2204                                        .into_iter()
2205                                        .find(|adapter| &adapter.name() == server_name)
2206                                        .expect("To find LSP adapter"),
2207                                    settings,
2208                                    cx,
2209                                );
2210                            }
2211                            if let Some(server_ids) = self
2212                                .language_server_ids
2213                                .get(&key)
2214                            {
2215                                debug_assert_eq!(server_ids.len(), 1);
2216                                let server_id = server_ids.iter().cloned().next().unwrap();
2217
2218                                if let Some(state) = self.language_servers.get(&server_id) {
2219                                    if let Ok(uri) = uri {
2220                                        state.add_workspace_folder(uri);
2221                                    };
2222                                }
2223                                server_id
2224                            } else {
2225                                unreachable!("Language server ID should be available, as it's registered on demand")
2226                            }
2227                        }
2228                    },
2229                )?;
2230                let server_state = self.language_servers.get(&server_id)?;
2231                if let LanguageServerState::Running { server, .. } = server_state {
2232                    Some(server.clone())
2233                } else {
2234                    None
2235                }
2236            })
2237            .collect::<Vec<_>>();
2238        for server in servers {
2239            buffer_handle.update(cx, |buffer, cx| {
2240                buffer.set_completion_triggers(
2241                    server.server_id(),
2242                    server
2243                        .capabilities()
2244                        .completion_provider
2245                        .as_ref()
2246                        .and_then(|provider| {
2247                            provider
2248                                .trigger_characters
2249                                .as_ref()
2250                                .map(|characters| characters.iter().cloned().collect())
2251                        })
2252                        .unwrap_or_default(),
2253                    cx,
2254                );
2255            });
2256        }
2257        for adapter in self.languages.lsp_adapters(&language.name()) {
2258            let servers = self
2259                .language_server_ids
2260                .get(&(worktree_id, adapter.name.clone()))
2261                .map(|ids| {
2262                    ids.iter().flat_map(|id| {
2263                        self.language_servers.get(id).and_then(|server_state| {
2264                            if let LanguageServerState::Running { server, .. } = server_state {
2265                                Some(server.clone())
2266                            } else {
2267                                None
2268                            }
2269                        })
2270                    })
2271                });
2272            let servers = match servers {
2273                Some(server) => server,
2274                None => continue,
2275            };
2276
2277            for server in servers {
2278                let snapshot = LspBufferSnapshot {
2279                    version: 0,
2280                    snapshot: initial_snapshot.clone(),
2281                };
2282                self.buffer_snapshots
2283                    .entry(buffer_id)
2284                    .or_default()
2285                    .entry(server.server_id())
2286                    .or_insert_with(|| {
2287                        server.register_buffer(
2288                            uri.clone(),
2289                            adapter.language_id(&language.name()),
2290                            0,
2291                            initial_snapshot.text(),
2292                        );
2293
2294                        vec![snapshot]
2295                    });
2296            }
2297        }
2298    }
2299
2300    pub(crate) fn unregister_old_buffer_from_language_servers(
2301        &mut self,
2302        buffer: &Entity<Buffer>,
2303        old_file: &File,
2304        cx: &mut App,
2305    ) {
2306        let old_path = match old_file.as_local() {
2307            Some(local) => local.abs_path(cx),
2308            None => return,
2309        };
2310
2311        let Ok(file_url) = lsp::Url::from_file_path(old_path.as_path()) else {
2312            debug_panic!(
2313                "`{}` is not parseable as an URI",
2314                old_path.to_string_lossy()
2315            );
2316            return;
2317        };
2318        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
2319    }
2320
2321    pub(crate) fn unregister_buffer_from_language_servers(
2322        &mut self,
2323        buffer: &Entity<Buffer>,
2324        file_url: &lsp::Url,
2325        cx: &mut App,
2326    ) {
2327        buffer.update(cx, |buffer, cx| {
2328            let _ = self.buffer_snapshots.remove(&buffer.remote_id());
2329
2330            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
2331                language_server.unregister_buffer(file_url.clone());
2332            }
2333        });
2334    }
2335
2336    fn buffer_snapshot_for_lsp_version(
2337        &mut self,
2338        buffer: &Entity<Buffer>,
2339        server_id: LanguageServerId,
2340        version: Option<i32>,
2341        cx: &App,
2342    ) -> Result<TextBufferSnapshot> {
2343        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
2344
2345        if let Some(version) = version {
2346            let buffer_id = buffer.read(cx).remote_id();
2347            let snapshots = if let Some(snapshots) = self
2348                .buffer_snapshots
2349                .get_mut(&buffer_id)
2350                .and_then(|m| m.get_mut(&server_id))
2351            {
2352                snapshots
2353            } else if version == 0 {
2354                // Some language servers report version 0 even if the buffer hasn't been opened yet.
2355                // We detect this case and treat it as if the version was `None`.
2356                return Ok(buffer.read(cx).text_snapshot());
2357            } else {
2358                return Err(anyhow!(
2359                    "no snapshots found for buffer {buffer_id} and server {server_id}"
2360                ));
2361            };
2362
2363            let found_snapshot = snapshots
2364                    .binary_search_by_key(&version, |e| e.version)
2365                    .map(|ix| snapshots[ix].snapshot.clone())
2366                    .map_err(|_| {
2367                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
2368                    })?;
2369
2370            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
2371            Ok(found_snapshot)
2372        } else {
2373            Ok((buffer.read(cx)).text_snapshot())
2374        }
2375    }
2376
2377    async fn get_server_code_actions_from_action_kinds(
2378        lsp_store: &WeakEntity<LspStore>,
2379        language_server_id: LanguageServerId,
2380        code_action_kinds: Vec<lsp::CodeActionKind>,
2381        buffer: &Entity<Buffer>,
2382        cx: &mut AsyncApp,
2383    ) -> Result<Vec<CodeAction>> {
2384        let actions = lsp_store
2385            .update(cx, move |this, cx| {
2386                let request = GetCodeActions {
2387                    range: text::Anchor::MIN..text::Anchor::MAX,
2388                    kinds: Some(code_action_kinds),
2389                };
2390                let server = LanguageServerToQuery::Other(language_server_id);
2391                this.request_lsp(buffer.clone(), server, request, cx)
2392            })?
2393            .await?;
2394        return Ok(actions);
2395    }
2396
2397    pub async fn execute_code_actions_on_server(
2398        lsp_store: &WeakEntity<LspStore>,
2399        language_server: &Arc<LanguageServer>,
2400        lsp_adapter: &Arc<CachedLspAdapter>,
2401        actions: Vec<CodeAction>,
2402        push_to_history: bool,
2403        project_transaction: &mut ProjectTransaction,
2404        cx: &mut AsyncApp,
2405    ) -> Result<(), anyhow::Error> {
2406        for mut action in actions {
2407            Self::try_resolve_code_action(language_server, &mut action)
2408                .await
2409                .context("resolving a formatting code action")?;
2410
2411            if let Some(edit) = action.lsp_action.edit() {
2412                if edit.changes.is_none() && edit.document_changes.is_none() {
2413                    continue;
2414                }
2415
2416                let new = Self::deserialize_workspace_edit(
2417                    lsp_store.upgrade().context("project dropped")?,
2418                    edit.clone(),
2419                    push_to_history,
2420                    lsp_adapter.clone(),
2421                    language_server.clone(),
2422                    cx,
2423                )
2424                .await?;
2425                project_transaction.0.extend(new.0);
2426            }
2427
2428            if let Some(command) = action.lsp_action.command() {
2429                let server_capabilities = language_server.capabilities();
2430                let available_commands = server_capabilities
2431                    .execute_command_provider
2432                    .as_ref()
2433                    .map(|options| options.commands.as_slice())
2434                    .unwrap_or_default();
2435                if available_commands.contains(&command.command) {
2436                    lsp_store.update(cx, |lsp_store, _| {
2437                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
2438                            mode.last_workspace_edits_by_language_server
2439                                .remove(&language_server.server_id());
2440                        }
2441                    })?;
2442
2443                    language_server
2444                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
2445                            command: command.command.clone(),
2446                            arguments: command.arguments.clone().unwrap_or_default(),
2447                            ..Default::default()
2448                        })
2449                        .await?;
2450
2451                    lsp_store.update(cx, |this, _| {
2452                        if let LspStoreMode::Local(mode) = &mut this.mode {
2453                            project_transaction.0.extend(
2454                                mode.last_workspace_edits_by_language_server
2455                                    .remove(&language_server.server_id())
2456                                    .unwrap_or_default()
2457                                    .0,
2458                            )
2459                        }
2460                    })?;
2461                } else {
2462                    log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command)
2463                }
2464            }
2465        }
2466        return Ok(());
2467    }
2468
2469    pub async fn deserialize_text_edits(
2470        this: Entity<LspStore>,
2471        buffer_to_edit: Entity<Buffer>,
2472        edits: Vec<lsp::TextEdit>,
2473        push_to_history: bool,
2474        _: Arc<CachedLspAdapter>,
2475        language_server: Arc<LanguageServer>,
2476        cx: &mut AsyncApp,
2477    ) -> Result<Option<Transaction>> {
2478        let edits = this
2479            .update(cx, |this, cx| {
2480                this.as_local_mut().unwrap().edits_from_lsp(
2481                    &buffer_to_edit,
2482                    edits,
2483                    language_server.server_id(),
2484                    None,
2485                    cx,
2486                )
2487            })?
2488            .await?;
2489
2490        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
2491            buffer.finalize_last_transaction();
2492            buffer.start_transaction();
2493            for (range, text) in edits {
2494                buffer.edit([(range, text)], None, cx);
2495            }
2496
2497            if buffer.end_transaction(cx).is_some() {
2498                let transaction = buffer.finalize_last_transaction().unwrap().clone();
2499                if !push_to_history {
2500                    buffer.forget_transaction(transaction.id);
2501                }
2502                Some(transaction)
2503            } else {
2504                None
2505            }
2506        })?;
2507
2508        Ok(transaction)
2509    }
2510
2511    #[allow(clippy::type_complexity)]
2512    pub(crate) fn edits_from_lsp(
2513        &mut self,
2514        buffer: &Entity<Buffer>,
2515        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
2516        server_id: LanguageServerId,
2517        version: Option<i32>,
2518        cx: &mut Context<LspStore>,
2519    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
2520        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
2521        cx.background_spawn(async move {
2522            let snapshot = snapshot?;
2523            let mut lsp_edits = lsp_edits
2524                .into_iter()
2525                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
2526                .collect::<Vec<_>>();
2527            lsp_edits.sort_by_key(|(range, _)| range.start);
2528
2529            let mut lsp_edits = lsp_edits.into_iter().peekable();
2530            let mut edits = Vec::new();
2531            while let Some((range, mut new_text)) = lsp_edits.next() {
2532                // Clip invalid ranges provided by the language server.
2533                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
2534                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
2535
2536                // Combine any LSP edits that are adjacent.
2537                //
2538                // Also, combine LSP edits that are separated from each other by only
2539                // a newline. This is important because for some code actions,
2540                // Rust-analyzer rewrites the entire buffer via a series of edits that
2541                // are separated by unchanged newline characters.
2542                //
2543                // In order for the diffing logic below to work properly, any edits that
2544                // cancel each other out must be combined into one.
2545                while let Some((next_range, next_text)) = lsp_edits.peek() {
2546                    if next_range.start.0 > range.end {
2547                        if next_range.start.0.row > range.end.row + 1
2548                            || next_range.start.0.column > 0
2549                            || snapshot.clip_point_utf16(
2550                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
2551                                Bias::Left,
2552                            ) > range.end
2553                        {
2554                            break;
2555                        }
2556                        new_text.push('\n');
2557                    }
2558                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
2559                    new_text.push_str(next_text);
2560                    lsp_edits.next();
2561                }
2562
2563                // For multiline edits, perform a diff of the old and new text so that
2564                // we can identify the changes more precisely, preserving the locations
2565                // of any anchors positioned in the unchanged regions.
2566                if range.end.row > range.start.row {
2567                    let offset = range.start.to_offset(&snapshot);
2568                    let old_text = snapshot.text_for_range(range).collect::<String>();
2569                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
2570                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
2571                        (
2572                            snapshot.anchor_after(offset + range.start)
2573                                ..snapshot.anchor_before(offset + range.end),
2574                            replacement,
2575                        )
2576                    }));
2577                } else if range.end == range.start {
2578                    let anchor = snapshot.anchor_after(range.start);
2579                    edits.push((anchor..anchor, new_text.into()));
2580                } else {
2581                    let edit_start = snapshot.anchor_after(range.start);
2582                    let edit_end = snapshot.anchor_before(range.end);
2583                    edits.push((edit_start..edit_end, new_text.into()));
2584                }
2585            }
2586
2587            Ok(edits)
2588        })
2589    }
2590
2591    pub(crate) async fn deserialize_workspace_edit(
2592        this: Entity<LspStore>,
2593        edit: lsp::WorkspaceEdit,
2594        push_to_history: bool,
2595        lsp_adapter: Arc<CachedLspAdapter>,
2596        language_server: Arc<LanguageServer>,
2597        cx: &mut AsyncApp,
2598    ) -> Result<ProjectTransaction> {
2599        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
2600
2601        let mut operations = Vec::new();
2602        if let Some(document_changes) = edit.document_changes {
2603            match document_changes {
2604                lsp::DocumentChanges::Edits(edits) => {
2605                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
2606                }
2607                lsp::DocumentChanges::Operations(ops) => operations = ops,
2608            }
2609        } else if let Some(changes) = edit.changes {
2610            operations.extend(changes.into_iter().map(|(uri, edits)| {
2611                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
2612                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
2613                        uri,
2614                        version: None,
2615                    },
2616                    edits: edits.into_iter().map(Edit::Plain).collect(),
2617                })
2618            }));
2619        }
2620
2621        let mut project_transaction = ProjectTransaction::default();
2622        for operation in operations {
2623            match operation {
2624                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
2625                    let abs_path = op
2626                        .uri
2627                        .to_file_path()
2628                        .map_err(|_| anyhow!("can't convert URI to path"))?;
2629
2630                    if let Some(parent_path) = abs_path.parent() {
2631                        fs.create_dir(parent_path).await?;
2632                    }
2633                    if abs_path.ends_with("/") {
2634                        fs.create_dir(&abs_path).await?;
2635                    } else {
2636                        fs.create_file(
2637                            &abs_path,
2638                            op.options
2639                                .map(|options| fs::CreateOptions {
2640                                    overwrite: options.overwrite.unwrap_or(false),
2641                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
2642                                })
2643                                .unwrap_or_default(),
2644                        )
2645                        .await?;
2646                    }
2647                }
2648
2649                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
2650                    let source_abs_path = op
2651                        .old_uri
2652                        .to_file_path()
2653                        .map_err(|_| anyhow!("can't convert URI to path"))?;
2654                    let target_abs_path = op
2655                        .new_uri
2656                        .to_file_path()
2657                        .map_err(|_| anyhow!("can't convert URI to path"))?;
2658                    fs.rename(
2659                        &source_abs_path,
2660                        &target_abs_path,
2661                        op.options
2662                            .map(|options| fs::RenameOptions {
2663                                overwrite: options.overwrite.unwrap_or(false),
2664                                ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
2665                            })
2666                            .unwrap_or_default(),
2667                    )
2668                    .await?;
2669                }
2670
2671                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
2672                    let abs_path = op
2673                        .uri
2674                        .to_file_path()
2675                        .map_err(|_| anyhow!("can't convert URI to path"))?;
2676                    let options = op
2677                        .options
2678                        .map(|options| fs::RemoveOptions {
2679                            recursive: options.recursive.unwrap_or(false),
2680                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
2681                        })
2682                        .unwrap_or_default();
2683                    if abs_path.ends_with("/") {
2684                        fs.remove_dir(&abs_path, options).await?;
2685                    } else {
2686                        fs.remove_file(&abs_path, options).await?;
2687                    }
2688                }
2689
2690                lsp::DocumentChangeOperation::Edit(op) => {
2691                    let buffer_to_edit = this
2692                        .update(cx, |this, cx| {
2693                            this.open_local_buffer_via_lsp(
2694                                op.text_document.uri.clone(),
2695                                language_server.server_id(),
2696                                lsp_adapter.name.clone(),
2697                                cx,
2698                            )
2699                        })?
2700                        .await?;
2701
2702                    let edits = this
2703                        .update(cx, |this, cx| {
2704                            let path = buffer_to_edit.read(cx).project_path(cx);
2705                            let active_entry = this.active_entry;
2706                            let is_active_entry = path.clone().map_or(false, |project_path| {
2707                                this.worktree_store
2708                                    .read(cx)
2709                                    .entry_for_path(&project_path, cx)
2710                                    .map_or(false, |entry| Some(entry.id) == active_entry)
2711                            });
2712                            let local = this.as_local_mut().unwrap();
2713
2714                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
2715                            for edit in op.edits {
2716                                match edit {
2717                                    Edit::Plain(edit) => {
2718                                        if !edits.contains(&edit) {
2719                                            edits.push(edit)
2720                                        }
2721                                    }
2722                                    Edit::Annotated(edit) => {
2723                                        if !edits.contains(&edit.text_edit) {
2724                                            edits.push(edit.text_edit)
2725                                        }
2726                                    }
2727                                    Edit::Snippet(edit) => {
2728                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
2729                                        else {
2730                                            continue;
2731                                        };
2732
2733                                        if is_active_entry {
2734                                            snippet_edits.push((edit.range, snippet));
2735                                        } else {
2736                                            // Since this buffer is not focused, apply a normal edit.
2737                                            let new_edit = TextEdit {
2738                                                range: edit.range,
2739                                                new_text: snippet.text,
2740                                            };
2741                                            if !edits.contains(&new_edit) {
2742                                                edits.push(new_edit);
2743                                            }
2744                                        }
2745                                    }
2746                                }
2747                            }
2748                            if !snippet_edits.is_empty() {
2749                                let buffer_id = buffer_to_edit.read(cx).remote_id();
2750                                let version = if let Some(buffer_version) = op.text_document.version
2751                                {
2752                                    local
2753                                        .buffer_snapshot_for_lsp_version(
2754                                            &buffer_to_edit,
2755                                            language_server.server_id(),
2756                                            Some(buffer_version),
2757                                            cx,
2758                                        )
2759                                        .ok()
2760                                        .map(|snapshot| snapshot.version)
2761                                } else {
2762                                    Some(buffer_to_edit.read(cx).saved_version().clone())
2763                                };
2764
2765                                let most_recent_edit = version.and_then(|version| {
2766                                    version.iter().max_by_key(|timestamp| timestamp.value)
2767                                });
2768                                // Check if the edit that triggered that edit has been made by this participant.
2769
2770                                if let Some(most_recent_edit) = most_recent_edit {
2771                                    cx.emit(LspStoreEvent::SnippetEdit {
2772                                        buffer_id,
2773                                        edits: snippet_edits,
2774                                        most_recent_edit,
2775                                    });
2776                                }
2777                            }
2778
2779                            local.edits_from_lsp(
2780                                &buffer_to_edit,
2781                                edits,
2782                                language_server.server_id(),
2783                                op.text_document.version,
2784                                cx,
2785                            )
2786                        })?
2787                        .await?;
2788
2789                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
2790                        buffer.finalize_last_transaction();
2791                        buffer.start_transaction();
2792                        for (range, text) in edits {
2793                            buffer.edit([(range, text)], None, cx);
2794                        }
2795                        let transaction = if buffer.end_transaction(cx).is_some() {
2796                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
2797                            if !push_to_history {
2798                                buffer.forget_transaction(transaction.id);
2799                            }
2800                            Some(transaction)
2801                        } else {
2802                            None
2803                        };
2804
2805                        transaction
2806                    })?;
2807                    if let Some(transaction) = transaction {
2808                        project_transaction.0.insert(buffer_to_edit, transaction);
2809                    }
2810                }
2811            }
2812        }
2813
2814        Ok(project_transaction)
2815    }
2816
2817    async fn on_lsp_workspace_edit(
2818        this: WeakEntity<LspStore>,
2819        params: lsp::ApplyWorkspaceEditParams,
2820        server_id: LanguageServerId,
2821        adapter: Arc<CachedLspAdapter>,
2822        cx: &mut AsyncApp,
2823    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
2824        let this = this
2825            .upgrade()
2826            .ok_or_else(|| anyhow!("project project closed"))?;
2827        let language_server = this
2828            .update(cx, |this, _| this.language_server_for_id(server_id))?
2829            .ok_or_else(|| anyhow!("language server not found"))?;
2830        let transaction = Self::deserialize_workspace_edit(
2831            this.clone(),
2832            params.edit,
2833            true,
2834            adapter.clone(),
2835            language_server.clone(),
2836            cx,
2837        )
2838        .await
2839        .log_err();
2840        this.update(cx, |this, _| {
2841            if let Some(transaction) = transaction {
2842                this.as_local_mut()
2843                    .unwrap()
2844                    .last_workspace_edits_by_language_server
2845                    .insert(server_id, transaction);
2846            }
2847        })?;
2848        Ok(lsp::ApplyWorkspaceEditResponse {
2849            applied: true,
2850            failed_change: None,
2851            failure_reason: None,
2852        })
2853    }
2854
2855    fn remove_worktree(
2856        &mut self,
2857        id_to_remove: WorktreeId,
2858        cx: &mut Context<'_, LspStore>,
2859    ) -> Vec<LanguageServerId> {
2860        self.diagnostics.remove(&id_to_remove);
2861        self.prettier_store.update(cx, |prettier_store, cx| {
2862            prettier_store.remove_worktree(id_to_remove, cx);
2863        });
2864
2865        let mut servers_to_remove = BTreeMap::default();
2866        let mut servers_to_preserve = HashSet::default();
2867        for ((path, server_name), ref server_ids) in &self.language_server_ids {
2868            if *path == id_to_remove {
2869                servers_to_remove.extend(server_ids.iter().map(|id| (*id, server_name.clone())));
2870            } else {
2871                servers_to_preserve.extend(server_ids.iter().cloned());
2872            }
2873        }
2874        servers_to_remove.retain(|server_id, _| !servers_to_preserve.contains(server_id));
2875
2876        for (server_id_to_remove, _) in &servers_to_remove {
2877            self.language_server_ids
2878                .values_mut()
2879                .for_each(|server_ids| {
2880                    server_ids.remove(server_id_to_remove);
2881                });
2882            self.language_server_watched_paths
2883                .remove(&server_id_to_remove);
2884            self.language_server_paths_watched_for_rename
2885                .remove(&server_id_to_remove);
2886            self.last_workspace_edits_by_language_server
2887                .remove(&server_id_to_remove);
2888            self.language_servers.remove(&server_id_to_remove);
2889            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
2890        }
2891        servers_to_remove.into_keys().collect()
2892    }
2893
2894    fn rebuild_watched_paths_inner<'a>(
2895        &'a self,
2896        language_server_id: LanguageServerId,
2897        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
2898        cx: &mut Context<LspStore>,
2899    ) -> LanguageServerWatchedPathsBuilder {
2900        let worktrees = self
2901            .worktree_store
2902            .read(cx)
2903            .worktrees()
2904            .filter_map(|worktree| {
2905                self.language_servers_for_worktree(worktree.read(cx).id())
2906                    .find(|server| server.server_id() == language_server_id)
2907                    .map(|_| worktree)
2908            })
2909            .collect::<Vec<_>>();
2910
2911        let mut worktree_globs = HashMap::default();
2912        let mut abs_globs = HashMap::default();
2913        log::trace!(
2914            "Processing new watcher paths for language server with id {}",
2915            language_server_id
2916        );
2917
2918        enum PathToWatch {
2919            Worktree {
2920                literal_prefix: Arc<Path>,
2921                pattern: String,
2922            },
2923            Absolute {
2924                path: Arc<Path>,
2925                pattern: String,
2926            },
2927        }
2928        for watcher in watchers {
2929            let mut found_host = false;
2930            for worktree in &worktrees {
2931                let glob_is_inside_worktree = worktree.update(cx, |tree, _| {
2932                    let worktree_root_path = tree.abs_path();
2933                    let path_to_watch = match &watcher.glob_pattern {
2934                        lsp::GlobPattern::String(s) => {
2935                            let watcher_path = SanitizedPath::from(s);
2936                            match watcher_path.as_path().strip_prefix(&worktree_root_path) {
2937                                Ok(relative) => {
2938                                    let pattern = relative.to_string_lossy().to_string();
2939                                    let literal_prefix = glob_literal_prefix(relative).into();
2940
2941                                    PathToWatch::Worktree {
2942                                        literal_prefix,
2943                                        pattern,
2944                                    }
2945                                }
2946                                Err(_) => {
2947                                    let path = glob_literal_prefix(watcher_path.as_path());
2948                                    let pattern = watcher_path
2949                                        .as_path()
2950                                        .strip_prefix(&path)
2951                                        .map(|p| p.to_string_lossy().to_string())
2952                                        .unwrap_or_else(|e| {
2953                                            debug_panic!(
2954                                                "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
2955                                                s,
2956                                                path.display(),
2957                                                e
2958                                            );
2959                                            watcher_path.as_path().to_string_lossy().to_string()
2960                                        });
2961                                    let path = if path.components().next().is_none() {
2962                                        worktree_root_path.clone()
2963                                    } else {
2964                                        path.into()
2965                                    };
2966
2967                                    PathToWatch::Absolute { path, pattern }
2968                                }
2969                            }
2970                        }
2971                        lsp::GlobPattern::Relative(rp) => {
2972                            let Ok(mut base_uri) = match &rp.base_uri {
2973                                lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
2974                                lsp::OneOf::Right(base_uri) => base_uri,
2975                            }
2976                            .to_file_path() else {
2977                                return false;
2978                            };
2979
2980                            match base_uri.strip_prefix(&worktree_root_path) {
2981                                Ok(relative) => {
2982                                    let mut literal_prefix = relative.to_owned();
2983                                    literal_prefix
2984                                        .push(glob_literal_prefix(Path::new(&rp.pattern)));
2985
2986                                    PathToWatch::Worktree {
2987                                        literal_prefix: literal_prefix.into(),
2988                                        pattern: rp.pattern.clone(),
2989                                    }
2990                                }
2991                                Err(_) => {
2992                                    let path = glob_literal_prefix(Path::new(&rp.pattern));
2993                                    let pattern = Path::new(&rp.pattern)
2994                                        .strip_prefix(&path)
2995                                        .map(|p| p.to_string_lossy().to_string())
2996                                        .unwrap_or_else(|e| {
2997                                            debug_panic!(
2998                                                "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
2999                                                rp.pattern,
3000                                                path.display(),
3001                                                e
3002                                            );
3003                                            rp.pattern.clone()
3004                                        });
3005                                    base_uri.push(path);
3006
3007                                    let path = if base_uri.components().next().is_none() {
3008                                        debug_panic!("base_uri is empty, {}", base_uri.display());
3009                                        worktree_root_path.clone()
3010                                    } else {
3011                                        base_uri.into()
3012                                    };
3013                                    PathToWatch::Absolute { path, pattern }
3014                                }
3015                            }
3016                        }
3017                    };
3018                    match path_to_watch {
3019                        PathToWatch::Worktree {
3020                            literal_prefix,
3021                            pattern,
3022                        } => {
3023                            if let Some((tree, glob)) =
3024                                tree.as_local_mut().zip(Glob::new(&pattern).log_err())
3025                            {
3026                                tree.add_path_prefix_to_scan(literal_prefix);
3027                                worktree_globs
3028                                    .entry(tree.id())
3029                                    .or_insert_with(GlobSetBuilder::new)
3030                                    .add(glob);
3031                            } else {
3032                                return false;
3033                            }
3034                        }
3035                        PathToWatch::Absolute { path, pattern } => {
3036                            if let Some(glob) = Glob::new(&pattern).log_err() {
3037                                abs_globs
3038                                    .entry(path)
3039                                    .or_insert_with(GlobSetBuilder::new)
3040                                    .add(glob);
3041                            }
3042                        }
3043                    }
3044                    true
3045                });
3046                if glob_is_inside_worktree {
3047                    log::trace!(
3048                        "Watcher pattern `{}` has been attached to the worktree at `{}`",
3049                        serde_json::to_string(&watcher.glob_pattern).unwrap(),
3050                        worktree.read(cx).abs_path().display()
3051                    );
3052                    found_host = true;
3053                }
3054            }
3055            if !found_host {
3056                log::error!(
3057                    "Watcher pattern `{}` has not been attached to any worktree or absolute path",
3058                    serde_json::to_string(&watcher.glob_pattern).unwrap()
3059                )
3060            }
3061        }
3062
3063        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
3064        for (worktree_id, builder) in worktree_globs {
3065            if let Ok(globset) = builder.build() {
3066                watch_builder.watch_worktree(worktree_id, globset);
3067            }
3068        }
3069        for (abs_path, builder) in abs_globs {
3070            if let Ok(globset) = builder.build() {
3071                watch_builder.watch_abs_path(abs_path, globset);
3072            }
3073        }
3074        watch_builder
3075    }
3076
3077    fn rebuild_watched_paths(
3078        &mut self,
3079        language_server_id: LanguageServerId,
3080        cx: &mut Context<LspStore>,
3081    ) {
3082        let Some(watchers) = self
3083            .language_server_watcher_registrations
3084            .get(&language_server_id)
3085        else {
3086            return;
3087        };
3088
3089        let watch_builder =
3090            self.rebuild_watched_paths_inner(language_server_id, watchers.values().flatten(), cx);
3091        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
3092        self.language_server_watched_paths
3093            .insert(language_server_id, watcher);
3094
3095        cx.notify();
3096    }
3097
3098    fn on_lsp_did_change_watched_files(
3099        &mut self,
3100        language_server_id: LanguageServerId,
3101        registration_id: &str,
3102        params: DidChangeWatchedFilesRegistrationOptions,
3103        cx: &mut Context<LspStore>,
3104    ) {
3105        let registrations = self
3106            .language_server_watcher_registrations
3107            .entry(language_server_id)
3108            .or_default();
3109
3110        registrations.insert(registration_id.to_string(), params.watchers);
3111
3112        self.rebuild_watched_paths(language_server_id, cx);
3113    }
3114
3115    fn on_lsp_unregister_did_change_watched_files(
3116        &mut self,
3117        language_server_id: LanguageServerId,
3118        registration_id: &str,
3119        cx: &mut Context<LspStore>,
3120    ) {
3121        let registrations = self
3122            .language_server_watcher_registrations
3123            .entry(language_server_id)
3124            .or_default();
3125
3126        if registrations.remove(registration_id).is_some() {
3127            log::info!(
3128                    "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
3129                    language_server_id,
3130                    registration_id
3131                );
3132        } else {
3133            log::warn!(
3134                    "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
3135                    language_server_id,
3136                    registration_id
3137                );
3138        }
3139
3140        self.rebuild_watched_paths(language_server_id, cx);
3141    }
3142}
3143
3144#[derive(Debug)]
3145pub struct FormattableBuffer {
3146    handle: Entity<Buffer>,
3147    abs_path: Option<PathBuf>,
3148    env: Option<HashMap<String, String>>,
3149    ranges: Option<Vec<Range<Anchor>>>,
3150}
3151
3152pub struct RemoteLspStore {
3153    upstream_client: Option<AnyProtoClient>,
3154    upstream_project_id: u64,
3155}
3156
3157#[allow(clippy::large_enum_variant)]
3158pub(crate) enum LspStoreMode {
3159    Local(LocalLspStore),   // ssh host and collab host
3160    Remote(RemoteLspStore), // collab guest
3161}
3162
3163impl LspStoreMode {
3164    fn is_local(&self) -> bool {
3165        matches!(self, LspStoreMode::Local(_))
3166    }
3167}
3168
3169pub struct LspStore {
3170    mode: LspStoreMode,
3171    last_formatting_failure: Option<String>,
3172    downstream_client: Option<(AnyProtoClient, u64)>,
3173    nonce: u128,
3174    buffer_store: Entity<BufferStore>,
3175    worktree_store: Entity<WorktreeStore>,
3176    toolchain_store: Option<Entity<ToolchainStore>>,
3177    pub languages: Arc<LanguageRegistry>,
3178    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
3179    active_entry: Option<ProjectEntryId>,
3180    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
3181    _maintain_buffer_languages: Task<()>,
3182    diagnostic_summaries:
3183        HashMap<WorktreeId, HashMap<Arc<Path>, HashMap<LanguageServerId, DiagnosticSummary>>>,
3184}
3185
3186pub enum LspStoreEvent {
3187    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
3188    LanguageServerRemoved(LanguageServerId),
3189    LanguageServerUpdate {
3190        language_server_id: LanguageServerId,
3191        message: proto::update_language_server::Variant,
3192    },
3193    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
3194    LanguageServerPrompt(LanguageServerPromptRequest),
3195    LanguageDetected {
3196        buffer: Entity<Buffer>,
3197        new_language: Option<Arc<Language>>,
3198    },
3199    Notification(String),
3200    RefreshInlayHints,
3201    RefreshCodeLens,
3202    DiagnosticsUpdated {
3203        language_server_id: LanguageServerId,
3204        path: ProjectPath,
3205    },
3206    DiskBasedDiagnosticsStarted {
3207        language_server_id: LanguageServerId,
3208    },
3209    DiskBasedDiagnosticsFinished {
3210        language_server_id: LanguageServerId,
3211    },
3212    SnippetEdit {
3213        buffer_id: BufferId,
3214        edits: Vec<(lsp::Range, Snippet)>,
3215        most_recent_edit: clock::Lamport,
3216    },
3217}
3218
3219#[derive(Clone, Debug, Serialize)]
3220pub struct LanguageServerStatus {
3221    pub name: String,
3222    pub pending_work: BTreeMap<String, LanguageServerProgress>,
3223    pub has_pending_diagnostic_updates: bool,
3224    progress_tokens: HashSet<String>,
3225}
3226
3227#[derive(Clone, Debug)]
3228struct CoreSymbol {
3229    pub language_server_name: LanguageServerName,
3230    pub source_worktree_id: WorktreeId,
3231    pub source_language_server_id: LanguageServerId,
3232    pub path: ProjectPath,
3233    pub name: String,
3234    pub kind: lsp::SymbolKind,
3235    pub range: Range<Unclipped<PointUtf16>>,
3236    pub signature: [u8; 32],
3237}
3238
3239impl LspStore {
3240    pub fn init(client: &AnyProtoClient) {
3241        client.add_entity_request_handler(Self::handle_multi_lsp_query);
3242        client.add_entity_request_handler(Self::handle_restart_language_servers);
3243        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
3244        client.add_entity_message_handler(Self::handle_start_language_server);
3245        client.add_entity_message_handler(Self::handle_update_language_server);
3246        client.add_entity_message_handler(Self::handle_language_server_log);
3247        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
3248        client.add_entity_request_handler(Self::handle_format_buffers);
3249        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
3250        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
3251        client.add_entity_request_handler(Self::handle_apply_code_action);
3252        client.add_entity_request_handler(Self::handle_inlay_hints);
3253        client.add_entity_request_handler(Self::handle_get_project_symbols);
3254        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
3255        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
3256        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
3257        client.add_entity_request_handler(Self::handle_refresh_code_lens);
3258        client.add_entity_request_handler(Self::handle_on_type_formatting);
3259        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
3260        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
3261        client.add_entity_request_handler(Self::handle_rename_project_entry);
3262        client.add_entity_request_handler(Self::handle_lsp_command::<GetCodeActions>);
3263        client.add_entity_request_handler(Self::handle_lsp_command::<GetCompletions>);
3264        client.add_entity_request_handler(Self::handle_lsp_command::<GetHover>);
3265        client.add_entity_request_handler(Self::handle_lsp_command::<GetDefinition>);
3266        client.add_entity_request_handler(Self::handle_lsp_command::<GetDeclaration>);
3267        client.add_entity_request_handler(Self::handle_lsp_command::<GetTypeDefinition>);
3268        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
3269        client.add_entity_request_handler(Self::handle_lsp_command::<GetReferences>);
3270        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
3271        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
3272        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
3273        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
3274    }
3275
3276    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
3277        match &self.mode {
3278            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
3279            _ => None,
3280        }
3281    }
3282
3283    pub fn as_local(&self) -> Option<&LocalLspStore> {
3284        match &self.mode {
3285            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
3286            _ => None,
3287        }
3288    }
3289
3290    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
3291        match &mut self.mode {
3292            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
3293            _ => None,
3294        }
3295    }
3296
3297    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
3298        match &self.mode {
3299            LspStoreMode::Remote(RemoteLspStore {
3300                upstream_client: Some(upstream_client),
3301                upstream_project_id,
3302                ..
3303            }) => Some((upstream_client.clone(), *upstream_project_id)),
3304
3305            LspStoreMode::Remote(RemoteLspStore {
3306                upstream_client: None,
3307                ..
3308            }) => None,
3309            LspStoreMode::Local(_) => None,
3310        }
3311    }
3312
3313    pub fn new_local(
3314        buffer_store: Entity<BufferStore>,
3315        worktree_store: Entity<WorktreeStore>,
3316        prettier_store: Entity<PrettierStore>,
3317        toolchain_store: Entity<ToolchainStore>,
3318        environment: Entity<ProjectEnvironment>,
3319        languages: Arc<LanguageRegistry>,
3320        http_client: Arc<dyn HttpClient>,
3321        fs: Arc<dyn Fs>,
3322        cx: &mut Context<Self>,
3323    ) -> Self {
3324        let yarn = YarnPathStore::new(fs.clone(), cx);
3325        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
3326            .detach();
3327        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
3328            .detach();
3329        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
3330            .detach();
3331        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
3332            .detach();
3333        if let Some(extension_events) = extension::ExtensionEvents::try_global(cx).as_ref() {
3334            cx.subscribe(
3335                extension_events,
3336                Self::reload_zed_json_schemas_on_extensions_changed,
3337            )
3338            .detach();
3339        } else {
3340            log::info!("No extension events global found. Skipping JSON schema auto-reload setup");
3341        }
3342        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
3343            .detach();
3344
3345        let _maintain_workspace_config = {
3346            let (sender, receiver) = watch::channel();
3347            (
3348                Self::maintain_workspace_config(fs.clone(), receiver, cx),
3349                sender,
3350            )
3351        };
3352        let manifest_tree = ManifestTree::new(worktree_store.clone(), cx);
3353        Self {
3354            mode: LspStoreMode::Local(LocalLspStore {
3355                weak: cx.weak_entity(),
3356                worktree_store: worktree_store.clone(),
3357                toolchain_store: toolchain_store.clone(),
3358                supplementary_language_servers: Default::default(),
3359                languages: languages.clone(),
3360                language_server_ids: Default::default(),
3361                language_servers: Default::default(),
3362                last_workspace_edits_by_language_server: Default::default(),
3363                language_server_watched_paths: Default::default(),
3364                language_server_paths_watched_for_rename: Default::default(),
3365                language_server_watcher_registrations: Default::default(),
3366                buffers_being_formatted: Default::default(),
3367                buffer_snapshots: Default::default(),
3368                prettier_store,
3369                environment,
3370                http_client,
3371                fs,
3372                yarn,
3373                next_diagnostic_group_id: Default::default(),
3374                diagnostics: Default::default(),
3375                _subscription: cx.on_app_quit(|this, cx| {
3376                    this.as_local_mut().unwrap().shutdown_language_servers(cx)
3377                }),
3378                lsp_tree: LanguageServerTree::new(manifest_tree, languages.clone(), cx),
3379                registered_buffers: Default::default(),
3380            }),
3381            last_formatting_failure: None,
3382            downstream_client: None,
3383            buffer_store,
3384            worktree_store,
3385            toolchain_store: Some(toolchain_store),
3386            languages: languages.clone(),
3387            language_server_statuses: Default::default(),
3388            nonce: StdRng::from_entropy().gen(),
3389            diagnostic_summaries: Default::default(),
3390            active_entry: None,
3391
3392            _maintain_workspace_config,
3393            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
3394        }
3395    }
3396
3397    fn send_lsp_proto_request<R: LspCommand>(
3398        &self,
3399        buffer: Entity<Buffer>,
3400        client: AnyProtoClient,
3401        upstream_project_id: u64,
3402        request: R,
3403        cx: &mut Context<'_, LspStore>,
3404    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
3405        let message = request.to_proto(upstream_project_id, buffer.read(cx));
3406        cx.spawn(async move |this, cx| {
3407            let response = client.request(message).await?;
3408            let this = this.upgrade().context("project dropped")?;
3409            request
3410                .response_from_proto(response, this, buffer, cx.clone())
3411                .await
3412        })
3413    }
3414
3415    pub(super) fn new_remote(
3416        buffer_store: Entity<BufferStore>,
3417        worktree_store: Entity<WorktreeStore>,
3418        toolchain_store: Option<Entity<ToolchainStore>>,
3419        languages: Arc<LanguageRegistry>,
3420        upstream_client: AnyProtoClient,
3421        project_id: u64,
3422        fs: Arc<dyn Fs>,
3423        cx: &mut Context<Self>,
3424    ) -> Self {
3425        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
3426            .detach();
3427        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
3428            .detach();
3429        let _maintain_workspace_config = {
3430            let (sender, receiver) = watch::channel();
3431            (Self::maintain_workspace_config(fs, receiver, cx), sender)
3432        };
3433        Self {
3434            mode: LspStoreMode::Remote(RemoteLspStore {
3435                upstream_client: Some(upstream_client),
3436                upstream_project_id: project_id,
3437            }),
3438            downstream_client: None,
3439            last_formatting_failure: None,
3440            buffer_store,
3441            worktree_store,
3442            languages: languages.clone(),
3443            language_server_statuses: Default::default(),
3444            nonce: StdRng::from_entropy().gen(),
3445            diagnostic_summaries: Default::default(),
3446            active_entry: None,
3447            toolchain_store,
3448            _maintain_workspace_config,
3449            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
3450        }
3451    }
3452
3453    fn on_buffer_store_event(
3454        &mut self,
3455        _: Entity<BufferStore>,
3456        event: &BufferStoreEvent,
3457        cx: &mut Context<Self>,
3458    ) {
3459        match event {
3460            BufferStoreEvent::BufferAdded(buffer) => {
3461                self.on_buffer_added(buffer, cx).log_err();
3462            }
3463            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
3464                let buffer_id = buffer.read(cx).remote_id();
3465                if let Some(local) = self.as_local_mut() {
3466                    if let Some(old_file) = File::from_dyn(old_file.as_ref()) {
3467                        local.reset_buffer(buffer, old_file, cx);
3468
3469                        if local.registered_buffers.contains_key(&buffer_id) {
3470                            local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
3471                        }
3472                    }
3473                }
3474
3475                self.detect_language_for_buffer(buffer, cx);
3476                if let Some(local) = self.as_local_mut() {
3477                    local.initialize_buffer(buffer, cx);
3478                    if local.registered_buffers.contains_key(&buffer_id) {
3479                        local.register_buffer_with_language_servers(buffer, cx);
3480                    }
3481                }
3482            }
3483            _ => {}
3484        }
3485    }
3486
3487    fn on_worktree_store_event(
3488        &mut self,
3489        _: Entity<WorktreeStore>,
3490        event: &WorktreeStoreEvent,
3491        cx: &mut Context<Self>,
3492    ) {
3493        match event {
3494            WorktreeStoreEvent::WorktreeAdded(worktree) => {
3495                if !worktree.read(cx).is_local() {
3496                    return;
3497                }
3498                cx.subscribe(worktree, |this, worktree, event, cx| match event {
3499                    worktree::Event::UpdatedEntries(changes) => {
3500                        this.update_local_worktree_language_servers(&worktree, changes, cx);
3501                    }
3502                    worktree::Event::UpdatedGitRepositories(_)
3503                    | worktree::Event::DeletedEntry(_) => {}
3504                })
3505                .detach()
3506            }
3507            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
3508            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
3509                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
3510            }
3511            WorktreeStoreEvent::WorktreeReleased(..)
3512            | WorktreeStoreEvent::WorktreeOrderChanged
3513            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
3514            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
3515            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
3516        }
3517    }
3518
3519    fn on_prettier_store_event(
3520        &mut self,
3521        _: Entity<PrettierStore>,
3522        event: &PrettierStoreEvent,
3523        cx: &mut Context<Self>,
3524    ) {
3525        match event {
3526            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
3527                self.unregister_supplementary_language_server(*prettier_server_id, cx);
3528            }
3529            PrettierStoreEvent::LanguageServerAdded {
3530                new_server_id,
3531                name,
3532                prettier_server,
3533            } => {
3534                self.register_supplementary_language_server(
3535                    *new_server_id,
3536                    name.clone(),
3537                    prettier_server.clone(),
3538                    cx,
3539                );
3540            }
3541        }
3542    }
3543
3544    fn on_toolchain_store_event(
3545        &mut self,
3546        _: Entity<ToolchainStore>,
3547        event: &ToolchainStoreEvent,
3548        _: &mut Context<Self>,
3549    ) {
3550        match event {
3551            ToolchainStoreEvent::ToolchainActivated { .. } => {
3552                self.request_workspace_config_refresh()
3553            }
3554        }
3555    }
3556
3557    fn request_workspace_config_refresh(&mut self) {
3558        *self._maintain_workspace_config.1.borrow_mut() = ();
3559    }
3560
3561    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
3562        self.as_local().map(|local| local.prettier_store.clone())
3563    }
3564
3565    fn on_buffer_event(
3566        &mut self,
3567        buffer: Entity<Buffer>,
3568        event: &language::BufferEvent,
3569        cx: &mut Context<Self>,
3570    ) {
3571        match event {
3572            language::BufferEvent::Edited { .. } => {
3573                self.on_buffer_edited(buffer, cx);
3574            }
3575
3576            language::BufferEvent::Saved => {
3577                self.on_buffer_saved(buffer, cx);
3578            }
3579
3580            _ => {}
3581        }
3582    }
3583
3584    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
3585        buffer.update(cx, |buffer, _| {
3586            buffer.set_language_registry(self.languages.clone())
3587        });
3588
3589        cx.subscribe(buffer, |this, buffer, event, cx| {
3590            this.on_buffer_event(buffer, event, cx);
3591        })
3592        .detach();
3593
3594        self.detect_language_for_buffer(buffer, cx);
3595        if let Some(local) = self.as_local_mut() {
3596            local.initialize_buffer(buffer, cx);
3597        }
3598
3599        Ok(())
3600    }
3601
3602    pub fn reload_zed_json_schemas_on_extensions_changed(
3603        &mut self,
3604        _: Entity<extension::ExtensionEvents>,
3605        evt: &extension::Event,
3606        cx: &mut Context<Self>,
3607    ) {
3608        #[expect(
3609            irrefutable_let_patterns,
3610            reason = "Make sure to handle new event types in extension properly"
3611        )]
3612        let extension::Event::ExtensionsInstalledChanged = evt
3613        else {
3614            return;
3615        };
3616        if self.as_local().is_none() {
3617            return;
3618        }
3619        cx.spawn(async move |this, cx| {
3620            let weak_ref = this.clone();
3621
3622            let servers = this
3623                .update(cx, |this, cx| {
3624                    let local = this.as_local()?;
3625
3626                    let mut servers = Vec::new();
3627                    for ((worktree_id, _), server_ids) in &local.language_server_ids {
3628                        for server_id in server_ids {
3629                            let Some(states) = local.language_servers.get(server_id) else {
3630                                continue;
3631                            };
3632                            let (json_adapter, json_server) = match states {
3633                                LanguageServerState::Running {
3634                                    adapter, server, ..
3635                                } if adapter.adapter.is_primary_zed_json_schema_adapter() => {
3636                                    (adapter.adapter.clone(), server.clone())
3637                                }
3638                                _ => continue,
3639                            };
3640
3641                            let Some(worktree) = this
3642                                .worktree_store
3643                                .read(cx)
3644                                .worktree_for_id(*worktree_id, cx)
3645                            else {
3646                                continue;
3647                            };
3648                            let json_delegate: Arc<dyn LspAdapterDelegate> =
3649                                LocalLspAdapterDelegate::new(
3650                                    local.languages.clone(),
3651                                    &local.environment,
3652                                    weak_ref.clone(),
3653                                    &worktree,
3654                                    local.http_client.clone(),
3655                                    local.fs.clone(),
3656                                    cx,
3657                                );
3658
3659                            servers.push((json_adapter, json_server, json_delegate));
3660                        }
3661                    }
3662                    return Some(servers);
3663                })
3664                .ok()
3665                .flatten();
3666
3667            let Some(servers) = servers else {
3668                return;
3669            };
3670
3671            let Ok(Some((fs, toolchain_store))) = this.read_with(cx, |this, cx| {
3672                let local = this.as_local()?;
3673                let toolchain_store = this.toolchain_store(cx);
3674                return Some((local.fs.clone(), toolchain_store));
3675            }) else {
3676                return;
3677            };
3678            for (adapter, server, delegate) in servers {
3679                adapter.clear_zed_json_schema_cache().await;
3680
3681                let Some(json_workspace_config) = adapter
3682                    .workspace_configuration(
3683                        fs.as_ref(),
3684                        &delegate,
3685                        toolchain_store.clone(),
3686                        cx,
3687                    )
3688                    .await
3689                    .context("generate new workspace configuration for JSON language server while trying to refresh JSON Schemas")
3690                    .ok()
3691                else {
3692                    continue;
3693                };
3694                server
3695                    .notify::<lsp::notification::DidChangeConfiguration>(
3696                        &lsp::DidChangeConfigurationParams {
3697                            settings: json_workspace_config,
3698                        },
3699                    )
3700                    .ok();
3701            }
3702        })
3703        .detach();
3704    }
3705
3706    pub(crate) fn register_buffer_with_language_servers(
3707        &mut self,
3708        buffer: &Entity<Buffer>,
3709        ignore_refcounts: bool,
3710        cx: &mut Context<Self>,
3711    ) -> OpenLspBufferHandle {
3712        let buffer_id = buffer.read(cx).remote_id();
3713        let handle = cx.new(|_| buffer.clone());
3714        if let Some(local) = self.as_local_mut() {
3715            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
3716                return handle;
3717            };
3718            if !file.is_local() {
3719                return handle;
3720            }
3721
3722            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
3723            if !ignore_refcounts {
3724                *refcount += 1;
3725            }
3726
3727            if !ignore_refcounts || *refcount == 1 {
3728                local.register_buffer_with_language_servers(buffer, cx);
3729            }
3730            if !ignore_refcounts {
3731                cx.observe_release(&handle, move |this, buffer, cx| {
3732                    let local = this.as_local_mut().unwrap();
3733                    let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
3734                        debug_panic!("bad refcounting");
3735                        return;
3736                    };
3737
3738                    *refcount -= 1;
3739                    if *refcount == 0 {
3740                        local.registered_buffers.remove(&buffer_id);
3741                        if let Some(file) = File::from_dyn(buffer.read(cx).file()).cloned() {
3742                            local.unregister_old_buffer_from_language_servers(&buffer, &file, cx);
3743                        }
3744                    }
3745                })
3746                .detach();
3747            }
3748        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
3749            let buffer_id = buffer.read(cx).remote_id().to_proto();
3750            cx.background_spawn(async move {
3751                upstream_client
3752                    .request(proto::RegisterBufferWithLanguageServers {
3753                        project_id: upstream_project_id,
3754                        buffer_id,
3755                    })
3756                    .await
3757            })
3758            .detach();
3759        } else {
3760            panic!("oops!");
3761        }
3762        handle
3763    }
3764
3765    fn maintain_buffer_languages(
3766        languages: Arc<LanguageRegistry>,
3767        cx: &mut Context<Self>,
3768    ) -> Task<()> {
3769        let mut subscription = languages.subscribe();
3770        let mut prev_reload_count = languages.reload_count();
3771        cx.spawn(async move |this, cx| {
3772            while let Some(()) = subscription.next().await {
3773                if let Some(this) = this.upgrade() {
3774                    // If the language registry has been reloaded, then remove and
3775                    // re-assign the languages on all open buffers.
3776                    let reload_count = languages.reload_count();
3777                    if reload_count > prev_reload_count {
3778                        prev_reload_count = reload_count;
3779                        this.update(cx, |this, cx| {
3780                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
3781                                for buffer in buffer_store.buffers() {
3782                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
3783                                    {
3784                                        buffer
3785                                            .update(cx, |buffer, cx| buffer.set_language(None, cx));
3786                                        if let Some(local) = this.as_local_mut() {
3787                                            local.reset_buffer(&buffer, &f, cx);
3788
3789                                            if local
3790                                                .registered_buffers
3791                                                .contains_key(&buffer.read(cx).remote_id())
3792                                            {
3793                                                if let Some(file_url) =
3794                                                    lsp::Url::from_file_path(&f.abs_path(cx))
3795                                                        .log_err()
3796                                                {
3797                                                    local.unregister_buffer_from_language_servers(
3798                                                        &buffer, &file_url, cx,
3799                                                    );
3800                                                }
3801                                            }
3802                                        }
3803                                    }
3804                                }
3805                            });
3806                        })
3807                        .ok();
3808                    }
3809
3810                    this.update(cx, |this, cx| {
3811                        let mut plain_text_buffers = Vec::new();
3812                        let mut buffers_with_unknown_injections = Vec::new();
3813                        for handle in this.buffer_store.read(cx).buffers() {
3814                            let buffer = handle.read(cx);
3815                            if buffer.language().is_none()
3816                                || buffer.language() == Some(&*language::PLAIN_TEXT)
3817                            {
3818                                plain_text_buffers.push(handle);
3819                            } else if buffer.contains_unknown_injections() {
3820                                buffers_with_unknown_injections.push(handle);
3821                            }
3822                        }
3823                        for buffer in plain_text_buffers {
3824                            this.detect_language_for_buffer(&buffer, cx);
3825                            if let Some(local) = this.as_local_mut() {
3826                                local.initialize_buffer(&buffer, cx);
3827                                if local
3828                                    .registered_buffers
3829                                    .contains_key(&buffer.read(cx).remote_id())
3830                                {
3831                                    local.register_buffer_with_language_servers(&buffer, cx);
3832                                }
3833                            }
3834                        }
3835
3836                        for buffer in buffers_with_unknown_injections {
3837                            buffer.update(cx, |buffer, cx| buffer.reparse(cx));
3838                        }
3839                    })
3840                    .ok();
3841                }
3842            }
3843        })
3844    }
3845
3846    fn detect_language_for_buffer(
3847        &mut self,
3848        buffer_handle: &Entity<Buffer>,
3849        cx: &mut Context<Self>,
3850    ) -> Option<language::AvailableLanguage> {
3851        // If the buffer has a language, set it and start the language server if we haven't already.
3852        let buffer = buffer_handle.read(cx);
3853        let file = buffer.file()?;
3854
3855        let content = buffer.as_rope();
3856        let available_language = self.languages.language_for_file(file, Some(content), cx);
3857        if let Some(available_language) = &available_language {
3858            if let Some(Ok(Ok(new_language))) = self
3859                .languages
3860                .load_language(available_language)
3861                .now_or_never()
3862            {
3863                self.set_language_for_buffer(buffer_handle, new_language, cx);
3864            }
3865        } else {
3866            cx.emit(LspStoreEvent::LanguageDetected {
3867                buffer: buffer_handle.clone(),
3868                new_language: None,
3869            });
3870        }
3871
3872        available_language
3873    }
3874
3875    pub(crate) fn set_language_for_buffer(
3876        &mut self,
3877        buffer_entity: &Entity<Buffer>,
3878        new_language: Arc<Language>,
3879        cx: &mut Context<Self>,
3880    ) {
3881        let buffer = buffer_entity.read(cx);
3882        let buffer_file = buffer.file().cloned();
3883        let buffer_id = buffer.remote_id();
3884        if let Some(local_store) = self.as_local_mut() {
3885            if local_store.registered_buffers.contains_key(&buffer_id) {
3886                if let Some(abs_path) =
3887                    File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
3888                {
3889                    if let Some(file_url) = lsp::Url::from_file_path(&abs_path).log_err() {
3890                        local_store.unregister_buffer_from_language_servers(
3891                            buffer_entity,
3892                            &file_url,
3893                            cx,
3894                        );
3895                    }
3896                }
3897            }
3898        }
3899        buffer_entity.update(cx, |buffer, cx| {
3900            if buffer.language().map_or(true, |old_language| {
3901                !Arc::ptr_eq(old_language, &new_language)
3902            }) {
3903                buffer.set_language(Some(new_language.clone()), cx);
3904            }
3905        });
3906
3907        let settings =
3908            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
3909        let buffer_file = File::from_dyn(buffer_file.as_ref());
3910
3911        let worktree_id = if let Some(file) = buffer_file {
3912            let worktree = file.worktree.clone();
3913
3914            if let Some(local) = self.as_local_mut() {
3915                if local.registered_buffers.contains_key(&buffer_id) {
3916                    local.register_buffer_with_language_servers(buffer_entity, cx);
3917                }
3918            }
3919            Some(worktree.read(cx).id())
3920        } else {
3921            None
3922        };
3923
3924        if settings.prettier.allowed {
3925            if let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
3926            {
3927                let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
3928                if let Some(prettier_store) = prettier_store {
3929                    prettier_store.update(cx, |prettier_store, cx| {
3930                        prettier_store.install_default_prettier(
3931                            worktree_id,
3932                            prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
3933                            cx,
3934                        )
3935                    })
3936                }
3937            }
3938        }
3939
3940        cx.emit(LspStoreEvent::LanguageDetected {
3941            buffer: buffer_entity.clone(),
3942            new_language: Some(new_language),
3943        })
3944    }
3945
3946    pub fn buffer_store(&self) -> Entity<BufferStore> {
3947        self.buffer_store.clone()
3948    }
3949
3950    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
3951        self.active_entry = active_entry;
3952    }
3953
3954    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
3955        if let Some((client, downstream_project_id)) = self.downstream_client.clone() {
3956            if let Some(summaries) = self.diagnostic_summaries.get(&worktree.id()) {
3957                for (path, summaries) in summaries {
3958                    for (&server_id, summary) in summaries {
3959                        client
3960                            .send(proto::UpdateDiagnosticSummary {
3961                                project_id: downstream_project_id,
3962                                worktree_id: worktree.id().to_proto(),
3963                                summary: Some(summary.to_proto(server_id, path)),
3964                            })
3965                            .log_err();
3966                    }
3967                }
3968            }
3969        }
3970    }
3971
3972    pub fn request_lsp<R: LspCommand>(
3973        &mut self,
3974        buffer_handle: Entity<Buffer>,
3975        server: LanguageServerToQuery,
3976        request: R,
3977        cx: &mut Context<Self>,
3978    ) -> Task<Result<R::Response>>
3979    where
3980        <R::LspRequest as lsp::request::Request>::Result: Send,
3981        <R::LspRequest as lsp::request::Request>::Params: Send,
3982    {
3983        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
3984            return self.send_lsp_proto_request(
3985                buffer_handle,
3986                upstream_client,
3987                upstream_project_id,
3988                request,
3989                cx,
3990            );
3991        }
3992
3993        let Some(language_server) = buffer_handle.update(cx, |buffer, cx| match server {
3994            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
3995                local
3996                    .language_servers_for_buffer(buffer, cx)
3997                    .find(|(_, server)| {
3998                        request.check_capabilities(server.adapter_server_capabilities())
3999                    })
4000                    .map(|(_, server)| server.clone())
4001            }),
4002            LanguageServerToQuery::Other(id) => self
4003                .language_server_for_local_buffer(buffer, id, cx)
4004                .and_then(|(_, server)| {
4005                    request
4006                        .check_capabilities(server.adapter_server_capabilities())
4007                        .then(|| Arc::clone(server))
4008                }),
4009        }) else {
4010            return Task::ready(Ok(Default::default()));
4011        };
4012
4013        let buffer = buffer_handle.read(cx);
4014        let file = File::from_dyn(buffer.file()).and_then(File::as_local);
4015
4016        let Some(file) = file else {
4017            return Task::ready(Ok(Default::default()));
4018        };
4019
4020        let lsp_params = match request.to_lsp_params_or_response(
4021            &file.abs_path(cx),
4022            buffer,
4023            &language_server,
4024            cx,
4025        ) {
4026            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
4027            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
4028
4029            Err(err) => {
4030                let message = format!(
4031                    "{} via {} failed: {}",
4032                    request.display_name(),
4033                    language_server.name(),
4034                    err
4035                );
4036                log::warn!("{}", message);
4037                return Task::ready(Err(anyhow!(message)));
4038            }
4039        };
4040
4041        let status = request.status();
4042        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
4043            return Task::ready(Ok(Default::default()));
4044        }
4045        return cx.spawn(async move |this, cx| {
4046            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
4047
4048            let id = lsp_request.id();
4049            let _cleanup = if status.is_some() {
4050                cx.update(|cx| {
4051                    this.update(cx, |this, cx| {
4052                        this.on_lsp_work_start(
4053                            language_server.server_id(),
4054                            id.to_string(),
4055                            LanguageServerProgress {
4056                                is_disk_based_diagnostics_progress: false,
4057                                is_cancellable: false,
4058                                title: None,
4059                                message: status.clone(),
4060                                percentage: None,
4061                                last_update_at: cx.background_executor().now(),
4062                            },
4063                            cx,
4064                        );
4065                    })
4066                })
4067                .log_err();
4068
4069                Some(defer(|| {
4070                    cx.update(|cx| {
4071                        this.update(cx, |this, cx| {
4072                            this.on_lsp_work_end(language_server.server_id(), id.to_string(), cx);
4073                        })
4074                    })
4075                    .log_err();
4076                }))
4077            } else {
4078                None
4079            };
4080
4081            let result = lsp_request.await;
4082
4083            let response = result.map_err(|err| {
4084                let message = format!(
4085                    "{} via {} failed: {}",
4086                    request.display_name(),
4087                    language_server.name(),
4088                    err
4089                );
4090                log::warn!("{}", message);
4091                anyhow!(message)
4092            })?;
4093
4094            let response = request
4095                .response_from_lsp(
4096                    response,
4097                    this.upgrade().ok_or_else(|| anyhow!("no app context"))?,
4098                    buffer_handle,
4099                    language_server.server_id(),
4100                    cx.clone(),
4101                )
4102                .await;
4103            response
4104        });
4105    }
4106
4107    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
4108        let mut language_formatters_to_check = Vec::new();
4109        for buffer in self.buffer_store.read(cx).buffers() {
4110            let buffer = buffer.read(cx);
4111            let buffer_file = File::from_dyn(buffer.file());
4112            let buffer_language = buffer.language();
4113            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
4114            if buffer_language.is_some() {
4115                language_formatters_to_check.push((
4116                    buffer_file.map(|f| f.worktree_id(cx)),
4117                    settings.into_owned(),
4118                ));
4119            }
4120        }
4121
4122        self.refresh_server_tree(cx);
4123
4124        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
4125            prettier_store.update(cx, |prettier_store, cx| {
4126                prettier_store.on_settings_changed(language_formatters_to_check, cx)
4127            })
4128        }
4129
4130        cx.notify();
4131    }
4132
4133    fn refresh_server_tree(&mut self, cx: &mut Context<'_, Self>) {
4134        let buffer_store = self.buffer_store.clone();
4135        if let Some(local) = self.as_local_mut() {
4136            let mut adapters = BTreeMap::default();
4137            let to_stop = local.lsp_tree.clone().update(cx, |lsp_tree, cx| {
4138                let get_adapter = {
4139                    let languages = local.languages.clone();
4140                    let environment = local.environment.clone();
4141                    let weak = local.weak.clone();
4142                    let worktree_store = local.worktree_store.clone();
4143                    let http_client = local.http_client.clone();
4144                    let fs = local.fs.clone();
4145                    move |worktree_id, cx: &mut App| {
4146                        let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
4147                        Some(LocalLspAdapterDelegate::new(
4148                            languages.clone(),
4149                            &environment,
4150                            weak.clone(),
4151                            &worktree,
4152                            http_client.clone(),
4153                            fs.clone(),
4154                            cx,
4155                        ))
4156                    }
4157                };
4158
4159                let mut rebase = lsp_tree.rebase();
4160                for buffer in buffer_store.read(cx).buffers().collect::<Vec<_>>() {
4161                    let buffer = buffer.read(cx);
4162                    if !local.registered_buffers.contains_key(&buffer.remote_id()) {
4163                        continue;
4164                    }
4165                    if let Some((file, language)) = File::from_dyn(buffer.file())
4166                        .cloned()
4167                        .zip(buffer.language().map(|l| l.name()))
4168                    {
4169                        let worktree_id = file.worktree_id(cx);
4170                        let Some(worktree) = local
4171                            .worktree_store
4172                            .read(cx)
4173                            .worktree_for_id(worktree_id, cx)
4174                        else {
4175                            continue;
4176                        };
4177                        let path: Arc<Path> = file
4178                            .path()
4179                            .parent()
4180                            .map(Arc::from)
4181                            .unwrap_or_else(|| file.path().clone());
4182                        let worktree_path = ProjectPath { worktree_id, path };
4183
4184                        let Some(delegate) = adapters
4185                            .entry(worktree_id)
4186                            .or_insert_with(|| get_adapter(worktree_id, cx))
4187                            .clone()
4188                        else {
4189                            continue;
4190                        };
4191                        let nodes = rebase.get(
4192                            worktree_path,
4193                            AdapterQuery::Language(&language),
4194                            delegate.clone(),
4195                            cx,
4196                        );
4197                        for node in nodes {
4198                            node.server_id_or_init(
4199                                |LaunchDisposition {
4200                                     server_name,
4201                                     attach,
4202                                     path,
4203                                     settings,
4204                                 }| match attach {
4205                                    language::Attach::InstancePerRoot => {
4206                                        // todo: handle instance per root proper.
4207                                        if let Some(server_ids) = local
4208                                            .language_server_ids
4209                                            .get(&(worktree_id, server_name.clone()))
4210                                        {
4211                                            server_ids.iter().cloned().next().unwrap()
4212                                        } else {
4213                                            local.start_language_server(
4214                                                &worktree,
4215                                                delegate.clone(),
4216                                                local
4217                                                    .languages
4218                                                    .lsp_adapters(&language)
4219                                                    .into_iter()
4220                                                    .find(|adapter| &adapter.name() == server_name)
4221                                                    .expect("To find LSP adapter"),
4222                                                settings,
4223                                                cx,
4224                                            )
4225                                        }
4226                                    }
4227                                    language::Attach::Shared => {
4228                                        let uri = Url::from_file_path(
4229                                            worktree.read(cx).abs_path().join(&path.path),
4230                                        );
4231                                        let key = (worktree_id, server_name.clone());
4232                                        local.language_server_ids.remove(&key);
4233
4234                                        let server_id = local.start_language_server(
4235                                            &worktree,
4236                                            delegate.clone(),
4237                                            local
4238                                                .languages
4239                                                .lsp_adapters(&language)
4240                                                .into_iter()
4241                                                .find(|adapter| &adapter.name() == server_name)
4242                                                .expect("To find LSP adapter"),
4243                                            settings,
4244                                            cx,
4245                                        );
4246                                        if let Some(state) = local.language_servers.get(&server_id)
4247                                        {
4248                                            if let Ok(uri) = uri {
4249                                                state.add_workspace_folder(uri);
4250                                            };
4251                                        }
4252                                        server_id
4253                                    }
4254                                },
4255                            );
4256                        }
4257                    }
4258                }
4259                rebase.finish()
4260            });
4261            for (id, name) in to_stop {
4262                self.stop_local_language_server(id, name, cx).detach();
4263            }
4264        }
4265    }
4266
4267    pub fn apply_code_action(
4268        &self,
4269        buffer_handle: Entity<Buffer>,
4270        mut action: CodeAction,
4271        push_to_history: bool,
4272        cx: &mut Context<Self>,
4273    ) -> Task<Result<ProjectTransaction>> {
4274        if let Some((upstream_client, project_id)) = self.upstream_client() {
4275            let request = proto::ApplyCodeAction {
4276                project_id,
4277                buffer_id: buffer_handle.read(cx).remote_id().into(),
4278                action: Some(Self::serialize_code_action(&action)),
4279            };
4280            let buffer_store = self.buffer_store();
4281            cx.spawn(async move |_, cx| {
4282                let response = upstream_client
4283                    .request(request)
4284                    .await?
4285                    .transaction
4286                    .ok_or_else(|| anyhow!("missing transaction"))?;
4287
4288                buffer_store
4289                    .update(cx, |buffer_store, cx| {
4290                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
4291                    })?
4292                    .await
4293            })
4294        } else if self.mode.is_local() {
4295            let Some((lsp_adapter, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
4296                self.language_server_for_local_buffer(buffer, action.server_id, cx)
4297                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
4298            }) else {
4299                return Task::ready(Ok(ProjectTransaction::default()));
4300            };
4301            cx.spawn(async move |this,  cx| {
4302                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
4303                    .await
4304                    .context("resolving a code action")?;
4305                if let Some(edit) = action.lsp_action.edit() {
4306                    if edit.changes.is_some() || edit.document_changes.is_some() {
4307                        return LocalLspStore::deserialize_workspace_edit(
4308                            this.upgrade().ok_or_else(|| anyhow!("no app present"))?,
4309                            edit.clone(),
4310                            push_to_history,
4311                            lsp_adapter.clone(),
4312                            lang_server.clone(),
4313                            cx,
4314                        )
4315                        .await;
4316                    }
4317                }
4318
4319                if let Some(command) = action.lsp_action.command() {
4320                    let server_capabilities = lang_server.capabilities();
4321                    let available_commands = server_capabilities
4322                        .execute_command_provider
4323                        .as_ref()
4324                        .map(|options| options.commands.as_slice())
4325                        .unwrap_or_default();
4326                    if available_commands.contains(&command.command) {
4327                        this.update(cx, |this, _| {
4328                            this.as_local_mut()
4329                                .unwrap()
4330                                .last_workspace_edits_by_language_server
4331                                .remove(&lang_server.server_id());
4332                        })?;
4333
4334                        let result = lang_server
4335                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
4336                                command: command.command.clone(),
4337                                arguments: command.arguments.clone().unwrap_or_default(),
4338                                ..Default::default()
4339                            })
4340                            .await;
4341
4342                        result?;
4343
4344                        return this.update(cx, |this, _| {
4345                            this.as_local_mut()
4346                                .unwrap()
4347                                .last_workspace_edits_by_language_server
4348                                .remove(&lang_server.server_id())
4349                                .unwrap_or_default()
4350                        });
4351                    } else {
4352                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
4353                    }
4354                }
4355
4356                Ok(ProjectTransaction::default())
4357            })
4358        } else {
4359            Task::ready(Err(anyhow!("no upstream client and not local")))
4360        }
4361    }
4362
4363    pub fn apply_code_action_kind(
4364        &mut self,
4365        buffers: HashSet<Entity<Buffer>>,
4366        kind: CodeActionKind,
4367        push_to_history: bool,
4368        cx: &mut Context<Self>,
4369    ) -> Task<anyhow::Result<ProjectTransaction>> {
4370        if let Some(_) = self.as_local() {
4371            cx.spawn(async move |lsp_store, cx| {
4372                let buffers = buffers.into_iter().collect::<Vec<_>>();
4373                let result = LocalLspStore::execute_code_action_kind_locally(
4374                    lsp_store.clone(),
4375                    buffers,
4376                    kind,
4377                    push_to_history,
4378                    cx,
4379                )
4380                .await;
4381                lsp_store.update(cx, |lsp_store, _| {
4382                    lsp_store.update_last_formatting_failure(&result);
4383                })?;
4384                result
4385            })
4386        } else if let Some((client, project_id)) = self.upstream_client() {
4387            let buffer_store = self.buffer_store();
4388            cx.spawn(async move |lsp_store, cx| {
4389                let result = client
4390                    .request(proto::ApplyCodeActionKind {
4391                        project_id,
4392                        kind: kind.as_str().to_owned(),
4393                        buffer_ids: buffers
4394                            .iter()
4395                            .map(|buffer| buffer.update(cx, |buffer, _| buffer.remote_id().into()))
4396                            .collect::<Result<_>>()?,
4397                    })
4398                    .await
4399                    .and_then(|result| result.transaction.context("missing transaction"));
4400                lsp_store.update(cx, |lsp_store, _| {
4401                    lsp_store.update_last_formatting_failure(&result);
4402                })?;
4403
4404                let transaction_response = result?;
4405                buffer_store
4406                    .update(cx, |buffer_store, cx| {
4407                        buffer_store.deserialize_project_transaction(
4408                            transaction_response,
4409                            push_to_history,
4410                            cx,
4411                        )
4412                    })?
4413                    .await
4414            })
4415        } else {
4416            Task::ready(Ok(ProjectTransaction::default()))
4417        }
4418    }
4419
4420    pub fn resolve_inlay_hint(
4421        &self,
4422        hint: InlayHint,
4423        buffer_handle: Entity<Buffer>,
4424        server_id: LanguageServerId,
4425        cx: &mut Context<Self>,
4426    ) -> Task<anyhow::Result<InlayHint>> {
4427        if let Some((upstream_client, project_id)) = self.upstream_client() {
4428            let request = proto::ResolveInlayHint {
4429                project_id,
4430                buffer_id: buffer_handle.read(cx).remote_id().into(),
4431                language_server_id: server_id.0 as u64,
4432                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
4433            };
4434            cx.spawn(async move |_, _| {
4435                let response = upstream_client
4436                    .request(request)
4437                    .await
4438                    .context("inlay hints proto request")?;
4439                match response.hint {
4440                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
4441                        .context("inlay hints proto resolve response conversion"),
4442                    None => Ok(hint),
4443                }
4444            })
4445        } else {
4446            let Some(lang_server) = buffer_handle.update(cx, |buffer, cx| {
4447                self.language_server_for_local_buffer(buffer, server_id, cx)
4448                    .map(|(_, server)| server.clone())
4449            }) else {
4450                return Task::ready(Ok(hint));
4451            };
4452            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
4453                return Task::ready(Ok(hint));
4454            }
4455            let buffer_snapshot = buffer_handle.read(cx).snapshot();
4456            cx.spawn(async move |_, cx| {
4457                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
4458                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
4459                );
4460                let resolved_hint = resolve_task
4461                    .await
4462                    .context("inlay hint resolve LSP request")?;
4463                let resolved_hint = InlayHints::lsp_to_project_hint(
4464                    resolved_hint,
4465                    &buffer_handle,
4466                    server_id,
4467                    ResolveState::Resolved,
4468                    false,
4469                    cx,
4470                )
4471                .await?;
4472                Ok(resolved_hint)
4473            })
4474        }
4475    }
4476
4477    pub(crate) fn linked_edit(
4478        &mut self,
4479        buffer: &Entity<Buffer>,
4480        position: Anchor,
4481        cx: &mut Context<Self>,
4482    ) -> Task<Result<Vec<Range<Anchor>>>> {
4483        let snapshot = buffer.read(cx).snapshot();
4484        let scope = snapshot.language_scope_at(position);
4485        let Some(server_id) = self
4486            .as_local()
4487            .and_then(|local| {
4488                buffer.update(cx, |buffer, cx| {
4489                    local
4490                        .language_servers_for_buffer(buffer, cx)
4491                        .filter(|(_, server)| {
4492                            server
4493                                .capabilities()
4494                                .linked_editing_range_provider
4495                                .is_some()
4496                        })
4497                        .filter(|(adapter, _)| {
4498                            scope
4499                                .as_ref()
4500                                .map(|scope| scope.language_allowed(&adapter.name))
4501                                .unwrap_or(true)
4502                        })
4503                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
4504                        .next()
4505                })
4506            })
4507            .or_else(|| {
4508                self.upstream_client()
4509                    .is_some()
4510                    .then_some(LanguageServerToQuery::FirstCapable)
4511            })
4512            .filter(|_| {
4513                maybe!({
4514                    let language = buffer.read(cx).language_at(position)?;
4515                    Some(
4516                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
4517                            .linked_edits,
4518                    )
4519                }) == Some(true)
4520            })
4521        else {
4522            return Task::ready(Ok(vec![]));
4523        };
4524
4525        self.request_lsp(
4526            buffer.clone(),
4527            server_id,
4528            LinkedEditingRange { position },
4529            cx,
4530        )
4531    }
4532
4533    fn apply_on_type_formatting(
4534        &mut self,
4535        buffer: Entity<Buffer>,
4536        position: Anchor,
4537        trigger: String,
4538        cx: &mut Context<Self>,
4539    ) -> Task<Result<Option<Transaction>>> {
4540        if let Some((client, project_id)) = self.upstream_client() {
4541            let request = proto::OnTypeFormatting {
4542                project_id,
4543                buffer_id: buffer.read(cx).remote_id().into(),
4544                position: Some(serialize_anchor(&position)),
4545                trigger,
4546                version: serialize_version(&buffer.read(cx).version()),
4547            };
4548            cx.spawn(async move |_, _| {
4549                client
4550                    .request(request)
4551                    .await?
4552                    .transaction
4553                    .map(language::proto::deserialize_transaction)
4554                    .transpose()
4555            })
4556        } else if let Some(local) = self.as_local_mut() {
4557            let buffer_id = buffer.read(cx).remote_id();
4558            local.buffers_being_formatted.insert(buffer_id);
4559            cx.spawn(async move |this, cx| {
4560                let _cleanup = defer({
4561                    let this = this.clone();
4562                    let mut cx = cx.clone();
4563                    move || {
4564                        this.update(&mut cx, |this, _| {
4565                            if let Some(local) = this.as_local_mut() {
4566                                local.buffers_being_formatted.remove(&buffer_id);
4567                            }
4568                        })
4569                        .ok();
4570                    }
4571                });
4572
4573                buffer
4574                    .update(cx, |buffer, _| {
4575                        buffer.wait_for_edits(Some(position.timestamp))
4576                    })?
4577                    .await?;
4578                this.update(cx, |this, cx| {
4579                    let position = position.to_point_utf16(buffer.read(cx));
4580                    this.on_type_format(buffer, position, trigger, false, cx)
4581                })?
4582                .await
4583            })
4584        } else {
4585            Task::ready(Err(anyhow!("No upstream client or local language server")))
4586        }
4587    }
4588
4589    pub fn on_type_format<T: ToPointUtf16>(
4590        &mut self,
4591        buffer: Entity<Buffer>,
4592        position: T,
4593        trigger: String,
4594        push_to_history: bool,
4595        cx: &mut Context<Self>,
4596    ) -> Task<Result<Option<Transaction>>> {
4597        let position = position.to_point_utf16(buffer.read(cx));
4598        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
4599    }
4600
4601    fn on_type_format_impl(
4602        &mut self,
4603        buffer: Entity<Buffer>,
4604        position: PointUtf16,
4605        trigger: String,
4606        push_to_history: bool,
4607        cx: &mut Context<Self>,
4608    ) -> Task<Result<Option<Transaction>>> {
4609        let options = buffer.update(cx, |buffer, cx| {
4610            lsp_command::lsp_formatting_options(
4611                language_settings(
4612                    buffer.language_at(position).map(|l| l.name()),
4613                    buffer.file(),
4614                    cx,
4615                )
4616                .as_ref(),
4617            )
4618        });
4619        self.request_lsp(
4620            buffer.clone(),
4621            LanguageServerToQuery::FirstCapable,
4622            OnTypeFormatting {
4623                position,
4624                trigger,
4625                options,
4626                push_to_history,
4627            },
4628            cx,
4629        )
4630    }
4631
4632    pub fn code_actions(
4633        &mut self,
4634        buffer_handle: &Entity<Buffer>,
4635        range: Range<Anchor>,
4636        kinds: Option<Vec<CodeActionKind>>,
4637        cx: &mut Context<Self>,
4638    ) -> Task<Result<Vec<CodeAction>>> {
4639        if let Some((upstream_client, project_id)) = self.upstream_client() {
4640            let request_task = upstream_client.request(proto::MultiLspQuery {
4641                buffer_id: buffer_handle.read(cx).remote_id().into(),
4642                version: serialize_version(&buffer_handle.read(cx).version()),
4643                project_id,
4644                strategy: Some(proto::multi_lsp_query::Strategy::All(
4645                    proto::AllLanguageServers {},
4646                )),
4647                request: Some(proto::multi_lsp_query::Request::GetCodeActions(
4648                    GetCodeActions {
4649                        range: range.clone(),
4650                        kinds: kinds.clone(),
4651                    }
4652                    .to_proto(project_id, buffer_handle.read(cx)),
4653                )),
4654            });
4655            let buffer = buffer_handle.clone();
4656            cx.spawn(async move |weak_project, cx| {
4657                let Some(project) = weak_project.upgrade() else {
4658                    return Ok(Vec::new());
4659                };
4660                let responses = request_task.await?.responses;
4661                let actions = join_all(
4662                    responses
4663                        .into_iter()
4664                        .filter_map(|lsp_response| match lsp_response.response? {
4665                            proto::lsp_response::Response::GetCodeActionsResponse(response) => {
4666                                Some(response)
4667                            }
4668                            unexpected => {
4669                                debug_panic!("Unexpected response: {unexpected:?}");
4670                                None
4671                            }
4672                        })
4673                        .map(|code_actions_response| {
4674                            GetCodeActions {
4675                                range: range.clone(),
4676                                kinds: kinds.clone(),
4677                            }
4678                            .response_from_proto(
4679                                code_actions_response,
4680                                project.clone(),
4681                                buffer.clone(),
4682                                cx.clone(),
4683                            )
4684                        }),
4685                )
4686                .await;
4687
4688                Ok(actions
4689                    .into_iter()
4690                    .collect::<Result<Vec<Vec<_>>>>()?
4691                    .into_iter()
4692                    .flatten()
4693                    .collect())
4694            })
4695        } else {
4696            let all_actions_task = self.request_multiple_lsp_locally(
4697                buffer_handle,
4698                Some(range.start),
4699                GetCodeActions {
4700                    range: range.clone(),
4701                    kinds: kinds.clone(),
4702                },
4703                cx,
4704            );
4705            cx.spawn(async move |_, _| Ok(all_actions_task.await.into_iter().flatten().collect()))
4706        }
4707    }
4708
4709    pub fn code_lens(
4710        &mut self,
4711        buffer_handle: &Entity<Buffer>,
4712        cx: &mut Context<Self>,
4713    ) -> Task<Result<Vec<CodeAction>>> {
4714        if let Some((upstream_client, project_id)) = self.upstream_client() {
4715            let request_task = upstream_client.request(proto::MultiLspQuery {
4716                buffer_id: buffer_handle.read(cx).remote_id().into(),
4717                version: serialize_version(&buffer_handle.read(cx).version()),
4718                project_id,
4719                strategy: Some(proto::multi_lsp_query::Strategy::All(
4720                    proto::AllLanguageServers {},
4721                )),
4722                request: Some(proto::multi_lsp_query::Request::GetCodeLens(
4723                    GetCodeLens.to_proto(project_id, buffer_handle.read(cx)),
4724                )),
4725            });
4726            let buffer = buffer_handle.clone();
4727            cx.spawn(async move |weak_project, cx| {
4728                let Some(project) = weak_project.upgrade() else {
4729                    return Ok(Vec::new());
4730                };
4731                let responses = request_task.await?.responses;
4732                let code_lens = join_all(
4733                    responses
4734                        .into_iter()
4735                        .filter_map(|lsp_response| match lsp_response.response? {
4736                            proto::lsp_response::Response::GetCodeLensResponse(response) => {
4737                                Some(response)
4738                            }
4739                            unexpected => {
4740                                debug_panic!("Unexpected response: {unexpected:?}");
4741                                None
4742                            }
4743                        })
4744                        .map(|code_lens_response| {
4745                            GetCodeLens.response_from_proto(
4746                                code_lens_response,
4747                                project.clone(),
4748                                buffer.clone(),
4749                                cx.clone(),
4750                            )
4751                        }),
4752                )
4753                .await;
4754
4755                Ok(code_lens
4756                    .into_iter()
4757                    .collect::<Result<Vec<Vec<_>>>>()?
4758                    .into_iter()
4759                    .flatten()
4760                    .collect())
4761            })
4762        } else {
4763            let code_lens_task =
4764                self.request_multiple_lsp_locally(buffer_handle, None::<usize>, GetCodeLens, cx);
4765            cx.spawn(async move |_, _| Ok(code_lens_task.await.into_iter().flatten().collect()))
4766        }
4767    }
4768
4769    #[inline(never)]
4770    pub fn completions(
4771        &self,
4772        buffer: &Entity<Buffer>,
4773        position: PointUtf16,
4774        context: CompletionContext,
4775        cx: &mut Context<Self>,
4776    ) -> Task<Result<Option<Vec<Completion>>>> {
4777        let language_registry = self.languages.clone();
4778
4779        if let Some((upstream_client, project_id)) = self.upstream_client() {
4780            let task = self.send_lsp_proto_request(
4781                buffer.clone(),
4782                upstream_client,
4783                project_id,
4784                GetCompletions { position, context },
4785                cx,
4786            );
4787            let language = buffer.read(cx).language().cloned();
4788
4789            // In the future, we should provide project guests with the names of LSP adapters,
4790            // so that they can use the correct LSP adapter when computing labels. For now,
4791            // guests just use the first LSP adapter associated with the buffer's language.
4792            let lsp_adapter = language.as_ref().and_then(|language| {
4793                language_registry
4794                    .lsp_adapters(&language.name())
4795                    .first()
4796                    .cloned()
4797            });
4798
4799            cx.foreground_executor().spawn(async move {
4800                let completions = task.await?;
4801                let mut result = Vec::new();
4802                populate_labels_for_completions(completions, language, lsp_adapter, &mut result)
4803                    .await;
4804                Ok(Some(result))
4805            })
4806        } else if let Some(local) = self.as_local() {
4807            let snapshot = buffer.read(cx).snapshot();
4808            let offset = position.to_offset(&snapshot);
4809            let scope = snapshot.language_scope_at(offset);
4810            let language = snapshot.language().cloned();
4811            let completion_settings = language_settings(
4812                language.as_ref().map(|language| language.name()),
4813                buffer.read(cx).file(),
4814                cx,
4815            )
4816            .completions;
4817            if !completion_settings.lsp {
4818                return Task::ready(Ok(None));
4819            }
4820
4821            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
4822                local
4823                    .language_servers_for_buffer(buffer, cx)
4824                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
4825                    .filter(|(adapter, _)| {
4826                        scope
4827                            .as_ref()
4828                            .map(|scope| scope.language_allowed(&adapter.name))
4829                            .unwrap_or(true)
4830                    })
4831                    .map(|(_, server)| server.server_id())
4832                    .collect()
4833            });
4834
4835            let buffer = buffer.clone();
4836            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
4837            let lsp_timeout = if lsp_timeout > 0 {
4838                Some(Duration::from_millis(lsp_timeout))
4839            } else {
4840                None
4841            };
4842            cx.spawn(async move |this,  cx| {
4843                let mut tasks = Vec::with_capacity(server_ids.len());
4844                this.update(cx, |lsp_store, cx| {
4845                    for server_id in server_ids {
4846                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
4847                        let lsp_timeout = lsp_timeout
4848                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
4849                        let mut timeout = cx.background_spawn(async move {
4850                            match lsp_timeout {
4851                                Some(lsp_timeout) => {
4852                                    lsp_timeout.await;
4853                                    true
4854                                },
4855                                None => false,
4856                            }
4857                        }).fuse();
4858                        let mut lsp_request = lsp_store.request_lsp(
4859                            buffer.clone(),
4860                            LanguageServerToQuery::Other(server_id),
4861                            GetCompletions {
4862                                position,
4863                                context: context.clone(),
4864                            },
4865                            cx,
4866                        ).fuse();
4867                        let new_task = cx.background_spawn(async move {
4868                            select_biased! {
4869                                response = lsp_request => anyhow::Ok(Some(response?)),
4870                                timeout_happened = timeout => {
4871                                    if timeout_happened {
4872                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
4873                                        Ok(None)
4874                                    } else {
4875                                        let completions = lsp_request.await?;
4876                                        Ok(Some(completions))
4877                                    }
4878                                },
4879                            }
4880                        });
4881                        tasks.push((lsp_adapter, new_task));
4882                    }
4883                })?;
4884
4885                let mut has_completions_returned = false;
4886                let mut completions = Vec::new();
4887                for (lsp_adapter, task) in tasks {
4888                    if let Ok(Some(new_completions)) = task.await {
4889                        has_completions_returned = true;
4890                        populate_labels_for_completions(
4891                            new_completions,
4892                            language.clone(),
4893                            lsp_adapter,
4894                            &mut completions,
4895                        )
4896                        .await;
4897                    }
4898                }
4899                if has_completions_returned {
4900                    Ok(Some(completions))
4901                } else {
4902                    Ok(None)
4903                }
4904            })
4905        } else {
4906            Task::ready(Err(anyhow!("No upstream client or local language server")))
4907        }
4908    }
4909
4910    pub fn resolve_completions(
4911        &self,
4912        buffer: Entity<Buffer>,
4913        completion_indices: Vec<usize>,
4914        completions: Rc<RefCell<Box<[Completion]>>>,
4915        cx: &mut Context<Self>,
4916    ) -> Task<Result<bool>> {
4917        let client = self.upstream_client();
4918
4919        let buffer_id = buffer.read(cx).remote_id();
4920        let buffer_snapshot = buffer.read(cx).snapshot();
4921
4922        cx.spawn(async move |this, cx| {
4923            let mut did_resolve = false;
4924            if let Some((client, project_id)) = client {
4925                for completion_index in completion_indices {
4926                    let server_id = {
4927                        let completion = &completions.borrow()[completion_index];
4928                        completion.source.server_id()
4929                    };
4930                    if let Some(server_id) = server_id {
4931                        if Self::resolve_completion_remote(
4932                            project_id,
4933                            server_id,
4934                            buffer_id,
4935                            completions.clone(),
4936                            completion_index,
4937                            client.clone(),
4938                        )
4939                        .await
4940                        .log_err()
4941                        .is_some()
4942                        {
4943                            did_resolve = true;
4944                        }
4945                    } else {
4946                        resolve_word_completion(
4947                            &buffer_snapshot,
4948                            &mut completions.borrow_mut()[completion_index],
4949                        );
4950                    }
4951                }
4952            } else {
4953                for completion_index in completion_indices {
4954                    let server_id = {
4955                        let completion = &completions.borrow()[completion_index];
4956                        completion.source.server_id()
4957                    };
4958                    if let Some(server_id) = server_id {
4959                        let server_and_adapter = this
4960                            .read_with(cx, |lsp_store, _| {
4961                                let server = lsp_store.language_server_for_id(server_id)?;
4962                                let adapter =
4963                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
4964                                Some((server, adapter))
4965                            })
4966                            .ok()
4967                            .flatten();
4968                        let Some((server, adapter)) = server_and_adapter else {
4969                            continue;
4970                        };
4971
4972                        let resolved = Self::resolve_completion_local(
4973                            server,
4974                            &buffer_snapshot,
4975                            completions.clone(),
4976                            completion_index,
4977                        )
4978                        .await
4979                        .log_err()
4980                        .is_some();
4981                        if resolved {
4982                            Self::regenerate_completion_labels(
4983                                adapter,
4984                                &buffer_snapshot,
4985                                completions.clone(),
4986                                completion_index,
4987                            )
4988                            .await
4989                            .log_err();
4990                            did_resolve = true;
4991                        }
4992                    } else {
4993                        resolve_word_completion(
4994                            &buffer_snapshot,
4995                            &mut completions.borrow_mut()[completion_index],
4996                        );
4997                    }
4998                }
4999            }
5000
5001            Ok(did_resolve)
5002        })
5003    }
5004
5005    async fn resolve_completion_local(
5006        server: Arc<lsp::LanguageServer>,
5007        snapshot: &BufferSnapshot,
5008        completions: Rc<RefCell<Box<[Completion]>>>,
5009        completion_index: usize,
5010    ) -> Result<()> {
5011        let server_id = server.server_id();
5012        let can_resolve = server
5013            .capabilities()
5014            .completion_provider
5015            .as_ref()
5016            .and_then(|options| options.resolve_provider)
5017            .unwrap_or(false);
5018        if !can_resolve {
5019            return Ok(());
5020        }
5021
5022        let request = {
5023            let completion = &completions.borrow()[completion_index];
5024            match &completion.source {
5025                CompletionSource::Lsp {
5026                    lsp_completion,
5027                    resolved,
5028                    server_id: completion_server_id,
5029                    ..
5030                } => {
5031                    if *resolved {
5032                        return Ok(());
5033                    }
5034                    anyhow::ensure!(
5035                        server_id == *completion_server_id,
5036                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
5037                    );
5038                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
5039                }
5040                CompletionSource::BufferWord { .. } | CompletionSource::Custom => {
5041                    return Ok(());
5042                }
5043            }
5044        };
5045        let resolved_completion = request.await?;
5046
5047        if let Some(text_edit) = resolved_completion.text_edit.as_ref() {
5048            // Technically we don't have to parse the whole `text_edit`, since the only
5049            // language server we currently use that does update `text_edit` in `completionItem/resolve`
5050            // is `typescript-language-server` and they only update `text_edit.new_text`.
5051            // But we should not rely on that.
5052            let edit = parse_completion_text_edit(text_edit, snapshot);
5053
5054            if let Some((old_range, mut new_text)) = edit {
5055                LineEnding::normalize(&mut new_text);
5056
5057                let mut completions = completions.borrow_mut();
5058                let completion = &mut completions[completion_index];
5059
5060                completion.new_text = new_text;
5061                completion.old_range = old_range;
5062            }
5063        }
5064
5065        let mut completions = completions.borrow_mut();
5066        let completion = &mut completions[completion_index];
5067        if let CompletionSource::Lsp {
5068            lsp_completion,
5069            resolved,
5070            server_id: completion_server_id,
5071            ..
5072        } = &mut completion.source
5073        {
5074            if *resolved {
5075                return Ok(());
5076            }
5077            anyhow::ensure!(
5078                server_id == *completion_server_id,
5079                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
5080            );
5081            *lsp_completion = Box::new(resolved_completion);
5082            *resolved = true;
5083        }
5084        Ok(())
5085    }
5086
5087    async fn regenerate_completion_labels(
5088        adapter: Arc<CachedLspAdapter>,
5089        snapshot: &BufferSnapshot,
5090        completions: Rc<RefCell<Box<[Completion]>>>,
5091        completion_index: usize,
5092    ) -> Result<()> {
5093        let completion_item = completions.borrow()[completion_index]
5094            .source
5095            .lsp_completion(true)
5096            .map(Cow::into_owned);
5097        if let Some(lsp_documentation) = completion_item
5098            .as_ref()
5099            .and_then(|completion_item| completion_item.documentation.clone())
5100        {
5101            let mut completions = completions.borrow_mut();
5102            let completion = &mut completions[completion_index];
5103            completion.documentation = Some(lsp_documentation.into());
5104        } else {
5105            let mut completions = completions.borrow_mut();
5106            let completion = &mut completions[completion_index];
5107            completion.documentation = Some(CompletionDocumentation::Undocumented);
5108        }
5109
5110        let mut new_label = match completion_item {
5111            Some(completion_item) => {
5112                // NB: Zed does not have `details` inside the completion resolve capabilities, but certain language servers violate the spec and do not return `details` immediately, e.g. https://github.com/yioneko/vtsls/issues/213
5113                // So we have to update the label here anyway...
5114                let language = snapshot.language();
5115                match language {
5116                    Some(language) => {
5117                        adapter
5118                            .labels_for_completions(&[completion_item.clone()], language)
5119                            .await?
5120                    }
5121                    None => Vec::new(),
5122                }
5123                .pop()
5124                .flatten()
5125                .unwrap_or_else(|| {
5126                    CodeLabel::fallback_for_completion(
5127                        &completion_item,
5128                        language.map(|language| language.as_ref()),
5129                    )
5130                })
5131            }
5132            None => CodeLabel::plain(
5133                completions.borrow()[completion_index].new_text.clone(),
5134                None,
5135            ),
5136        };
5137        ensure_uniform_list_compatible_label(&mut new_label);
5138
5139        let mut completions = completions.borrow_mut();
5140        let completion = &mut completions[completion_index];
5141        if completion.label.filter_text() == new_label.filter_text() {
5142            completion.label = new_label;
5143        } else {
5144            log::error!(
5145                "Resolved completion changed display label from {} to {}. \
5146                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
5147                completion.label.text(),
5148                new_label.text(),
5149                completion.label.filter_text(),
5150                new_label.filter_text()
5151            );
5152        }
5153
5154        Ok(())
5155    }
5156
5157    async fn resolve_completion_remote(
5158        project_id: u64,
5159        server_id: LanguageServerId,
5160        buffer_id: BufferId,
5161        completions: Rc<RefCell<Box<[Completion]>>>,
5162        completion_index: usize,
5163        client: AnyProtoClient,
5164    ) -> Result<()> {
5165        let lsp_completion = {
5166            let completion = &completions.borrow()[completion_index];
5167            match &completion.source {
5168                CompletionSource::Lsp {
5169                    lsp_completion,
5170                    resolved,
5171                    server_id: completion_server_id,
5172                    ..
5173                } => {
5174                    anyhow::ensure!(
5175                        server_id == *completion_server_id,
5176                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
5177                    );
5178                    if *resolved {
5179                        return Ok(());
5180                    }
5181                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
5182                }
5183                CompletionSource::Custom | CompletionSource::BufferWord { .. } => {
5184                    return Ok(());
5185                }
5186            }
5187        };
5188        let request = proto::ResolveCompletionDocumentation {
5189            project_id,
5190            language_server_id: server_id.0 as u64,
5191            lsp_completion,
5192            buffer_id: buffer_id.into(),
5193        };
5194
5195        let response = client
5196            .request(request)
5197            .await
5198            .context("completion documentation resolve proto request")?;
5199        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
5200
5201        let documentation = if response.documentation.is_empty() {
5202            CompletionDocumentation::Undocumented
5203        } else if response.documentation_is_markdown {
5204            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
5205        } else if response.documentation.lines().count() <= 1 {
5206            CompletionDocumentation::SingleLine(response.documentation.into())
5207        } else {
5208            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
5209        };
5210
5211        let mut completions = completions.borrow_mut();
5212        let completion = &mut completions[completion_index];
5213        completion.documentation = Some(documentation);
5214        if let CompletionSource::Lsp {
5215            lsp_completion,
5216            resolved,
5217            server_id: completion_server_id,
5218            lsp_defaults: _,
5219        } = &mut completion.source
5220        {
5221            if *resolved {
5222                return Ok(());
5223            }
5224            anyhow::ensure!(
5225                server_id == *completion_server_id,
5226                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
5227            );
5228            *lsp_completion = Box::new(resolved_lsp_completion);
5229            *resolved = true;
5230        }
5231
5232        let old_range = response
5233            .old_start
5234            .and_then(deserialize_anchor)
5235            .zip(response.old_end.and_then(deserialize_anchor));
5236        if let Some((old_start, old_end)) = old_range {
5237            if !response.new_text.is_empty() {
5238                completion.new_text = response.new_text;
5239                completion.old_range = old_start..old_end;
5240            }
5241        }
5242
5243        Ok(())
5244    }
5245
5246    pub fn apply_additional_edits_for_completion(
5247        &self,
5248        buffer_handle: Entity<Buffer>,
5249        completions: Rc<RefCell<Box<[Completion]>>>,
5250        completion_index: usize,
5251        push_to_history: bool,
5252        cx: &mut Context<Self>,
5253    ) -> Task<Result<Option<Transaction>>> {
5254        if let Some((client, project_id)) = self.upstream_client() {
5255            let buffer = buffer_handle.read(cx);
5256            let buffer_id = buffer.remote_id();
5257            cx.spawn(async move |_, cx| {
5258                let request = {
5259                    let completion = completions.borrow()[completion_index].clone();
5260                    proto::ApplyCompletionAdditionalEdits {
5261                        project_id,
5262                        buffer_id: buffer_id.into(),
5263                        completion: Some(Self::serialize_completion(&CoreCompletion {
5264                            old_range: completion.old_range,
5265                            new_text: completion.new_text,
5266                            source: completion.source,
5267                        })),
5268                    }
5269                };
5270
5271                if let Some(transaction) = client.request(request).await?.transaction {
5272                    let transaction = language::proto::deserialize_transaction(transaction)?;
5273                    buffer_handle
5274                        .update(cx, |buffer, _| {
5275                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
5276                        })?
5277                        .await?;
5278                    if push_to_history {
5279                        buffer_handle.update(cx, |buffer, _| {
5280                            buffer.push_transaction(transaction.clone(), Instant::now());
5281                        })?;
5282                    }
5283                    Ok(Some(transaction))
5284                } else {
5285                    Ok(None)
5286                }
5287            })
5288        } else {
5289            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
5290                let completion = &completions.borrow()[completion_index];
5291                let server_id = completion.source.server_id()?;
5292                Some(
5293                    self.language_server_for_local_buffer(buffer, server_id, cx)?
5294                        .1
5295                        .clone(),
5296                )
5297            }) else {
5298                return Task::ready(Ok(None));
5299            };
5300            let snapshot = buffer_handle.read(&cx).snapshot();
5301
5302            cx.spawn(async move |this, cx| {
5303                Self::resolve_completion_local(
5304                    server.clone(),
5305                    &snapshot,
5306                    completions.clone(),
5307                    completion_index,
5308                )
5309                .await
5310                .context("resolving completion")?;
5311                let completion = completions.borrow()[completion_index].clone();
5312                let additional_text_edits = completion
5313                    .source
5314                    .lsp_completion(true)
5315                    .as_ref()
5316                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
5317                if let Some(edits) = additional_text_edits {
5318                    let edits = this
5319                        .update(cx, |this, cx| {
5320                            this.as_local_mut().unwrap().edits_from_lsp(
5321                                &buffer_handle,
5322                                edits,
5323                                server.server_id(),
5324                                None,
5325                                cx,
5326                            )
5327                        })?
5328                        .await?;
5329
5330                    buffer_handle.update(cx, |buffer, cx| {
5331                        buffer.finalize_last_transaction();
5332                        buffer.start_transaction();
5333
5334                        for (range, text) in edits {
5335                            let primary = &completion.old_range;
5336                            let start_within = primary.start.cmp(&range.start, buffer).is_le()
5337                                && primary.end.cmp(&range.start, buffer).is_ge();
5338                            let end_within = range.start.cmp(&primary.end, buffer).is_le()
5339                                && range.end.cmp(&primary.end, buffer).is_ge();
5340
5341                            //Skip additional edits which overlap with the primary completion edit
5342                            //https://github.com/zed-industries/zed/pull/1871
5343                            if !start_within && !end_within {
5344                                buffer.edit([(range, text)], None, cx);
5345                            }
5346                        }
5347
5348                        let transaction = if buffer.end_transaction(cx).is_some() {
5349                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
5350                            if !push_to_history {
5351                                buffer.forget_transaction(transaction.id);
5352                            }
5353                            Some(transaction)
5354                        } else {
5355                            None
5356                        };
5357                        Ok(transaction)
5358                    })?
5359                } else {
5360                    Ok(None)
5361                }
5362            })
5363        }
5364    }
5365
5366    pub fn inlay_hints(
5367        &mut self,
5368        buffer_handle: Entity<Buffer>,
5369        range: Range<Anchor>,
5370        cx: &mut Context<Self>,
5371    ) -> Task<anyhow::Result<Vec<InlayHint>>> {
5372        let buffer = buffer_handle.read(cx);
5373        let range_start = range.start;
5374        let range_end = range.end;
5375        let buffer_id = buffer.remote_id().into();
5376        let lsp_request = InlayHints { range };
5377
5378        if let Some((client, project_id)) = self.upstream_client() {
5379            let request = proto::InlayHints {
5380                project_id,
5381                buffer_id,
5382                start: Some(serialize_anchor(&range_start)),
5383                end: Some(serialize_anchor(&range_end)),
5384                version: serialize_version(&buffer_handle.read(cx).version()),
5385            };
5386            cx.spawn(async move |project, cx| {
5387                let response = client
5388                    .request(request)
5389                    .await
5390                    .context("inlay hints proto request")?;
5391                LspCommand::response_from_proto(
5392                    lsp_request,
5393                    response,
5394                    project.upgrade().ok_or_else(|| anyhow!("No project"))?,
5395                    buffer_handle.clone(),
5396                    cx.clone(),
5397                )
5398                .await
5399                .context("inlay hints proto response conversion")
5400            })
5401        } else {
5402            let lsp_request_task = self.request_lsp(
5403                buffer_handle.clone(),
5404                LanguageServerToQuery::FirstCapable,
5405                lsp_request,
5406                cx,
5407            );
5408            cx.spawn(async move |_, cx| {
5409                buffer_handle
5410                    .update(cx, |buffer, _| {
5411                        buffer.wait_for_edits(vec![range_start.timestamp, range_end.timestamp])
5412                    })?
5413                    .await
5414                    .context("waiting for inlay hint request range edits")?;
5415                lsp_request_task.await.context("inlay hints LSP request")
5416            })
5417        }
5418    }
5419
5420    pub fn signature_help<T: ToPointUtf16>(
5421        &mut self,
5422        buffer: &Entity<Buffer>,
5423        position: T,
5424        cx: &mut Context<Self>,
5425    ) -> Task<Vec<SignatureHelp>> {
5426        let position = position.to_point_utf16(buffer.read(cx));
5427
5428        if let Some((client, upstream_project_id)) = self.upstream_client() {
5429            let request_task = client.request(proto::MultiLspQuery {
5430                buffer_id: buffer.read(cx).remote_id().into(),
5431                version: serialize_version(&buffer.read(cx).version()),
5432                project_id: upstream_project_id,
5433                strategy: Some(proto::multi_lsp_query::Strategy::All(
5434                    proto::AllLanguageServers {},
5435                )),
5436                request: Some(proto::multi_lsp_query::Request::GetSignatureHelp(
5437                    GetSignatureHelp { position }.to_proto(upstream_project_id, buffer.read(cx)),
5438                )),
5439            });
5440            let buffer = buffer.clone();
5441            cx.spawn(async move |weak_project, cx| {
5442                let Some(project) = weak_project.upgrade() else {
5443                    return Vec::new();
5444                };
5445                join_all(
5446                    request_task
5447                        .await
5448                        .log_err()
5449                        .map(|response| response.responses)
5450                        .unwrap_or_default()
5451                        .into_iter()
5452                        .filter_map(|lsp_response| match lsp_response.response? {
5453                            proto::lsp_response::Response::GetSignatureHelpResponse(response) => {
5454                                Some(response)
5455                            }
5456                            unexpected => {
5457                                debug_panic!("Unexpected response: {unexpected:?}");
5458                                None
5459                            }
5460                        })
5461                        .map(|signature_response| {
5462                            let response = GetSignatureHelp { position }.response_from_proto(
5463                                signature_response,
5464                                project.clone(),
5465                                buffer.clone(),
5466                                cx.clone(),
5467                            );
5468                            async move { response.await.log_err().flatten() }
5469                        }),
5470                )
5471                .await
5472                .into_iter()
5473                .flatten()
5474                .collect()
5475            })
5476        } else {
5477            let all_actions_task = self.request_multiple_lsp_locally(
5478                buffer,
5479                Some(position),
5480                GetSignatureHelp { position },
5481                cx,
5482            );
5483            cx.spawn(async move |_, _| {
5484                all_actions_task
5485                    .await
5486                    .into_iter()
5487                    .flatten()
5488                    .filter(|help| !help.label.is_empty())
5489                    .collect::<Vec<_>>()
5490            })
5491        }
5492    }
5493
5494    pub fn hover(
5495        &mut self,
5496        buffer: &Entity<Buffer>,
5497        position: PointUtf16,
5498        cx: &mut Context<Self>,
5499    ) -> Task<Vec<Hover>> {
5500        if let Some((client, upstream_project_id)) = self.upstream_client() {
5501            let request_task = client.request(proto::MultiLspQuery {
5502                buffer_id: buffer.read(cx).remote_id().into(),
5503                version: serialize_version(&buffer.read(cx).version()),
5504                project_id: upstream_project_id,
5505                strategy: Some(proto::multi_lsp_query::Strategy::All(
5506                    proto::AllLanguageServers {},
5507                )),
5508                request: Some(proto::multi_lsp_query::Request::GetHover(
5509                    GetHover { position }.to_proto(upstream_project_id, buffer.read(cx)),
5510                )),
5511            });
5512            let buffer = buffer.clone();
5513            cx.spawn(async move |weak_project, cx| {
5514                let Some(project) = weak_project.upgrade() else {
5515                    return Vec::new();
5516                };
5517                join_all(
5518                    request_task
5519                        .await
5520                        .log_err()
5521                        .map(|response| response.responses)
5522                        .unwrap_or_default()
5523                        .into_iter()
5524                        .filter_map(|lsp_response| match lsp_response.response? {
5525                            proto::lsp_response::Response::GetHoverResponse(response) => {
5526                                Some(response)
5527                            }
5528                            unexpected => {
5529                                debug_panic!("Unexpected response: {unexpected:?}");
5530                                None
5531                            }
5532                        })
5533                        .map(|hover_response| {
5534                            let response = GetHover { position }.response_from_proto(
5535                                hover_response,
5536                                project.clone(),
5537                                buffer.clone(),
5538                                cx.clone(),
5539                            );
5540                            async move {
5541                                response
5542                                    .await
5543                                    .log_err()
5544                                    .flatten()
5545                                    .and_then(remove_empty_hover_blocks)
5546                            }
5547                        }),
5548                )
5549                .await
5550                .into_iter()
5551                .flatten()
5552                .collect()
5553            })
5554        } else {
5555            let all_actions_task = self.request_multiple_lsp_locally(
5556                buffer,
5557                Some(position),
5558                GetHover { position },
5559                cx,
5560            );
5561            cx.spawn(async move |_, _| {
5562                all_actions_task
5563                    .await
5564                    .into_iter()
5565                    .filter_map(|hover| remove_empty_hover_blocks(hover?))
5566                    .collect::<Vec<Hover>>()
5567            })
5568        }
5569    }
5570
5571    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
5572        let language_registry = self.languages.clone();
5573
5574        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
5575            let request = upstream_client.request(proto::GetProjectSymbols {
5576                project_id: *project_id,
5577                query: query.to_string(),
5578            });
5579            cx.foreground_executor().spawn(async move {
5580                let response = request.await?;
5581                let mut symbols = Vec::new();
5582                let core_symbols = response
5583                    .symbols
5584                    .into_iter()
5585                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
5586                    .collect::<Vec<_>>();
5587                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
5588                    .await;
5589                Ok(symbols)
5590            })
5591        } else if let Some(local) = self.as_local() {
5592            struct WorkspaceSymbolsResult {
5593                server_id: LanguageServerId,
5594                lsp_adapter: Arc<CachedLspAdapter>,
5595                worktree: WeakEntity<Worktree>,
5596                worktree_abs_path: Arc<Path>,
5597                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
5598            }
5599
5600            let mut requests = Vec::new();
5601            let mut requested_servers = BTreeSet::new();
5602            'next_server: for ((worktree_id, _), server_ids) in local.language_server_ids.iter() {
5603                let Some(worktree_handle) = self
5604                    .worktree_store
5605                    .read(cx)
5606                    .worktree_for_id(*worktree_id, cx)
5607                else {
5608                    continue;
5609                };
5610                let worktree = worktree_handle.read(cx);
5611                if !worktree.is_visible() {
5612                    continue;
5613                }
5614
5615                let mut servers_to_query = server_ids
5616                    .difference(&requested_servers)
5617                    .cloned()
5618                    .collect::<BTreeSet<_>>();
5619                for server_id in &servers_to_query {
5620                    let (lsp_adapter, server) = match local.language_servers.get(server_id) {
5621                        Some(LanguageServerState::Running {
5622                            adapter, server, ..
5623                        }) => (adapter.clone(), server),
5624
5625                        _ => continue 'next_server,
5626                    };
5627                    let worktree_abs_path = worktree.abs_path().clone();
5628                    let worktree_handle = worktree_handle.clone();
5629                    let server_id = server.server_id();
5630                    requests.push(
5631                            server
5632                                .request::<lsp::request::WorkspaceSymbolRequest>(
5633                                    lsp::WorkspaceSymbolParams {
5634                                        query: query.to_string(),
5635                                        ..Default::default()
5636                                    },
5637                                )
5638                                .log_err()
5639                                .map(move |response| {
5640                                    let lsp_symbols = response.flatten().map(|symbol_response| match symbol_response {
5641                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
5642                                            flat_responses.into_iter().map(|lsp_symbol| {
5643                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
5644                                            }).collect::<Vec<_>>()
5645                                        }
5646                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
5647                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
5648                                                let location = match lsp_symbol.location {
5649                                                    OneOf::Left(location) => location,
5650                                                    OneOf::Right(_) => {
5651                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
5652                                                        return None
5653                                                    }
5654                                                };
5655                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
5656                                            }).collect::<Vec<_>>()
5657                                        }
5658                                    }).unwrap_or_default();
5659
5660                                    WorkspaceSymbolsResult {
5661                                        server_id,
5662                                        lsp_adapter,
5663                                        worktree: worktree_handle.downgrade(),
5664                                        worktree_abs_path,
5665                                        lsp_symbols,
5666                                    }
5667                                }),
5668                        );
5669                }
5670                requested_servers.append(&mut servers_to_query);
5671            }
5672
5673            cx.spawn(async move |this, cx| {
5674                let responses = futures::future::join_all(requests).await;
5675                let this = match this.upgrade() {
5676                    Some(this) => this,
5677                    None => return Ok(Vec::new()),
5678                };
5679
5680                let mut symbols = Vec::new();
5681                for result in responses {
5682                    let core_symbols = this.update(cx, |this, cx| {
5683                        result
5684                            .lsp_symbols
5685                            .into_iter()
5686                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
5687                                let abs_path = symbol_location.uri.to_file_path().ok()?;
5688                                let source_worktree = result.worktree.upgrade()?;
5689                                let source_worktree_id = source_worktree.read(cx).id();
5690
5691                                let path;
5692                                let worktree;
5693                                if let Some((tree, rel_path)) =
5694                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
5695                                {
5696                                    worktree = tree;
5697                                    path = rel_path;
5698                                } else {
5699                                    worktree = source_worktree.clone();
5700                                    path = relativize_path(&result.worktree_abs_path, &abs_path);
5701                                }
5702
5703                                let worktree_id = worktree.read(cx).id();
5704                                let project_path = ProjectPath {
5705                                    worktree_id,
5706                                    path: path.into(),
5707                                };
5708                                let signature = this.symbol_signature(&project_path);
5709                                Some(CoreSymbol {
5710                                    source_language_server_id: result.server_id,
5711                                    language_server_name: result.lsp_adapter.name.clone(),
5712                                    source_worktree_id,
5713                                    path: project_path,
5714                                    kind: symbol_kind,
5715                                    name: symbol_name,
5716                                    range: range_from_lsp(symbol_location.range),
5717                                    signature,
5718                                })
5719                            })
5720                            .collect()
5721                    })?;
5722
5723                    populate_labels_for_symbols(
5724                        core_symbols,
5725                        &language_registry,
5726                        Some(result.lsp_adapter),
5727                        &mut symbols,
5728                    )
5729                    .await;
5730                }
5731
5732                Ok(symbols)
5733            })
5734        } else {
5735            Task::ready(Err(anyhow!("No upstream client or local language server")))
5736        }
5737    }
5738
5739    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
5740        let mut summary = DiagnosticSummary::default();
5741        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
5742            summary.error_count += path_summary.error_count;
5743            summary.warning_count += path_summary.warning_count;
5744        }
5745        summary
5746    }
5747
5748    pub fn diagnostic_summaries<'a>(
5749        &'a self,
5750        include_ignored: bool,
5751        cx: &'a App,
5752    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
5753        self.worktree_store
5754            .read(cx)
5755            .visible_worktrees(cx)
5756            .filter_map(|worktree| {
5757                let worktree = worktree.read(cx);
5758                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
5759            })
5760            .flat_map(move |(worktree, summaries)| {
5761                let worktree_id = worktree.id();
5762                summaries
5763                    .iter()
5764                    .filter(move |(path, _)| {
5765                        include_ignored
5766                            || worktree
5767                                .entry_for_path(path.as_ref())
5768                                .map_or(false, |entry| !entry.is_ignored)
5769                    })
5770                    .flat_map(move |(path, summaries)| {
5771                        summaries.iter().map(move |(server_id, summary)| {
5772                            (
5773                                ProjectPath {
5774                                    worktree_id,
5775                                    path: path.clone(),
5776                                },
5777                                *server_id,
5778                                *summary,
5779                            )
5780                        })
5781                    })
5782            })
5783    }
5784
5785    pub fn on_buffer_edited(
5786        &mut self,
5787        buffer: Entity<Buffer>,
5788        cx: &mut Context<Self>,
5789    ) -> Option<()> {
5790        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
5791            Some(
5792                self.as_local()?
5793                    .language_servers_for_buffer(buffer, cx)
5794                    .map(|i| i.1.clone())
5795                    .collect(),
5796            )
5797        })?;
5798
5799        let buffer = buffer.read(cx);
5800        let file = File::from_dyn(buffer.file())?;
5801        let abs_path = file.as_local()?.abs_path(cx);
5802        let uri = lsp::Url::from_file_path(abs_path).unwrap();
5803        let next_snapshot = buffer.text_snapshot();
5804        for language_server in language_servers {
5805            let language_server = language_server.clone();
5806
5807            let buffer_snapshots = self
5808                .as_local_mut()
5809                .unwrap()
5810                .buffer_snapshots
5811                .get_mut(&buffer.remote_id())
5812                .and_then(|m| m.get_mut(&language_server.server_id()))?;
5813            let previous_snapshot = buffer_snapshots.last()?;
5814
5815            let build_incremental_change = || {
5816                buffer
5817                    .edits_since::<(PointUtf16, usize)>(previous_snapshot.snapshot.version())
5818                    .map(|edit| {
5819                        let edit_start = edit.new.start.0;
5820                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
5821                        let new_text = next_snapshot
5822                            .text_for_range(edit.new.start.1..edit.new.end.1)
5823                            .collect();
5824                        lsp::TextDocumentContentChangeEvent {
5825                            range: Some(lsp::Range::new(
5826                                point_to_lsp(edit_start),
5827                                point_to_lsp(edit_end),
5828                            )),
5829                            range_length: None,
5830                            text: new_text,
5831                        }
5832                    })
5833                    .collect()
5834            };
5835
5836            let document_sync_kind = language_server
5837                .capabilities()
5838                .text_document_sync
5839                .as_ref()
5840                .and_then(|sync| match sync {
5841                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
5842                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
5843                });
5844
5845            let content_changes: Vec<_> = match document_sync_kind {
5846                Some(lsp::TextDocumentSyncKind::FULL) => {
5847                    vec![lsp::TextDocumentContentChangeEvent {
5848                        range: None,
5849                        range_length: None,
5850                        text: next_snapshot.text(),
5851                    }]
5852                }
5853                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
5854                _ => {
5855                    #[cfg(any(test, feature = "test-support"))]
5856                    {
5857                        build_incremental_change()
5858                    }
5859
5860                    #[cfg(not(any(test, feature = "test-support")))]
5861                    {
5862                        continue;
5863                    }
5864                }
5865            };
5866
5867            let next_version = previous_snapshot.version + 1;
5868            buffer_snapshots.push(LspBufferSnapshot {
5869                version: next_version,
5870                snapshot: next_snapshot.clone(),
5871            });
5872
5873            language_server
5874                .notify::<lsp::notification::DidChangeTextDocument>(
5875                    &lsp::DidChangeTextDocumentParams {
5876                        text_document: lsp::VersionedTextDocumentIdentifier::new(
5877                            uri.clone(),
5878                            next_version,
5879                        ),
5880                        content_changes,
5881                    },
5882                )
5883                .log_err();
5884        }
5885
5886        None
5887    }
5888
5889    pub fn on_buffer_saved(
5890        &mut self,
5891        buffer: Entity<Buffer>,
5892        cx: &mut Context<Self>,
5893    ) -> Option<()> {
5894        let file = File::from_dyn(buffer.read(cx).file())?;
5895        let worktree_id = file.worktree_id(cx);
5896        let abs_path = file.as_local()?.abs_path(cx);
5897        let text_document = lsp::TextDocumentIdentifier {
5898            uri: lsp::Url::from_file_path(abs_path).log_err()?,
5899        };
5900        let local = self.as_local()?;
5901
5902        for server in local.language_servers_for_worktree(worktree_id) {
5903            if let Some(include_text) = include_text(server.as_ref()) {
5904                let text = if include_text {
5905                    Some(buffer.read(cx).text())
5906                } else {
5907                    None
5908                };
5909                server
5910                    .notify::<lsp::notification::DidSaveTextDocument>(
5911                        &lsp::DidSaveTextDocumentParams {
5912                            text_document: text_document.clone(),
5913                            text,
5914                        },
5915                    )
5916                    .log_err();
5917            }
5918        }
5919
5920        let language_servers = buffer.update(cx, |buffer, cx| {
5921            local.language_server_ids_for_buffer(buffer, cx)
5922        });
5923        for language_server_id in language_servers {
5924            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
5925        }
5926
5927        None
5928    }
5929
5930    pub(crate) async fn refresh_workspace_configurations(
5931        this: &WeakEntity<Self>,
5932        fs: Arc<dyn Fs>,
5933        cx: &mut AsyncApp,
5934    ) {
5935        maybe!(async move {
5936            let servers = this
5937                .update(cx, |this, cx| {
5938                    let Some(local) = this.as_local() else {
5939                        return Vec::default();
5940                    };
5941                    local
5942                        .language_server_ids
5943                        .iter()
5944                        .flat_map(|((worktree_id, _), server_ids)| {
5945                            let worktree = this
5946                                .worktree_store
5947                                .read(cx)
5948                                .worktree_for_id(*worktree_id, cx);
5949                            let delegate = worktree.map(|worktree| {
5950                                LocalLspAdapterDelegate::new(
5951                                    local.languages.clone(),
5952                                    &local.environment,
5953                                    cx.weak_entity(),
5954                                    &worktree,
5955                                    local.http_client.clone(),
5956                                    local.fs.clone(),
5957                                    cx,
5958                                )
5959                            });
5960
5961                            server_ids.iter().filter_map(move |server_id| {
5962                                let states = local.language_servers.get(server_id)?;
5963
5964                                match states {
5965                                    LanguageServerState::Starting { .. } => None,
5966                                    LanguageServerState::Running {
5967                                        adapter, server, ..
5968                                    } => Some((
5969                                        adapter.adapter.clone(),
5970                                        server.clone(),
5971                                        delegate.clone()? as Arc<dyn LspAdapterDelegate>,
5972                                    )),
5973                                }
5974                            })
5975                        })
5976                        .collect::<Vec<_>>()
5977                })
5978                .ok()?;
5979
5980            let toolchain_store = this.update(cx, |this, cx| this.toolchain_store(cx)).ok()?;
5981            for (adapter, server, delegate) in servers {
5982                let settings = adapter
5983                    .workspace_configuration(fs.as_ref(), &delegate, toolchain_store.clone(), cx)
5984                    .await
5985                    .ok()?;
5986
5987                server
5988                    .notify::<lsp::notification::DidChangeConfiguration>(
5989                        &lsp::DidChangeConfigurationParams { settings },
5990                    )
5991                    .ok();
5992            }
5993            Some(())
5994        })
5995        .await;
5996    }
5997
5998    fn toolchain_store(&self, cx: &App) -> Arc<dyn LanguageToolchainStore> {
5999        if let Some(toolchain_store) = self.toolchain_store.as_ref() {
6000            toolchain_store.read(cx).as_language_toolchain_store()
6001        } else {
6002            Arc::new(EmptyToolchainStore)
6003        }
6004    }
6005    fn maintain_workspace_config(
6006        fs: Arc<dyn Fs>,
6007        external_refresh_requests: watch::Receiver<()>,
6008        cx: &mut Context<Self>,
6009    ) -> Task<Result<()>> {
6010        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
6011        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
6012
6013        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
6014            *settings_changed_tx.borrow_mut() = ();
6015        });
6016
6017        let mut joint_future =
6018            futures::stream::select(settings_changed_rx, external_refresh_requests);
6019        cx.spawn(async move |this, cx| {
6020            while let Some(()) = joint_future.next().await {
6021                Self::refresh_workspace_configurations(&this, fs.clone(), cx).await;
6022            }
6023
6024            drop(settings_observation);
6025            anyhow::Ok(())
6026        })
6027    }
6028
6029    pub fn language_servers_for_local_buffer<'a>(
6030        &'a self,
6031        buffer: &Buffer,
6032        cx: &mut App,
6033    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
6034        let local = self.as_local();
6035        let language_server_ids = local
6036            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
6037            .unwrap_or_default();
6038
6039        language_server_ids
6040            .into_iter()
6041            .filter_map(
6042                move |server_id| match local?.language_servers.get(&server_id)? {
6043                    LanguageServerState::Running {
6044                        adapter, server, ..
6045                    } => Some((adapter, server)),
6046                    _ => None,
6047                },
6048            )
6049    }
6050
6051    pub fn language_server_for_local_buffer<'a>(
6052        &'a self,
6053        buffer: &'a Buffer,
6054        server_id: LanguageServerId,
6055        cx: &'a mut App,
6056    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
6057        self.as_local()?
6058            .language_servers_for_buffer(buffer, cx)
6059            .find(|(_, s)| s.server_id() == server_id)
6060    }
6061
6062    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
6063        self.diagnostic_summaries.remove(&id_to_remove);
6064        if let Some(local) = self.as_local_mut() {
6065            let to_remove = local.remove_worktree(id_to_remove, cx);
6066            for server in to_remove {
6067                self.language_server_statuses.remove(&server);
6068            }
6069        }
6070    }
6071
6072    pub fn shared(
6073        &mut self,
6074        project_id: u64,
6075        downstream_client: AnyProtoClient,
6076        _: &mut Context<Self>,
6077    ) {
6078        self.downstream_client = Some((downstream_client.clone(), project_id));
6079
6080        for (server_id, status) in &self.language_server_statuses {
6081            downstream_client
6082                .send(proto::StartLanguageServer {
6083                    project_id,
6084                    server: Some(proto::LanguageServer {
6085                        id: server_id.0 as u64,
6086                        name: status.name.clone(),
6087                        worktree_id: None,
6088                    }),
6089                })
6090                .log_err();
6091        }
6092    }
6093
6094    pub fn disconnected_from_host(&mut self) {
6095        self.downstream_client.take();
6096    }
6097
6098    pub fn disconnected_from_ssh_remote(&mut self) {
6099        if let LspStoreMode::Remote(RemoteLspStore {
6100            upstream_client, ..
6101        }) = &mut self.mode
6102        {
6103            upstream_client.take();
6104        }
6105    }
6106
6107    pub(crate) fn set_language_server_statuses_from_proto(
6108        &mut self,
6109        language_servers: Vec<proto::LanguageServer>,
6110    ) {
6111        self.language_server_statuses = language_servers
6112            .into_iter()
6113            .map(|server| {
6114                (
6115                    LanguageServerId(server.id as usize),
6116                    LanguageServerStatus {
6117                        name: server.name,
6118                        pending_work: Default::default(),
6119                        has_pending_diagnostic_updates: false,
6120                        progress_tokens: Default::default(),
6121                    },
6122                )
6123            })
6124            .collect();
6125    }
6126
6127    fn register_local_language_server(
6128        &mut self,
6129        worktree: Entity<Worktree>,
6130        language_server_name: LanguageServerName,
6131        language_server_id: LanguageServerId,
6132        cx: &mut App,
6133    ) {
6134        let Some(local) = self.as_local_mut() else {
6135            return;
6136        };
6137        let worktree_id = worktree.read(cx).id();
6138        let path = ProjectPath {
6139            worktree_id,
6140            path: Arc::from("".as_ref()),
6141        };
6142        let delegate = LocalLspAdapterDelegate::from_local_lsp(local, &worktree, cx);
6143        local.lsp_tree.update(cx, |this, cx| {
6144            for node in this.get(
6145                path,
6146                AdapterQuery::Adapter(&language_server_name),
6147                delegate,
6148                cx,
6149            ) {
6150                node.server_id_or_init(|disposition| {
6151                    assert_eq!(disposition.server_name, &language_server_name);
6152
6153                    language_server_id
6154                });
6155            }
6156        });
6157        local
6158            .language_server_ids
6159            .entry((worktree_id, language_server_name))
6160            .or_default()
6161            .insert(language_server_id);
6162    }
6163
6164    pub fn update_diagnostic_entries(
6165        &mut self,
6166        server_id: LanguageServerId,
6167        abs_path: PathBuf,
6168        version: Option<i32>,
6169        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
6170        cx: &mut Context<Self>,
6171    ) -> Result<(), anyhow::Error> {
6172        let Some((worktree, relative_path)) =
6173            self.worktree_store.read(cx).find_worktree(&abs_path, cx)
6174        else {
6175            log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
6176            return Ok(());
6177        };
6178
6179        let project_path = ProjectPath {
6180            worktree_id: worktree.read(cx).id(),
6181            path: relative_path.into(),
6182        };
6183
6184        if let Some(buffer) = self.buffer_store.read(cx).get_by_path(&project_path, cx) {
6185            self.as_local_mut().unwrap().update_buffer_diagnostics(
6186                &buffer,
6187                server_id,
6188                version,
6189                diagnostics.clone(),
6190                cx,
6191            )?;
6192        }
6193
6194        let updated = worktree.update(cx, |worktree, cx| {
6195            self.update_worktree_diagnostics(
6196                worktree.id(),
6197                server_id,
6198                project_path.path.clone(),
6199                diagnostics,
6200                cx,
6201            )
6202        })?;
6203        if updated {
6204            cx.emit(LspStoreEvent::DiagnosticsUpdated {
6205                language_server_id: server_id,
6206                path: project_path,
6207            })
6208        }
6209        Ok(())
6210    }
6211
6212    fn update_worktree_diagnostics(
6213        &mut self,
6214        worktree_id: WorktreeId,
6215        server_id: LanguageServerId,
6216        worktree_path: Arc<Path>,
6217        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
6218        _: &mut Context<Worktree>,
6219    ) -> Result<bool> {
6220        let local = match &mut self.mode {
6221            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
6222            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
6223        };
6224
6225        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
6226        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
6227        let summaries_by_server_id = summaries_for_tree.entry(worktree_path.clone()).or_default();
6228
6229        let old_summary = summaries_by_server_id
6230            .remove(&server_id)
6231            .unwrap_or_default();
6232
6233        let new_summary = DiagnosticSummary::new(&diagnostics);
6234        if new_summary.is_empty() {
6235            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&worktree_path) {
6236                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
6237                    diagnostics_by_server_id.remove(ix);
6238                }
6239                if diagnostics_by_server_id.is_empty() {
6240                    diagnostics_for_tree.remove(&worktree_path);
6241                }
6242            }
6243        } else {
6244            summaries_by_server_id.insert(server_id, new_summary);
6245            let diagnostics_by_server_id = diagnostics_for_tree
6246                .entry(worktree_path.clone())
6247                .or_default();
6248            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
6249                Ok(ix) => {
6250                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
6251                }
6252                Err(ix) => {
6253                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
6254                }
6255            }
6256        }
6257
6258        if !old_summary.is_empty() || !new_summary.is_empty() {
6259            if let Some((downstream_client, project_id)) = &self.downstream_client {
6260                downstream_client
6261                    .send(proto::UpdateDiagnosticSummary {
6262                        project_id: *project_id,
6263                        worktree_id: worktree_id.to_proto(),
6264                        summary: Some(proto::DiagnosticSummary {
6265                            path: worktree_path.to_proto(),
6266                            language_server_id: server_id.0 as u64,
6267                            error_count: new_summary.error_count as u32,
6268                            warning_count: new_summary.warning_count as u32,
6269                        }),
6270                    })
6271                    .log_err();
6272            }
6273        }
6274
6275        Ok(!old_summary.is_empty() || !new_summary.is_empty())
6276    }
6277
6278    pub fn open_buffer_for_symbol(
6279        &mut self,
6280        symbol: &Symbol,
6281        cx: &mut Context<Self>,
6282    ) -> Task<Result<Entity<Buffer>>> {
6283        if let Some((client, project_id)) = self.upstream_client() {
6284            let request = client.request(proto::OpenBufferForSymbol {
6285                project_id,
6286                symbol: Some(Self::serialize_symbol(symbol)),
6287            });
6288            cx.spawn(async move |this, cx| {
6289                let response = request.await?;
6290                let buffer_id = BufferId::new(response.buffer_id)?;
6291                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
6292                    .await
6293            })
6294        } else if let Some(local) = self.as_local() {
6295            let Some(language_server_id) = local
6296                .language_server_ids
6297                .get(&(
6298                    symbol.source_worktree_id,
6299                    symbol.language_server_name.clone(),
6300                ))
6301                .and_then(|ids| {
6302                    ids.contains(&symbol.source_language_server_id)
6303                        .then_some(symbol.source_language_server_id)
6304                })
6305            else {
6306                return Task::ready(Err(anyhow!(
6307                    "language server for worktree and language not found"
6308                )));
6309            };
6310
6311            let worktree_abs_path = if let Some(worktree_abs_path) = self
6312                .worktree_store
6313                .read(cx)
6314                .worktree_for_id(symbol.path.worktree_id, cx)
6315                .map(|worktree| worktree.read(cx).abs_path())
6316            {
6317                worktree_abs_path
6318            } else {
6319                return Task::ready(Err(anyhow!("worktree not found for symbol")));
6320            };
6321
6322            let symbol_abs_path = resolve_path(&worktree_abs_path, &symbol.path.path);
6323            let symbol_uri = if let Ok(uri) = lsp::Url::from_file_path(symbol_abs_path) {
6324                uri
6325            } else {
6326                return Task::ready(Err(anyhow!("invalid symbol path")));
6327            };
6328
6329            self.open_local_buffer_via_lsp(
6330                symbol_uri,
6331                language_server_id,
6332                symbol.language_server_name.clone(),
6333                cx,
6334            )
6335        } else {
6336            Task::ready(Err(anyhow!("no upstream client or local store")))
6337        }
6338    }
6339
6340    pub fn open_local_buffer_via_lsp(
6341        &mut self,
6342        mut abs_path: lsp::Url,
6343        language_server_id: LanguageServerId,
6344        language_server_name: LanguageServerName,
6345        cx: &mut Context<Self>,
6346    ) -> Task<Result<Entity<Buffer>>> {
6347        cx.spawn(async move |lsp_store, cx| {
6348            // Escape percent-encoded string.
6349            let current_scheme = abs_path.scheme().to_owned();
6350            let _ = abs_path.set_scheme("file");
6351
6352            let abs_path = abs_path
6353                .to_file_path()
6354                .map_err(|_| anyhow!("can't convert URI to path"))?;
6355            let p = abs_path.clone();
6356            let yarn_worktree = lsp_store
6357                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
6358                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
6359                        cx.spawn(async move |this, cx| {
6360                            let t = this
6361                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
6362                                .ok()?;
6363                            t.await
6364                        })
6365                    }),
6366                    None => Task::ready(None),
6367                })?
6368                .await;
6369            let (worktree_root_target, known_relative_path) =
6370                if let Some((zip_root, relative_path)) = yarn_worktree {
6371                    (zip_root, Some(relative_path))
6372                } else {
6373                    (Arc::<Path>::from(abs_path.as_path()), None)
6374                };
6375            let (worktree, relative_path) = if let Some(result) =
6376                lsp_store.update(cx, |lsp_store, cx| {
6377                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
6378                        worktree_store.find_worktree(&worktree_root_target, cx)
6379                    })
6380                })? {
6381                let relative_path =
6382                    known_relative_path.unwrap_or_else(|| Arc::<Path>::from(result.1));
6383                (result.0, relative_path)
6384            } else {
6385                let worktree = lsp_store
6386                    .update(cx, |lsp_store, cx| {
6387                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
6388                            worktree_store.create_worktree(&worktree_root_target, false, cx)
6389                        })
6390                    })?
6391                    .await?;
6392                if worktree.update(cx, |worktree, _| worktree.is_local())? {
6393                    lsp_store
6394                        .update(cx, |lsp_store, cx| {
6395                            lsp_store.register_local_language_server(
6396                                worktree.clone(),
6397                                language_server_name,
6398                                language_server_id,
6399                                cx,
6400                            )
6401                        })
6402                        .ok();
6403                }
6404                let worktree_root = worktree.update(cx, |worktree, _| worktree.abs_path())?;
6405                let relative_path = if let Some(known_path) = known_relative_path {
6406                    known_path
6407                } else {
6408                    abs_path.strip_prefix(worktree_root)?.into()
6409                };
6410                (worktree, relative_path)
6411            };
6412            let project_path = ProjectPath {
6413                worktree_id: worktree.update(cx, |worktree, _| worktree.id())?,
6414                path: relative_path,
6415            };
6416            lsp_store
6417                .update(cx, |lsp_store, cx| {
6418                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
6419                        buffer_store.open_buffer(project_path, cx)
6420                    })
6421                })?
6422                .await
6423        })
6424    }
6425
6426    fn request_multiple_lsp_locally<P, R>(
6427        &mut self,
6428        buffer: &Entity<Buffer>,
6429        position: Option<P>,
6430        request: R,
6431        cx: &mut Context<'_, Self>,
6432    ) -> Task<Vec<R::Response>>
6433    where
6434        P: ToOffset,
6435        R: LspCommand + Clone,
6436        <R::LspRequest as lsp::request::Request>::Result: Send,
6437        <R::LspRequest as lsp::request::Request>::Params: Send,
6438    {
6439        let Some(local) = self.as_local() else {
6440            return Task::ready(Vec::new());
6441        };
6442
6443        let snapshot = buffer.read(cx).snapshot();
6444        let scope = position.and_then(|position| snapshot.language_scope_at(position));
6445
6446        let server_ids = buffer.update(cx, |buffer, cx| {
6447            local
6448                .language_servers_for_buffer(buffer, cx)
6449                .filter(|(adapter, _)| {
6450                    scope
6451                        .as_ref()
6452                        .map(|scope| scope.language_allowed(&adapter.name))
6453                        .unwrap_or(true)
6454                })
6455                .map(|(_, server)| server.server_id())
6456                .collect::<Vec<_>>()
6457        });
6458
6459        let mut response_results = server_ids
6460            .into_iter()
6461            .map(|server_id| {
6462                self.request_lsp(
6463                    buffer.clone(),
6464                    LanguageServerToQuery::Other(server_id),
6465                    request.clone(),
6466                    cx,
6467                )
6468            })
6469            .collect::<FuturesUnordered<_>>();
6470
6471        cx.spawn(async move |_, _| {
6472            let mut responses = Vec::with_capacity(response_results.len());
6473            while let Some(response_result) = response_results.next().await {
6474                if let Some(response) = response_result.log_err() {
6475                    responses.push(response);
6476                }
6477            }
6478            responses
6479        })
6480    }
6481
6482    async fn handle_lsp_command<T: LspCommand>(
6483        this: Entity<Self>,
6484        envelope: TypedEnvelope<T::ProtoRequest>,
6485        mut cx: AsyncApp,
6486    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
6487    where
6488        <T::LspRequest as lsp::request::Request>::Params: Send,
6489        <T::LspRequest as lsp::request::Request>::Result: Send,
6490    {
6491        let sender_id = envelope.original_sender_id().unwrap_or_default();
6492        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
6493        let buffer_handle = this.update(&mut cx, |this, cx| {
6494            this.buffer_store.read(cx).get_existing(buffer_id)
6495        })??;
6496        let request = T::from_proto(
6497            envelope.payload,
6498            this.clone(),
6499            buffer_handle.clone(),
6500            cx.clone(),
6501        )
6502        .await?;
6503        let response = this
6504            .update(&mut cx, |this, cx| {
6505                this.request_lsp(
6506                    buffer_handle.clone(),
6507                    LanguageServerToQuery::FirstCapable,
6508                    request,
6509                    cx,
6510                )
6511            })?
6512            .await?;
6513        this.update(&mut cx, |this, cx| {
6514            Ok(T::response_to_proto(
6515                response,
6516                this,
6517                sender_id,
6518                &buffer_handle.read(cx).version(),
6519                cx,
6520            ))
6521        })?
6522    }
6523
6524    async fn handle_multi_lsp_query(
6525        this: Entity<Self>,
6526        envelope: TypedEnvelope<proto::MultiLspQuery>,
6527        mut cx: AsyncApp,
6528    ) -> Result<proto::MultiLspQueryResponse> {
6529        let response_from_ssh = this.update(&mut cx, |this, _| {
6530            let (upstream_client, project_id) = this.upstream_client()?;
6531            let mut payload = envelope.payload.clone();
6532            payload.project_id = project_id;
6533
6534            Some(upstream_client.request(payload))
6535        })?;
6536        if let Some(response_from_ssh) = response_from_ssh {
6537            return response_from_ssh.await;
6538        }
6539
6540        let sender_id = envelope.original_sender_id().unwrap_or_default();
6541        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
6542        let version = deserialize_version(&envelope.payload.version);
6543        let buffer = this.update(&mut cx, |this, cx| {
6544            this.buffer_store.read(cx).get_existing(buffer_id)
6545        })??;
6546        buffer
6547            .update(&mut cx, |buffer, _| {
6548                buffer.wait_for_version(version.clone())
6549            })?
6550            .await?;
6551        let buffer_version = buffer.update(&mut cx, |buffer, _| buffer.version())?;
6552        match envelope
6553            .payload
6554            .strategy
6555            .context("invalid request without the strategy")?
6556        {
6557            proto::multi_lsp_query::Strategy::All(_) => {
6558                // currently, there's only one multiple language servers query strategy,
6559                // so just ensure it's specified correctly
6560            }
6561        }
6562        match envelope.payload.request {
6563            Some(proto::multi_lsp_query::Request::GetHover(get_hover)) => {
6564                let get_hover =
6565                    GetHover::from_proto(get_hover, this.clone(), buffer.clone(), cx.clone())
6566                        .await?;
6567                let all_hovers = this
6568                    .update(&mut cx, |this, cx| {
6569                        this.request_multiple_lsp_locally(
6570                            &buffer,
6571                            Some(get_hover.position),
6572                            get_hover,
6573                            cx,
6574                        )
6575                    })?
6576                    .await
6577                    .into_iter()
6578                    .filter_map(|hover| remove_empty_hover_blocks(hover?));
6579                this.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
6580                    responses: all_hovers
6581                        .map(|hover| proto::LspResponse {
6582                            response: Some(proto::lsp_response::Response::GetHoverResponse(
6583                                GetHover::response_to_proto(
6584                                    Some(hover),
6585                                    project,
6586                                    sender_id,
6587                                    &buffer_version,
6588                                    cx,
6589                                ),
6590                            )),
6591                        })
6592                        .collect(),
6593                })
6594            }
6595            Some(proto::multi_lsp_query::Request::GetCodeActions(get_code_actions)) => {
6596                let get_code_actions = GetCodeActions::from_proto(
6597                    get_code_actions,
6598                    this.clone(),
6599                    buffer.clone(),
6600                    cx.clone(),
6601                )
6602                .await?;
6603
6604                let all_actions = this
6605                    .update(&mut cx, |project, cx| {
6606                        project.request_multiple_lsp_locally(
6607                            &buffer,
6608                            Some(get_code_actions.range.start),
6609                            get_code_actions,
6610                            cx,
6611                        )
6612                    })?
6613                    .await
6614                    .into_iter();
6615
6616                this.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
6617                    responses: all_actions
6618                        .map(|code_actions| proto::LspResponse {
6619                            response: Some(proto::lsp_response::Response::GetCodeActionsResponse(
6620                                GetCodeActions::response_to_proto(
6621                                    code_actions,
6622                                    project,
6623                                    sender_id,
6624                                    &buffer_version,
6625                                    cx,
6626                                ),
6627                            )),
6628                        })
6629                        .collect(),
6630                })
6631            }
6632            Some(proto::multi_lsp_query::Request::GetSignatureHelp(get_signature_help)) => {
6633                let get_signature_help = GetSignatureHelp::from_proto(
6634                    get_signature_help,
6635                    this.clone(),
6636                    buffer.clone(),
6637                    cx.clone(),
6638                )
6639                .await?;
6640
6641                let all_signatures = this
6642                    .update(&mut cx, |project, cx| {
6643                        project.request_multiple_lsp_locally(
6644                            &buffer,
6645                            Some(get_signature_help.position),
6646                            get_signature_help,
6647                            cx,
6648                        )
6649                    })?
6650                    .await
6651                    .into_iter();
6652
6653                this.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
6654                    responses: all_signatures
6655                        .map(|signature_help| proto::LspResponse {
6656                            response: Some(
6657                                proto::lsp_response::Response::GetSignatureHelpResponse(
6658                                    GetSignatureHelp::response_to_proto(
6659                                        signature_help,
6660                                        project,
6661                                        sender_id,
6662                                        &buffer_version,
6663                                        cx,
6664                                    ),
6665                                ),
6666                            ),
6667                        })
6668                        .collect(),
6669                })
6670            }
6671            Some(proto::multi_lsp_query::Request::GetCodeLens(get_code_lens)) => {
6672                let get_code_lens = GetCodeLens::from_proto(
6673                    get_code_lens,
6674                    this.clone(),
6675                    buffer.clone(),
6676                    cx.clone(),
6677                )
6678                .await?;
6679
6680                let code_lens_actions = this
6681                    .update(&mut cx, |project, cx| {
6682                        project.request_multiple_lsp_locally(
6683                            &buffer,
6684                            None::<usize>,
6685                            get_code_lens,
6686                            cx,
6687                        )
6688                    })?
6689                    .await
6690                    .into_iter();
6691
6692                this.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
6693                    responses: code_lens_actions
6694                        .map(|actions| proto::LspResponse {
6695                            response: Some(proto::lsp_response::Response::GetCodeLensResponse(
6696                                GetCodeLens::response_to_proto(
6697                                    actions,
6698                                    project,
6699                                    sender_id,
6700                                    &buffer_version,
6701                                    cx,
6702                                ),
6703                            )),
6704                        })
6705                        .collect(),
6706                })
6707            }
6708            None => anyhow::bail!("empty multi lsp query request"),
6709        }
6710    }
6711
6712    async fn handle_apply_code_action(
6713        this: Entity<Self>,
6714        envelope: TypedEnvelope<proto::ApplyCodeAction>,
6715        mut cx: AsyncApp,
6716    ) -> Result<proto::ApplyCodeActionResponse> {
6717        let sender_id = envelope.original_sender_id().unwrap_or_default();
6718        let action = Self::deserialize_code_action(
6719            envelope
6720                .payload
6721                .action
6722                .ok_or_else(|| anyhow!("invalid action"))?,
6723        )?;
6724        let apply_code_action = this.update(&mut cx, |this, cx| {
6725            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
6726            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
6727            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
6728        })??;
6729
6730        let project_transaction = apply_code_action.await?;
6731        let project_transaction = this.update(&mut cx, |this, cx| {
6732            this.buffer_store.update(cx, |buffer_store, cx| {
6733                buffer_store.serialize_project_transaction_for_peer(
6734                    project_transaction,
6735                    sender_id,
6736                    cx,
6737                )
6738            })
6739        })?;
6740        Ok(proto::ApplyCodeActionResponse {
6741            transaction: Some(project_transaction),
6742        })
6743    }
6744
6745    async fn handle_register_buffer_with_language_servers(
6746        this: Entity<Self>,
6747        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
6748        mut cx: AsyncApp,
6749    ) -> Result<proto::Ack> {
6750        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
6751        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
6752        this.update(&mut cx, |this, cx| {
6753            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
6754                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
6755                    project_id: upstream_project_id,
6756                    buffer_id: buffer_id.to_proto(),
6757                });
6758            }
6759
6760            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
6761                anyhow::bail!("buffer is not open");
6762            };
6763
6764            let handle = this.register_buffer_with_language_servers(&buffer, false, cx);
6765            this.buffer_store().update(cx, |buffer_store, _| {
6766                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
6767            });
6768
6769            Ok(())
6770        })??;
6771        Ok(proto::Ack {})
6772    }
6773
6774    async fn handle_rename_project_entry(
6775        this: Entity<Self>,
6776        envelope: TypedEnvelope<proto::RenameProjectEntry>,
6777        mut cx: AsyncApp,
6778    ) -> Result<proto::ProjectEntryResponse> {
6779        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
6780        let (worktree_id, worktree, old_path, is_dir) = this
6781            .update(&mut cx, |this, cx| {
6782                this.worktree_store
6783                    .read(cx)
6784                    .worktree_and_entry_for_id(entry_id, cx)
6785                    .map(|(worktree, entry)| {
6786                        (
6787                            worktree.read(cx).id(),
6788                            worktree,
6789                            entry.path.clone(),
6790                            entry.is_dir(),
6791                        )
6792                    })
6793            })?
6794            .ok_or_else(|| anyhow!("worktree not found"))?;
6795        let (old_abs_path, new_abs_path) = {
6796            let root_path = worktree.update(&mut cx, |this, _| this.abs_path())?;
6797            let new_path = PathBuf::from_proto(envelope.payload.new_path.clone());
6798            (root_path.join(&old_path), root_path.join(&new_path))
6799        };
6800
6801        Self::will_rename_entry(
6802            this.downgrade(),
6803            worktree_id,
6804            &old_abs_path,
6805            &new_abs_path,
6806            is_dir,
6807            cx.clone(),
6808        )
6809        .await;
6810        let response = Worktree::handle_rename_entry(worktree, envelope.payload, cx.clone()).await;
6811        this.update(&mut cx, |this, _| {
6812            this.did_rename_entry(worktree_id, &old_abs_path, &new_abs_path, is_dir);
6813        })
6814        .ok();
6815        response
6816    }
6817
6818    async fn handle_update_diagnostic_summary(
6819        this: Entity<Self>,
6820        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
6821        mut cx: AsyncApp,
6822    ) -> Result<()> {
6823        this.update(&mut cx, |this, cx| {
6824            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
6825            if let Some(message) = envelope.payload.summary {
6826                let project_path = ProjectPath {
6827                    worktree_id,
6828                    path: Arc::<Path>::from_proto(message.path),
6829                };
6830                let path = project_path.path.clone();
6831                let server_id = LanguageServerId(message.language_server_id as usize);
6832                let summary = DiagnosticSummary {
6833                    error_count: message.error_count as usize,
6834                    warning_count: message.warning_count as usize,
6835                };
6836
6837                if summary.is_empty() {
6838                    if let Some(worktree_summaries) =
6839                        this.diagnostic_summaries.get_mut(&worktree_id)
6840                    {
6841                        if let Some(summaries) = worktree_summaries.get_mut(&path) {
6842                            summaries.remove(&server_id);
6843                            if summaries.is_empty() {
6844                                worktree_summaries.remove(&path);
6845                            }
6846                        }
6847                    }
6848                } else {
6849                    this.diagnostic_summaries
6850                        .entry(worktree_id)
6851                        .or_default()
6852                        .entry(path)
6853                        .or_default()
6854                        .insert(server_id, summary);
6855                }
6856                if let Some((downstream_client, project_id)) = &this.downstream_client {
6857                    downstream_client
6858                        .send(proto::UpdateDiagnosticSummary {
6859                            project_id: *project_id,
6860                            worktree_id: worktree_id.to_proto(),
6861                            summary: Some(proto::DiagnosticSummary {
6862                                path: project_path.path.as_ref().to_proto(),
6863                                language_server_id: server_id.0 as u64,
6864                                error_count: summary.error_count as u32,
6865                                warning_count: summary.warning_count as u32,
6866                            }),
6867                        })
6868                        .log_err();
6869                }
6870                cx.emit(LspStoreEvent::DiagnosticsUpdated {
6871                    language_server_id: LanguageServerId(message.language_server_id as usize),
6872                    path: project_path,
6873                });
6874            }
6875            Ok(())
6876        })?
6877    }
6878
6879    async fn handle_start_language_server(
6880        this: Entity<Self>,
6881        envelope: TypedEnvelope<proto::StartLanguageServer>,
6882        mut cx: AsyncApp,
6883    ) -> Result<()> {
6884        let server = envelope
6885            .payload
6886            .server
6887            .ok_or_else(|| anyhow!("invalid server"))?;
6888
6889        this.update(&mut cx, |this, cx| {
6890            let server_id = LanguageServerId(server.id as usize);
6891            this.language_server_statuses.insert(
6892                server_id,
6893                LanguageServerStatus {
6894                    name: server.name.clone(),
6895                    pending_work: Default::default(),
6896                    has_pending_diagnostic_updates: false,
6897                    progress_tokens: Default::default(),
6898                },
6899            );
6900            cx.emit(LspStoreEvent::LanguageServerAdded(
6901                server_id,
6902                LanguageServerName(server.name.into()),
6903                server.worktree_id.map(WorktreeId::from_proto),
6904            ));
6905            cx.notify();
6906        })?;
6907        Ok(())
6908    }
6909
6910    async fn handle_update_language_server(
6911        this: Entity<Self>,
6912        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
6913        mut cx: AsyncApp,
6914    ) -> Result<()> {
6915        this.update(&mut cx, |this, cx| {
6916            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
6917
6918            match envelope
6919                .payload
6920                .variant
6921                .ok_or_else(|| anyhow!("invalid variant"))?
6922            {
6923                proto::update_language_server::Variant::WorkStart(payload) => {
6924                    this.on_lsp_work_start(
6925                        language_server_id,
6926                        payload.token,
6927                        LanguageServerProgress {
6928                            title: payload.title,
6929                            is_disk_based_diagnostics_progress: false,
6930                            is_cancellable: payload.is_cancellable.unwrap_or(false),
6931                            message: payload.message,
6932                            percentage: payload.percentage.map(|p| p as usize),
6933                            last_update_at: cx.background_executor().now(),
6934                        },
6935                        cx,
6936                    );
6937                }
6938
6939                proto::update_language_server::Variant::WorkProgress(payload) => {
6940                    this.on_lsp_work_progress(
6941                        language_server_id,
6942                        payload.token,
6943                        LanguageServerProgress {
6944                            title: None,
6945                            is_disk_based_diagnostics_progress: false,
6946                            is_cancellable: payload.is_cancellable.unwrap_or(false),
6947                            message: payload.message,
6948                            percentage: payload.percentage.map(|p| p as usize),
6949                            last_update_at: cx.background_executor().now(),
6950                        },
6951                        cx,
6952                    );
6953                }
6954
6955                proto::update_language_server::Variant::WorkEnd(payload) => {
6956                    this.on_lsp_work_end(language_server_id, payload.token, cx);
6957                }
6958
6959                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
6960                    this.disk_based_diagnostics_started(language_server_id, cx);
6961                }
6962
6963                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
6964                    this.disk_based_diagnostics_finished(language_server_id, cx)
6965                }
6966            }
6967
6968            Ok(())
6969        })?
6970    }
6971
6972    async fn handle_language_server_log(
6973        this: Entity<Self>,
6974        envelope: TypedEnvelope<proto::LanguageServerLog>,
6975        mut cx: AsyncApp,
6976    ) -> Result<()> {
6977        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
6978        let log_type = envelope
6979            .payload
6980            .log_type
6981            .map(LanguageServerLogType::from_proto)
6982            .context("invalid language server log type")?;
6983
6984        let message = envelope.payload.message;
6985
6986        this.update(&mut cx, |_, cx| {
6987            cx.emit(LspStoreEvent::LanguageServerLog(
6988                language_server_id,
6989                log_type,
6990                message,
6991            ));
6992        })
6993    }
6994
6995    pub fn disk_based_diagnostics_started(
6996        &mut self,
6997        language_server_id: LanguageServerId,
6998        cx: &mut Context<Self>,
6999    ) {
7000        if let Some(language_server_status) =
7001            self.language_server_statuses.get_mut(&language_server_id)
7002        {
7003            language_server_status.has_pending_diagnostic_updates = true;
7004        }
7005
7006        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
7007        cx.emit(LspStoreEvent::LanguageServerUpdate {
7008            language_server_id,
7009            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
7010                Default::default(),
7011            ),
7012        })
7013    }
7014
7015    pub fn disk_based_diagnostics_finished(
7016        &mut self,
7017        language_server_id: LanguageServerId,
7018        cx: &mut Context<Self>,
7019    ) {
7020        if let Some(language_server_status) =
7021            self.language_server_statuses.get_mut(&language_server_id)
7022        {
7023            language_server_status.has_pending_diagnostic_updates = false;
7024        }
7025
7026        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
7027        cx.emit(LspStoreEvent::LanguageServerUpdate {
7028            language_server_id,
7029            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
7030                Default::default(),
7031            ),
7032        })
7033    }
7034
7035    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
7036    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
7037    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
7038    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
7039    // the language server might take some time to publish diagnostics.
7040    fn simulate_disk_based_diagnostics_events_if_needed(
7041        &mut self,
7042        language_server_id: LanguageServerId,
7043        cx: &mut Context<Self>,
7044    ) {
7045        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
7046
7047        let Some(LanguageServerState::Running {
7048            simulate_disk_based_diagnostics_completion,
7049            adapter,
7050            ..
7051        }) = self
7052            .as_local_mut()
7053            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
7054        else {
7055            return;
7056        };
7057
7058        if adapter.disk_based_diagnostics_progress_token.is_some() {
7059            return;
7060        }
7061
7062        let prev_task =
7063            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
7064                cx.background_executor()
7065                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
7066                    .await;
7067
7068                this.update(cx, |this, cx| {
7069                    this.disk_based_diagnostics_finished(language_server_id, cx);
7070
7071                    if let Some(LanguageServerState::Running {
7072                        simulate_disk_based_diagnostics_completion,
7073                        ..
7074                    }) = this.as_local_mut().and_then(|local_store| {
7075                        local_store.language_servers.get_mut(&language_server_id)
7076                    }) {
7077                        *simulate_disk_based_diagnostics_completion = None;
7078                    }
7079                })
7080                .ok();
7081            }));
7082
7083        if prev_task.is_none() {
7084            self.disk_based_diagnostics_started(language_server_id, cx);
7085        }
7086    }
7087
7088    pub fn language_server_statuses(
7089        &self,
7090    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
7091        self.language_server_statuses
7092            .iter()
7093            .map(|(key, value)| (*key, value))
7094    }
7095
7096    pub(super) fn did_rename_entry(
7097        &self,
7098        worktree_id: WorktreeId,
7099        old_path: &Path,
7100        new_path: &Path,
7101        is_dir: bool,
7102    ) {
7103        maybe!({
7104            let local_store = self.as_local()?;
7105
7106            let old_uri = lsp::Url::from_file_path(old_path).ok().map(String::from)?;
7107            let new_uri = lsp::Url::from_file_path(new_path).ok().map(String::from)?;
7108
7109            for language_server in local_store.language_servers_for_worktree(worktree_id) {
7110                let Some(filter) = local_store
7111                    .language_server_paths_watched_for_rename
7112                    .get(&language_server.server_id())
7113                else {
7114                    continue;
7115                };
7116
7117                if filter.should_send_did_rename(&old_uri, is_dir) {
7118                    language_server
7119                        .notify::<DidRenameFiles>(&RenameFilesParams {
7120                            files: vec![FileRename {
7121                                old_uri: old_uri.clone(),
7122                                new_uri: new_uri.clone(),
7123                            }],
7124                        })
7125                        .log_err();
7126                }
7127            }
7128            Some(())
7129        });
7130    }
7131
7132    pub(super) fn will_rename_entry(
7133        this: WeakEntity<Self>,
7134        worktree_id: WorktreeId,
7135        old_path: &Path,
7136        new_path: &Path,
7137        is_dir: bool,
7138        cx: AsyncApp,
7139    ) -> Task<()> {
7140        let old_uri = lsp::Url::from_file_path(old_path).ok().map(String::from);
7141        let new_uri = lsp::Url::from_file_path(new_path).ok().map(String::from);
7142        cx.spawn(async move |cx| {
7143            let mut tasks = vec![];
7144            this.update(cx, |this, cx| {
7145                let local_store = this.as_local()?;
7146                let old_uri = old_uri?;
7147                let new_uri = new_uri?;
7148                for language_server in local_store.language_servers_for_worktree(worktree_id) {
7149                    let Some(filter) = local_store
7150                        .language_server_paths_watched_for_rename
7151                        .get(&language_server.server_id())
7152                    else {
7153                        continue;
7154                    };
7155                    let Some(adapter) =
7156                        this.language_server_adapter_for_id(language_server.server_id())
7157                    else {
7158                        continue;
7159                    };
7160                    if filter.should_send_will_rename(&old_uri, is_dir) {
7161                        let apply_edit = cx.spawn({
7162                            let old_uri = old_uri.clone();
7163                            let new_uri = new_uri.clone();
7164                            let language_server = language_server.clone();
7165                            async move |this, cx| {
7166                                let edit = language_server
7167                                    .request::<WillRenameFiles>(RenameFilesParams {
7168                                        files: vec![FileRename { old_uri, new_uri }],
7169                                    })
7170                                    .log_err()
7171                                    .await
7172                                    .flatten()?;
7173
7174                                LocalLspStore::deserialize_workspace_edit(
7175                                    this.upgrade()?,
7176                                    edit,
7177                                    false,
7178                                    adapter.clone(),
7179                                    language_server.clone(),
7180                                    cx,
7181                                )
7182                                .await
7183                                .ok();
7184                                Some(())
7185                            }
7186                        });
7187                        tasks.push(apply_edit);
7188                    }
7189                }
7190                Some(())
7191            })
7192            .ok()
7193            .flatten();
7194            for task in tasks {
7195                // Await on tasks sequentially so that the order of application of edits is deterministic
7196                // (at least with regards to the order of registration of language servers)
7197                task.await;
7198            }
7199        })
7200    }
7201
7202    fn lsp_notify_abs_paths_changed(
7203        &mut self,
7204        server_id: LanguageServerId,
7205        changes: Vec<PathEvent>,
7206    ) {
7207        maybe!({
7208            let server = self.language_server_for_id(server_id)?;
7209            let changes = changes
7210                .into_iter()
7211                .filter_map(|event| {
7212                    let typ = match event.kind? {
7213                        PathEventKind::Created => lsp::FileChangeType::CREATED,
7214                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
7215                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
7216                    };
7217                    Some(lsp::FileEvent {
7218                        uri: lsp::Url::from_file_path(&event.path).ok()?,
7219                        typ,
7220                    })
7221                })
7222                .collect::<Vec<_>>();
7223            if !changes.is_empty() {
7224                server
7225                    .notify::<lsp::notification::DidChangeWatchedFiles>(
7226                        &lsp::DidChangeWatchedFilesParams { changes },
7227                    )
7228                    .log_err();
7229            }
7230            Some(())
7231        });
7232    }
7233
7234    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
7235        let local_lsp_store = self.as_local()?;
7236        if let Some(LanguageServerState::Running { server, .. }) =
7237            local_lsp_store.language_servers.get(&id)
7238        {
7239            Some(server.clone())
7240        } else if let Some((_, server)) = local_lsp_store.supplementary_language_servers.get(&id) {
7241            Some(Arc::clone(server))
7242        } else {
7243            None
7244        }
7245    }
7246
7247    fn on_lsp_progress(
7248        &mut self,
7249        progress: lsp::ProgressParams,
7250        language_server_id: LanguageServerId,
7251        disk_based_diagnostics_progress_token: Option<String>,
7252        cx: &mut Context<Self>,
7253    ) {
7254        let token = match progress.token {
7255            lsp::NumberOrString::String(token) => token,
7256            lsp::NumberOrString::Number(token) => {
7257                log::info!("skipping numeric progress token {}", token);
7258                return;
7259            }
7260        };
7261
7262        let lsp::ProgressParamsValue::WorkDone(progress) = progress.value;
7263        let language_server_status =
7264            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
7265                status
7266            } else {
7267                return;
7268            };
7269
7270        if !language_server_status.progress_tokens.contains(&token) {
7271            return;
7272        }
7273
7274        let is_disk_based_diagnostics_progress = disk_based_diagnostics_progress_token
7275            .as_ref()
7276            .map_or(false, |disk_based_token| {
7277                token.starts_with(disk_based_token)
7278            });
7279
7280        match progress {
7281            lsp::WorkDoneProgress::Begin(report) => {
7282                if is_disk_based_diagnostics_progress {
7283                    self.disk_based_diagnostics_started(language_server_id, cx);
7284                }
7285                self.on_lsp_work_start(
7286                    language_server_id,
7287                    token.clone(),
7288                    LanguageServerProgress {
7289                        title: Some(report.title),
7290                        is_disk_based_diagnostics_progress,
7291                        is_cancellable: report.cancellable.unwrap_or(false),
7292                        message: report.message.clone(),
7293                        percentage: report.percentage.map(|p| p as usize),
7294                        last_update_at: cx.background_executor().now(),
7295                    },
7296                    cx,
7297                );
7298            }
7299            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
7300                language_server_id,
7301                token,
7302                LanguageServerProgress {
7303                    title: None,
7304                    is_disk_based_diagnostics_progress,
7305                    is_cancellable: report.cancellable.unwrap_or(false),
7306                    message: report.message,
7307                    percentage: report.percentage.map(|p| p as usize),
7308                    last_update_at: cx.background_executor().now(),
7309                },
7310                cx,
7311            ),
7312            lsp::WorkDoneProgress::End(_) => {
7313                language_server_status.progress_tokens.remove(&token);
7314                self.on_lsp_work_end(language_server_id, token.clone(), cx);
7315                if is_disk_based_diagnostics_progress {
7316                    self.disk_based_diagnostics_finished(language_server_id, cx);
7317                }
7318            }
7319        }
7320    }
7321
7322    fn on_lsp_work_start(
7323        &mut self,
7324        language_server_id: LanguageServerId,
7325        token: String,
7326        progress: LanguageServerProgress,
7327        cx: &mut Context<Self>,
7328    ) {
7329        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
7330            status.pending_work.insert(token.clone(), progress.clone());
7331            cx.notify();
7332        }
7333        cx.emit(LspStoreEvent::LanguageServerUpdate {
7334            language_server_id,
7335            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
7336                token,
7337                title: progress.title,
7338                message: progress.message,
7339                percentage: progress.percentage.map(|p| p as u32),
7340                is_cancellable: Some(progress.is_cancellable),
7341            }),
7342        })
7343    }
7344
7345    fn on_lsp_work_progress(
7346        &mut self,
7347        language_server_id: LanguageServerId,
7348        token: String,
7349        progress: LanguageServerProgress,
7350        cx: &mut Context<Self>,
7351    ) {
7352        let mut did_update = false;
7353        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
7354            match status.pending_work.entry(token.clone()) {
7355                btree_map::Entry::Vacant(entry) => {
7356                    entry.insert(progress.clone());
7357                    did_update = true;
7358                }
7359                btree_map::Entry::Occupied(mut entry) => {
7360                    let entry = entry.get_mut();
7361                    if (progress.last_update_at - entry.last_update_at)
7362                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
7363                    {
7364                        entry.last_update_at = progress.last_update_at;
7365                        if progress.message.is_some() {
7366                            entry.message = progress.message.clone();
7367                        }
7368                        if progress.percentage.is_some() {
7369                            entry.percentage = progress.percentage;
7370                        }
7371                        if progress.is_cancellable != entry.is_cancellable {
7372                            entry.is_cancellable = progress.is_cancellable;
7373                        }
7374                        did_update = true;
7375                    }
7376                }
7377            }
7378        }
7379
7380        if did_update {
7381            cx.emit(LspStoreEvent::LanguageServerUpdate {
7382                language_server_id,
7383                message: proto::update_language_server::Variant::WorkProgress(
7384                    proto::LspWorkProgress {
7385                        token,
7386                        message: progress.message,
7387                        percentage: progress.percentage.map(|p| p as u32),
7388                        is_cancellable: Some(progress.is_cancellable),
7389                    },
7390                ),
7391            })
7392        }
7393    }
7394
7395    fn on_lsp_work_end(
7396        &mut self,
7397        language_server_id: LanguageServerId,
7398        token: String,
7399        cx: &mut Context<Self>,
7400    ) {
7401        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
7402            if let Some(work) = status.pending_work.remove(&token) {
7403                if !work.is_disk_based_diagnostics_progress {
7404                    cx.emit(LspStoreEvent::RefreshInlayHints);
7405                }
7406            }
7407            cx.notify();
7408        }
7409
7410        cx.emit(LspStoreEvent::LanguageServerUpdate {
7411            language_server_id,
7412            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd { token }),
7413        })
7414    }
7415
7416    pub async fn handle_resolve_completion_documentation(
7417        this: Entity<Self>,
7418        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
7419        mut cx: AsyncApp,
7420    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
7421        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
7422
7423        let completion = this
7424            .read_with(&cx, |this, cx| {
7425                let id = LanguageServerId(envelope.payload.language_server_id as usize);
7426                let Some(server) = this.language_server_for_id(id) else {
7427                    return Err(anyhow!("No language server {id}"));
7428                };
7429
7430                Ok(cx.background_spawn(async move {
7431                    let can_resolve = server
7432                        .capabilities()
7433                        .completion_provider
7434                        .as_ref()
7435                        .and_then(|options| options.resolve_provider)
7436                        .unwrap_or(false);
7437                    if can_resolve {
7438                        server
7439                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
7440                            .await
7441                    } else {
7442                        anyhow::Ok(lsp_completion)
7443                    }
7444                }))
7445            })??
7446            .await?;
7447
7448        let mut documentation_is_markdown = false;
7449        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
7450        let documentation = match completion.documentation {
7451            Some(lsp::Documentation::String(text)) => text,
7452
7453            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
7454                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
7455                value
7456            }
7457
7458            _ => String::new(),
7459        };
7460
7461        // If we have a new buffer_id, that means we're talking to a new client
7462        // and want to check for new text_edits in the completion too.
7463        let mut old_start = None;
7464        let mut old_end = None;
7465        let mut new_text = String::default();
7466        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
7467            let buffer_snapshot = this.update(&mut cx, |this, cx| {
7468                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
7469                anyhow::Ok(buffer.read(cx).snapshot())
7470            })??;
7471
7472            if let Some(text_edit) = completion.text_edit.as_ref() {
7473                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
7474
7475                if let Some((old_range, mut text_edit_new_text)) = edit {
7476                    LineEnding::normalize(&mut text_edit_new_text);
7477
7478                    new_text = text_edit_new_text;
7479                    old_start = Some(serialize_anchor(&old_range.start));
7480                    old_end = Some(serialize_anchor(&old_range.end));
7481                }
7482            }
7483        }
7484
7485        Ok(proto::ResolveCompletionDocumentationResponse {
7486            documentation,
7487            documentation_is_markdown,
7488            old_start,
7489            old_end,
7490            new_text,
7491            lsp_completion,
7492        })
7493    }
7494
7495    async fn handle_on_type_formatting(
7496        this: Entity<Self>,
7497        envelope: TypedEnvelope<proto::OnTypeFormatting>,
7498        mut cx: AsyncApp,
7499    ) -> Result<proto::OnTypeFormattingResponse> {
7500        let on_type_formatting = this.update(&mut cx, |this, cx| {
7501            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
7502            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
7503            let position = envelope
7504                .payload
7505                .position
7506                .and_then(deserialize_anchor)
7507                .ok_or_else(|| anyhow!("invalid position"))?;
7508            Ok::<_, anyhow::Error>(this.apply_on_type_formatting(
7509                buffer,
7510                position,
7511                envelope.payload.trigger.clone(),
7512                cx,
7513            ))
7514        })??;
7515
7516        let transaction = on_type_formatting
7517            .await?
7518            .as_ref()
7519            .map(language::proto::serialize_transaction);
7520        Ok(proto::OnTypeFormattingResponse { transaction })
7521    }
7522
7523    async fn handle_refresh_inlay_hints(
7524        this: Entity<Self>,
7525        _: TypedEnvelope<proto::RefreshInlayHints>,
7526        mut cx: AsyncApp,
7527    ) -> Result<proto::Ack> {
7528        this.update(&mut cx, |_, cx| {
7529            cx.emit(LspStoreEvent::RefreshInlayHints);
7530        })?;
7531        Ok(proto::Ack {})
7532    }
7533
7534    async fn handle_inlay_hints(
7535        this: Entity<Self>,
7536        envelope: TypedEnvelope<proto::InlayHints>,
7537        mut cx: AsyncApp,
7538    ) -> Result<proto::InlayHintsResponse> {
7539        let sender_id = envelope.original_sender_id().unwrap_or_default();
7540        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
7541        let buffer = this.update(&mut cx, |this, cx| {
7542            this.buffer_store.read(cx).get_existing(buffer_id)
7543        })??;
7544        buffer
7545            .update(&mut cx, |buffer, _| {
7546                buffer.wait_for_version(deserialize_version(&envelope.payload.version))
7547            })?
7548            .await
7549            .with_context(|| format!("waiting for version for buffer {}", buffer.entity_id()))?;
7550
7551        let start = envelope
7552            .payload
7553            .start
7554            .and_then(deserialize_anchor)
7555            .context("missing range start")?;
7556        let end = envelope
7557            .payload
7558            .end
7559            .and_then(deserialize_anchor)
7560            .context("missing range end")?;
7561        let buffer_hints = this
7562            .update(&mut cx, |lsp_store, cx| {
7563                lsp_store.inlay_hints(buffer.clone(), start..end, cx)
7564            })?
7565            .await
7566            .context("inlay hints fetch")?;
7567
7568        this.update(&mut cx, |project, cx| {
7569            InlayHints::response_to_proto(
7570                buffer_hints,
7571                project,
7572                sender_id,
7573                &buffer.read(cx).version(),
7574                cx,
7575            )
7576        })
7577    }
7578
7579    async fn handle_resolve_inlay_hint(
7580        this: Entity<Self>,
7581        envelope: TypedEnvelope<proto::ResolveInlayHint>,
7582        mut cx: AsyncApp,
7583    ) -> Result<proto::ResolveInlayHintResponse> {
7584        let proto_hint = envelope
7585            .payload
7586            .hint
7587            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
7588        let hint = InlayHints::proto_to_project_hint(proto_hint)
7589            .context("resolved proto inlay hint conversion")?;
7590        let buffer = this.update(&mut cx, |this, cx| {
7591            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
7592            this.buffer_store.read(cx).get_existing(buffer_id)
7593        })??;
7594        let response_hint = this
7595            .update(&mut cx, |this, cx| {
7596                this.resolve_inlay_hint(
7597                    hint,
7598                    buffer,
7599                    LanguageServerId(envelope.payload.language_server_id as usize),
7600                    cx,
7601                )
7602            })?
7603            .await
7604            .context("inlay hints fetch")?;
7605        Ok(proto::ResolveInlayHintResponse {
7606            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
7607        })
7608    }
7609
7610    async fn handle_refresh_code_lens(
7611        this: Entity<Self>,
7612        _: TypedEnvelope<proto::RefreshCodeLens>,
7613        mut cx: AsyncApp,
7614    ) -> Result<proto::Ack> {
7615        this.update(&mut cx, |_, cx| {
7616            cx.emit(LspStoreEvent::RefreshCodeLens);
7617        })?;
7618        Ok(proto::Ack {})
7619    }
7620
7621    async fn handle_open_buffer_for_symbol(
7622        this: Entity<Self>,
7623        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
7624        mut cx: AsyncApp,
7625    ) -> Result<proto::OpenBufferForSymbolResponse> {
7626        let peer_id = envelope.original_sender_id().unwrap_or_default();
7627        let symbol = envelope
7628            .payload
7629            .symbol
7630            .ok_or_else(|| anyhow!("invalid symbol"))?;
7631        let symbol = Self::deserialize_symbol(symbol)?;
7632        let symbol = this.update(&mut cx, |this, _| {
7633            let signature = this.symbol_signature(&symbol.path);
7634            if signature == symbol.signature {
7635                Ok(symbol)
7636            } else {
7637                Err(anyhow!("invalid symbol signature"))
7638            }
7639        })??;
7640        let buffer = this
7641            .update(&mut cx, |this, cx| {
7642                this.open_buffer_for_symbol(
7643                    &Symbol {
7644                        language_server_name: symbol.language_server_name,
7645                        source_worktree_id: symbol.source_worktree_id,
7646                        source_language_server_id: symbol.source_language_server_id,
7647                        path: symbol.path,
7648                        name: symbol.name,
7649                        kind: symbol.kind,
7650                        range: symbol.range,
7651                        signature: symbol.signature,
7652                        label: CodeLabel {
7653                            text: Default::default(),
7654                            runs: Default::default(),
7655                            filter_range: Default::default(),
7656                        },
7657                    },
7658                    cx,
7659                )
7660            })?
7661            .await?;
7662
7663        this.update(&mut cx, |this, cx| {
7664            let is_private = buffer
7665                .read(cx)
7666                .file()
7667                .map(|f| f.is_private())
7668                .unwrap_or_default();
7669            if is_private {
7670                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
7671            } else {
7672                this.buffer_store
7673                    .update(cx, |buffer_store, cx| {
7674                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
7675                    })
7676                    .detach_and_log_err(cx);
7677                let buffer_id = buffer.read(cx).remote_id().to_proto();
7678                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
7679            }
7680        })?
7681    }
7682
7683    fn symbol_signature(&self, project_path: &ProjectPath) -> [u8; 32] {
7684        let mut hasher = Sha256::new();
7685        hasher.update(project_path.worktree_id.to_proto().to_be_bytes());
7686        hasher.update(project_path.path.to_string_lossy().as_bytes());
7687        hasher.update(self.nonce.to_be_bytes());
7688        hasher.finalize().as_slice().try_into().unwrap()
7689    }
7690
7691    pub async fn handle_get_project_symbols(
7692        this: Entity<Self>,
7693        envelope: TypedEnvelope<proto::GetProjectSymbols>,
7694        mut cx: AsyncApp,
7695    ) -> Result<proto::GetProjectSymbolsResponse> {
7696        let symbols = this
7697            .update(&mut cx, |this, cx| {
7698                this.symbols(&envelope.payload.query, cx)
7699            })?
7700            .await?;
7701
7702        Ok(proto::GetProjectSymbolsResponse {
7703            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
7704        })
7705    }
7706
7707    pub async fn handle_restart_language_servers(
7708        this: Entity<Self>,
7709        envelope: TypedEnvelope<proto::RestartLanguageServers>,
7710        mut cx: AsyncApp,
7711    ) -> Result<proto::Ack> {
7712        this.update(&mut cx, |this, cx| {
7713            let buffers = this.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
7714            this.restart_language_servers_for_buffers(buffers, cx);
7715        })?;
7716
7717        Ok(proto::Ack {})
7718    }
7719
7720    pub async fn handle_cancel_language_server_work(
7721        this: Entity<Self>,
7722        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
7723        mut cx: AsyncApp,
7724    ) -> Result<proto::Ack> {
7725        this.update(&mut cx, |this, cx| {
7726            if let Some(work) = envelope.payload.work {
7727                match work {
7728                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
7729                        let buffers =
7730                            this.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
7731                        this.cancel_language_server_work_for_buffers(buffers, cx);
7732                    }
7733                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
7734                        let server_id = LanguageServerId::from_proto(work.language_server_id);
7735                        this.cancel_language_server_work(server_id, work.token, cx);
7736                    }
7737                }
7738            }
7739        })?;
7740
7741        Ok(proto::Ack {})
7742    }
7743
7744    fn buffer_ids_to_buffers(
7745        &mut self,
7746        buffer_ids: impl Iterator<Item = u64>,
7747        cx: &mut Context<Self>,
7748    ) -> Vec<Entity<Buffer>> {
7749        buffer_ids
7750            .into_iter()
7751            .flat_map(|buffer_id| {
7752                self.buffer_store
7753                    .read(cx)
7754                    .get(BufferId::new(buffer_id).log_err()?)
7755            })
7756            .collect::<Vec<_>>()
7757    }
7758
7759    async fn handle_apply_additional_edits_for_completion(
7760        this: Entity<Self>,
7761        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
7762        mut cx: AsyncApp,
7763    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
7764        let (buffer, completion) = this.update(&mut cx, |this, cx| {
7765            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
7766            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
7767            let completion = Self::deserialize_completion(
7768                envelope
7769                    .payload
7770                    .completion
7771                    .ok_or_else(|| anyhow!("invalid completion"))?,
7772            )?;
7773            anyhow::Ok((buffer, completion))
7774        })??;
7775
7776        let apply_additional_edits = this.update(&mut cx, |this, cx| {
7777            this.apply_additional_edits_for_completion(
7778                buffer,
7779                Rc::new(RefCell::new(Box::new([Completion {
7780                    old_range: completion.old_range,
7781                    new_text: completion.new_text,
7782                    source: completion.source,
7783                    documentation: None,
7784                    label: CodeLabel {
7785                        text: Default::default(),
7786                        runs: Default::default(),
7787                        filter_range: Default::default(),
7788                    },
7789                    confirm: None,
7790                }]))),
7791                0,
7792                false,
7793                cx,
7794            )
7795        })?;
7796
7797        Ok(proto::ApplyCompletionAdditionalEditsResponse {
7798            transaction: apply_additional_edits
7799                .await?
7800                .as_ref()
7801                .map(language::proto::serialize_transaction),
7802        })
7803    }
7804
7805    pub fn last_formatting_failure(&self) -> Option<&str> {
7806        self.last_formatting_failure.as_deref()
7807    }
7808
7809    pub fn reset_last_formatting_failure(&mut self) {
7810        self.last_formatting_failure = None;
7811    }
7812
7813    pub fn environment_for_buffer(
7814        &self,
7815        buffer: &Entity<Buffer>,
7816        cx: &mut Context<Self>,
7817    ) -> Shared<Task<Option<HashMap<String, String>>>> {
7818        let worktree_id = buffer.read(cx).file().map(|file| file.worktree_id(cx));
7819        let worktree_abs_path = worktree_id.and_then(|worktree_id| {
7820            self.worktree_store
7821                .read(cx)
7822                .worktree_for_id(worktree_id, cx)
7823                .map(|entry| entry.read(cx).abs_path().clone())
7824        });
7825
7826        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
7827            environment.update(cx, |env, cx| {
7828                env.get_environment(worktree_id, worktree_abs_path, cx)
7829            })
7830        } else {
7831            Task::ready(None).shared()
7832        }
7833    }
7834
7835    pub fn format(
7836        &mut self,
7837        buffers: HashSet<Entity<Buffer>>,
7838        target: LspFormatTarget,
7839        push_to_history: bool,
7840        trigger: FormatTrigger,
7841        cx: &mut Context<Self>,
7842    ) -> Task<anyhow::Result<ProjectTransaction>> {
7843        if let Some(_) = self.as_local() {
7844            let buffers = buffers
7845                .into_iter()
7846                .map(|buffer_handle| {
7847                    let buffer = buffer_handle.read(cx);
7848                    let buffer_abs_path = File::from_dyn(buffer.file())
7849                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
7850
7851                    (buffer_handle, buffer_abs_path, buffer.remote_id())
7852                })
7853                .collect::<Vec<_>>();
7854
7855            cx.spawn(async move |lsp_store, cx| {
7856                let mut formattable_buffers = Vec::with_capacity(buffers.len());
7857
7858                for (handle, abs_path, id) in buffers {
7859                    let env = lsp_store
7860                        .update(cx, |lsp_store, cx| {
7861                            lsp_store.environment_for_buffer(&handle, cx)
7862                        })?
7863                        .await;
7864
7865                    let ranges = match &target {
7866                        LspFormatTarget::Buffers => None,
7867                        LspFormatTarget::Ranges(ranges) => {
7868                            let Some(ranges) = ranges.get(&id) else {
7869                                return Err(anyhow!("No format ranges provided for buffer"));
7870                            };
7871                            Some(ranges.clone())
7872                        }
7873                    };
7874
7875                    formattable_buffers.push(FormattableBuffer {
7876                        handle,
7877                        abs_path,
7878                        env,
7879                        ranges,
7880                    });
7881                }
7882
7883                let result = LocalLspStore::format_locally(
7884                    lsp_store.clone(),
7885                    formattable_buffers,
7886                    push_to_history,
7887                    trigger,
7888                    cx,
7889                )
7890                .await;
7891                lsp_store.update(cx, |lsp_store, _| {
7892                    lsp_store.update_last_formatting_failure(&result);
7893                })?;
7894
7895                result
7896            })
7897        } else if let Some((client, project_id)) = self.upstream_client() {
7898            // Don't support formatting ranges via remote
7899            match target {
7900                LspFormatTarget::Buffers => {}
7901                LspFormatTarget::Ranges(_) => {
7902                    return Task::ready(Ok(ProjectTransaction::default()));
7903                }
7904            }
7905
7906            let buffer_store = self.buffer_store();
7907            cx.spawn(async move |lsp_store, cx| {
7908                let result = client
7909                    .request(proto::FormatBuffers {
7910                        project_id,
7911                        trigger: trigger as i32,
7912                        buffer_ids: buffers
7913                            .iter()
7914                            .map(|buffer| buffer.update(cx, |buffer, _| buffer.remote_id().into()))
7915                            .collect::<Result<_>>()?,
7916                    })
7917                    .await
7918                    .and_then(|result| result.transaction.context("missing transaction"));
7919
7920                lsp_store.update(cx, |lsp_store, _| {
7921                    lsp_store.update_last_formatting_failure(&result);
7922                })?;
7923
7924                let transaction_response = result?;
7925                buffer_store
7926                    .update(cx, |buffer_store, cx| {
7927                        buffer_store.deserialize_project_transaction(
7928                            transaction_response,
7929                            push_to_history,
7930                            cx,
7931                        )
7932                    })?
7933                    .await
7934            })
7935        } else {
7936            Task::ready(Ok(ProjectTransaction::default()))
7937        }
7938    }
7939
7940    async fn handle_format_buffers(
7941        this: Entity<Self>,
7942        envelope: TypedEnvelope<proto::FormatBuffers>,
7943        mut cx: AsyncApp,
7944    ) -> Result<proto::FormatBuffersResponse> {
7945        let sender_id = envelope.original_sender_id().unwrap_or_default();
7946        let format = this.update(&mut cx, |this, cx| {
7947            let mut buffers = HashSet::default();
7948            for buffer_id in &envelope.payload.buffer_ids {
7949                let buffer_id = BufferId::new(*buffer_id)?;
7950                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
7951            }
7952            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
7953            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
7954        })??;
7955
7956        let project_transaction = format.await?;
7957        let project_transaction = this.update(&mut cx, |this, cx| {
7958            this.buffer_store.update(cx, |buffer_store, cx| {
7959                buffer_store.serialize_project_transaction_for_peer(
7960                    project_transaction,
7961                    sender_id,
7962                    cx,
7963                )
7964            })
7965        })?;
7966        Ok(proto::FormatBuffersResponse {
7967            transaction: Some(project_transaction),
7968        })
7969    }
7970
7971    async fn handle_apply_code_action_kind(
7972        this: Entity<Self>,
7973        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
7974        mut cx: AsyncApp,
7975    ) -> Result<proto::ApplyCodeActionKindResponse> {
7976        let sender_id = envelope.original_sender_id().unwrap_or_default();
7977        let format = this.update(&mut cx, |this, cx| {
7978            let mut buffers = HashSet::default();
7979            for buffer_id in &envelope.payload.buffer_ids {
7980                let buffer_id = BufferId::new(*buffer_id)?;
7981                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
7982            }
7983            let kind = match envelope.payload.kind.as_str() {
7984                "" => Ok(CodeActionKind::EMPTY),
7985                "quickfix" => Ok(CodeActionKind::QUICKFIX),
7986                "refactor" => Ok(CodeActionKind::REFACTOR),
7987                "refactor.extract" => Ok(CodeActionKind::REFACTOR_EXTRACT),
7988                "refactor.inline" => Ok(CodeActionKind::REFACTOR_INLINE),
7989                "refactor.rewrite" => Ok(CodeActionKind::REFACTOR_REWRITE),
7990                "source" => Ok(CodeActionKind::SOURCE),
7991                "source.organizeImports" => Ok(CodeActionKind::SOURCE_ORGANIZE_IMPORTS),
7992                "source.fixAll" => Ok(CodeActionKind::SOURCE_FIX_ALL),
7993                _ => Err(anyhow!("Invalid code action kind")),
7994            }?;
7995            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
7996        })??;
7997
7998        let project_transaction = format.await?;
7999        let project_transaction = this.update(&mut cx, |this, cx| {
8000            this.buffer_store.update(cx, |buffer_store, cx| {
8001                buffer_store.serialize_project_transaction_for_peer(
8002                    project_transaction,
8003                    sender_id,
8004                    cx,
8005                )
8006            })
8007        })?;
8008        Ok(proto::ApplyCodeActionKindResponse {
8009            transaction: Some(project_transaction),
8010        })
8011    }
8012
8013    async fn shutdown_language_server(
8014        server_state: Option<LanguageServerState>,
8015        name: LanguageServerName,
8016        cx: &mut AsyncApp,
8017    ) {
8018        let server = match server_state {
8019            Some(LanguageServerState::Starting { startup, .. }) => {
8020                let mut timer = cx
8021                    .background_executor()
8022                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
8023                    .fuse();
8024
8025                select! {
8026                    server = startup.fuse() => server,
8027                    _ = timer => {
8028                        log::info!(
8029                            "timeout waiting for language server {} to finish launching before stopping",
8030                            name
8031                        );
8032                        None
8033                    },
8034                }
8035            }
8036
8037            Some(LanguageServerState::Running { server, .. }) => Some(server),
8038
8039            None => None,
8040        };
8041
8042        if let Some(server) = server {
8043            if let Some(shutdown) = server.shutdown() {
8044                shutdown.await;
8045            }
8046        }
8047    }
8048
8049    // Returns a list of all of the worktrees which no longer have a language server and the root path
8050    // for the stopped server
8051    fn stop_local_language_server(
8052        &mut self,
8053        server_id: LanguageServerId,
8054        name: LanguageServerName,
8055        cx: &mut Context<Self>,
8056    ) -> Task<Vec<WorktreeId>> {
8057        let local = match &mut self.mode {
8058            LspStoreMode::Local(local) => local,
8059            _ => {
8060                return Task::ready(Vec::new());
8061            }
8062        };
8063
8064        let mut orphaned_worktrees = vec![];
8065        // Remove this server ID from all entries in the given worktree.
8066        local.language_server_ids.retain(|(worktree, _), ids| {
8067            if !ids.remove(&server_id) {
8068                return true;
8069            }
8070
8071            if ids.is_empty() {
8072                orphaned_worktrees.push(*worktree);
8073                false
8074            } else {
8075                true
8076            }
8077        });
8078        let _ = self.language_server_statuses.remove(&server_id);
8079        log::info!("stopping language server {name}");
8080        self.buffer_store.update(cx, |buffer_store, cx| {
8081            for buffer in buffer_store.buffers() {
8082                buffer.update(cx, |buffer, cx| {
8083                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
8084                    buffer.set_completion_triggers(server_id, Default::default(), cx);
8085                });
8086            }
8087        });
8088
8089        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
8090            summaries.retain(|path, summaries_by_server_id| {
8091                if summaries_by_server_id.remove(&server_id).is_some() {
8092                    if let Some((client, project_id)) = self.downstream_client.clone() {
8093                        client
8094                            .send(proto::UpdateDiagnosticSummary {
8095                                project_id,
8096                                worktree_id: worktree_id.to_proto(),
8097                                summary: Some(proto::DiagnosticSummary {
8098                                    path: path.as_ref().to_proto(),
8099                                    language_server_id: server_id.0 as u64,
8100                                    error_count: 0,
8101                                    warning_count: 0,
8102                                }),
8103                            })
8104                            .log_err();
8105                    }
8106                    !summaries_by_server_id.is_empty()
8107                } else {
8108                    true
8109                }
8110            });
8111        }
8112
8113        let local = self.as_local_mut().unwrap();
8114        for diagnostics in local.diagnostics.values_mut() {
8115            diagnostics.retain(|_, diagnostics_by_server_id| {
8116                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
8117                    diagnostics_by_server_id.remove(ix);
8118                    !diagnostics_by_server_id.is_empty()
8119                } else {
8120                    true
8121                }
8122            });
8123        }
8124        local.language_server_watched_paths.remove(&server_id);
8125        let server_state = local.language_servers.remove(&server_id);
8126        cx.notify();
8127        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
8128        cx.spawn(async move |_, cx| {
8129            Self::shutdown_language_server(server_state, name, cx).await;
8130            orphaned_worktrees
8131        })
8132    }
8133
8134    pub fn restart_language_servers_for_buffers(
8135        &mut self,
8136        buffers: Vec<Entity<Buffer>>,
8137        cx: &mut Context<Self>,
8138    ) {
8139        if let Some((client, project_id)) = self.upstream_client() {
8140            let request = client.request(proto::RestartLanguageServers {
8141                project_id,
8142                buffer_ids: buffers
8143                    .into_iter()
8144                    .map(|b| b.read(cx).remote_id().to_proto())
8145                    .collect(),
8146            });
8147            cx.background_spawn(request).detach_and_log_err(cx);
8148        } else {
8149            let Some(local) = self.as_local_mut() else {
8150                return;
8151            };
8152            let language_servers_to_stop = buffers
8153                .iter()
8154                .flat_map(|buffer| {
8155                    buffer.update(cx, |buffer, cx| {
8156                        local.language_server_ids_for_buffer(buffer, cx)
8157                    })
8158                })
8159                .collect::<BTreeSet<_>>();
8160            local.lsp_tree.update(cx, |this, _| {
8161                this.remove_nodes(&language_servers_to_stop);
8162            });
8163            let tasks = language_servers_to_stop
8164                .into_iter()
8165                .map(|server| {
8166                    let name = self
8167                        .language_server_statuses
8168                        .get(&server)
8169                        .map(|state| state.name.as_str().into())
8170                        .unwrap_or_else(|| LanguageServerName::from("Unknown"));
8171                    self.stop_local_language_server(server, name, cx)
8172                })
8173                .collect::<Vec<_>>();
8174
8175            cx.spawn(async move |this, cx| {
8176                cx.background_spawn(futures::future::join_all(tasks)).await;
8177                this.update(cx, |this, cx| {
8178                    for buffer in buffers {
8179                        this.register_buffer_with_language_servers(&buffer, true, cx);
8180                    }
8181                })
8182                .ok()
8183            })
8184            .detach();
8185        }
8186    }
8187
8188    pub fn update_diagnostics(
8189        &mut self,
8190        language_server_id: LanguageServerId,
8191        mut params: lsp::PublishDiagnosticsParams,
8192        disk_based_sources: &[String],
8193        cx: &mut Context<Self>,
8194    ) -> Result<()> {
8195        if !self.mode.is_local() {
8196            anyhow::bail!("called update_diagnostics on remote");
8197        }
8198        let abs_path = params
8199            .uri
8200            .to_file_path()
8201            .map_err(|_| anyhow!("URI is not a file"))?;
8202        let mut diagnostics = Vec::default();
8203        let mut primary_diagnostic_group_ids = HashMap::default();
8204        let mut sources_by_group_id = HashMap::default();
8205        let mut supporting_diagnostics = HashMap::default();
8206
8207        // Ensure that primary diagnostics are always the most severe
8208        params.diagnostics.sort_by_key(|item| item.severity);
8209
8210        for diagnostic in &params.diagnostics {
8211            let source = diagnostic.source.as_ref();
8212            let range = range_from_lsp(diagnostic.range);
8213            let is_supporting = diagnostic
8214                .related_information
8215                .as_ref()
8216                .map_or(false, |infos| {
8217                    infos.iter().any(|info| {
8218                        primary_diagnostic_group_ids.contains_key(&(
8219                            source,
8220                            diagnostic.code.clone(),
8221                            range_from_lsp(info.location.range),
8222                        ))
8223                    })
8224                });
8225
8226            let is_unnecessary = diagnostic.tags.as_ref().map_or(false, |tags| {
8227                tags.iter().any(|tag| *tag == DiagnosticTag::UNNECESSARY)
8228            });
8229
8230            if is_supporting {
8231                supporting_diagnostics.insert(
8232                    (source, diagnostic.code.clone(), range),
8233                    (diagnostic.severity, is_unnecessary),
8234                );
8235            } else {
8236                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
8237                let is_disk_based =
8238                    source.map_or(false, |source| disk_based_sources.contains(source));
8239
8240                sources_by_group_id.insert(group_id, source);
8241                primary_diagnostic_group_ids
8242                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
8243
8244                diagnostics.push(DiagnosticEntry {
8245                    range,
8246                    diagnostic: Diagnostic {
8247                        source: diagnostic.source.clone(),
8248                        code: diagnostic.code.clone(),
8249                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
8250                        message: diagnostic.message.trim().to_string(),
8251                        group_id,
8252                        is_primary: true,
8253                        is_disk_based,
8254                        is_unnecessary,
8255                        data: diagnostic.data.clone(),
8256                    },
8257                });
8258                if let Some(infos) = &diagnostic.related_information {
8259                    for info in infos {
8260                        if info.location.uri == params.uri && !info.message.is_empty() {
8261                            let range = range_from_lsp(info.location.range);
8262                            diagnostics.push(DiagnosticEntry {
8263                                range,
8264                                diagnostic: Diagnostic {
8265                                    source: diagnostic.source.clone(),
8266                                    code: diagnostic.code.clone(),
8267                                    severity: DiagnosticSeverity::INFORMATION,
8268                                    message: info.message.trim().to_string(),
8269                                    group_id,
8270                                    is_primary: false,
8271                                    is_disk_based,
8272                                    is_unnecessary: false,
8273                                    data: diagnostic.data.clone(),
8274                                },
8275                            });
8276                        }
8277                    }
8278                }
8279            }
8280        }
8281
8282        for entry in &mut diagnostics {
8283            let diagnostic = &mut entry.diagnostic;
8284            if !diagnostic.is_primary {
8285                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
8286                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
8287                    source,
8288                    diagnostic.code.clone(),
8289                    entry.range.clone(),
8290                )) {
8291                    if let Some(severity) = severity {
8292                        diagnostic.severity = severity;
8293                    }
8294                    diagnostic.is_unnecessary = is_unnecessary;
8295                }
8296            }
8297        }
8298
8299        self.update_diagnostic_entries(
8300            language_server_id,
8301            abs_path,
8302            params.version,
8303            diagnostics,
8304            cx,
8305        )?;
8306        Ok(())
8307    }
8308
8309    fn insert_newly_running_language_server(
8310        &mut self,
8311        adapter: Arc<CachedLspAdapter>,
8312        language_server: Arc<LanguageServer>,
8313        server_id: LanguageServerId,
8314        key: (WorktreeId, LanguageServerName),
8315        workspace_folders: Arc<Mutex<BTreeSet<Url>>>,
8316        cx: &mut Context<Self>,
8317    ) {
8318        let Some(local) = self.as_local_mut() else {
8319            return;
8320        };
8321        // If the language server for this key doesn't match the server id, don't store the
8322        // server. Which will cause it to be dropped, killing the process
8323        if local
8324            .language_server_ids
8325            .get(&key)
8326            .map(|ids| !ids.contains(&server_id))
8327            .unwrap_or(false)
8328        {
8329            return;
8330        }
8331
8332        // Update language_servers collection with Running variant of LanguageServerState
8333        // indicating that the server is up and running and ready
8334        let workspace_folders = workspace_folders.lock().clone();
8335        local.language_servers.insert(
8336            server_id,
8337            LanguageServerState::running(
8338                workspace_folders,
8339                adapter.clone(),
8340                language_server.clone(),
8341                None,
8342            ),
8343        );
8344        if let Some(file_ops_caps) = language_server
8345            .capabilities()
8346            .workspace
8347            .as_ref()
8348            .and_then(|ws| ws.file_operations.as_ref())
8349        {
8350            let did_rename_caps = file_ops_caps.did_rename.as_ref();
8351            let will_rename_caps = file_ops_caps.will_rename.as_ref();
8352            if did_rename_caps.or(will_rename_caps).is_some() {
8353                let watcher = RenamePathsWatchedForServer::default()
8354                    .with_did_rename_patterns(did_rename_caps)
8355                    .with_will_rename_patterns(will_rename_caps);
8356                local
8357                    .language_server_paths_watched_for_rename
8358                    .insert(server_id, watcher);
8359            }
8360        }
8361
8362        self.language_server_statuses.insert(
8363            server_id,
8364            LanguageServerStatus {
8365                name: language_server.name().to_string(),
8366                pending_work: Default::default(),
8367                has_pending_diagnostic_updates: false,
8368                progress_tokens: Default::default(),
8369            },
8370        );
8371
8372        cx.emit(LspStoreEvent::LanguageServerAdded(
8373            server_id,
8374            language_server.name(),
8375            Some(key.0),
8376        ));
8377        cx.emit(LspStoreEvent::RefreshInlayHints);
8378
8379        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
8380            downstream_client
8381                .send(proto::StartLanguageServer {
8382                    project_id: *project_id,
8383                    server: Some(proto::LanguageServer {
8384                        id: server_id.0 as u64,
8385                        name: language_server.name().to_string(),
8386                        worktree_id: Some(key.0.to_proto()),
8387                    }),
8388                })
8389                .log_err();
8390        }
8391
8392        // Tell the language server about every open buffer in the worktree that matches the language.
8393        self.buffer_store.clone().update(cx, |buffer_store, cx| {
8394            for buffer_handle in buffer_store.buffers() {
8395                let buffer = buffer_handle.read(cx);
8396                let file = match File::from_dyn(buffer.file()) {
8397                    Some(file) => file,
8398                    None => continue,
8399                };
8400                let language = match buffer.language() {
8401                    Some(language) => language,
8402                    None => continue,
8403                };
8404
8405                if file.worktree.read(cx).id() != key.0
8406                    || !self
8407                        .languages
8408                        .lsp_adapters(&language.name())
8409                        .iter()
8410                        .any(|a| a.name == key.1)
8411                {
8412                    continue;
8413                }
8414                // didOpen
8415                let file = match file.as_local() {
8416                    Some(file) => file,
8417                    None => continue,
8418                };
8419
8420                let local = self.as_local_mut().unwrap();
8421
8422                if local.registered_buffers.contains_key(&buffer.remote_id()) {
8423                    let versions = local
8424                        .buffer_snapshots
8425                        .entry(buffer.remote_id())
8426                        .or_default()
8427                        .entry(server_id)
8428                        .and_modify(|_| {
8429                            assert!(
8430                            false,
8431                            "There should not be an existing snapshot for a newly inserted buffer"
8432                        )
8433                        })
8434                        .or_insert_with(|| {
8435                            vec![LspBufferSnapshot {
8436                                version: 0,
8437                                snapshot: buffer.text_snapshot(),
8438                            }]
8439                        });
8440
8441                    let snapshot = versions.last().unwrap();
8442                    let version = snapshot.version;
8443                    let initial_snapshot = &snapshot.snapshot;
8444                    let uri = lsp::Url::from_file_path(file.abs_path(cx)).unwrap();
8445                    language_server.register_buffer(
8446                        uri,
8447                        adapter.language_id(&language.name()),
8448                        version,
8449                        initial_snapshot.text(),
8450                    );
8451                }
8452                buffer_handle.update(cx, |buffer, cx| {
8453                    buffer.set_completion_triggers(
8454                        server_id,
8455                        language_server
8456                            .capabilities()
8457                            .completion_provider
8458                            .as_ref()
8459                            .and_then(|provider| {
8460                                provider
8461                                    .trigger_characters
8462                                    .as_ref()
8463                                    .map(|characters| characters.iter().cloned().collect())
8464                            })
8465                            .unwrap_or_default(),
8466                        cx,
8467                    )
8468                });
8469            }
8470        });
8471
8472        cx.notify();
8473    }
8474
8475    pub fn language_servers_running_disk_based_diagnostics(
8476        &self,
8477    ) -> impl Iterator<Item = LanguageServerId> + '_ {
8478        self.language_server_statuses
8479            .iter()
8480            .filter_map(|(id, status)| {
8481                if status.has_pending_diagnostic_updates {
8482                    Some(*id)
8483                } else {
8484                    None
8485                }
8486            })
8487    }
8488
8489    pub(crate) fn cancel_language_server_work_for_buffers(
8490        &mut self,
8491        buffers: impl IntoIterator<Item = Entity<Buffer>>,
8492        cx: &mut Context<Self>,
8493    ) {
8494        if let Some((client, project_id)) = self.upstream_client() {
8495            let request = client.request(proto::CancelLanguageServerWork {
8496                project_id,
8497                work: Some(proto::cancel_language_server_work::Work::Buffers(
8498                    proto::cancel_language_server_work::Buffers {
8499                        buffer_ids: buffers
8500                            .into_iter()
8501                            .map(|b| b.read(cx).remote_id().to_proto())
8502                            .collect(),
8503                    },
8504                )),
8505            });
8506            cx.background_spawn(request).detach_and_log_err(cx);
8507        } else if let Some(local) = self.as_local() {
8508            let servers = buffers
8509                .into_iter()
8510                .flat_map(|buffer| {
8511                    buffer.update(cx, |buffer, cx| {
8512                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
8513                    })
8514                })
8515                .collect::<HashSet<_>>();
8516            for server_id in servers {
8517                self.cancel_language_server_work(server_id, None, cx);
8518            }
8519        }
8520    }
8521
8522    pub(crate) fn cancel_language_server_work(
8523        &mut self,
8524        server_id: LanguageServerId,
8525        token_to_cancel: Option<String>,
8526        cx: &mut Context<Self>,
8527    ) {
8528        if let Some(local) = self.as_local() {
8529            let status = self.language_server_statuses.get(&server_id);
8530            let server = local.language_servers.get(&server_id);
8531            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
8532            {
8533                for (token, progress) in &status.pending_work {
8534                    if let Some(token_to_cancel) = token_to_cancel.as_ref() {
8535                        if token != token_to_cancel {
8536                            continue;
8537                        }
8538                    }
8539                    if progress.is_cancellable {
8540                        server
8541                            .notify::<lsp::notification::WorkDoneProgressCancel>(
8542                                &WorkDoneProgressCancelParams {
8543                                    token: lsp::NumberOrString::String(token.clone()),
8544                                },
8545                            )
8546                            .ok();
8547                    }
8548                }
8549            }
8550        } else if let Some((client, project_id)) = self.upstream_client() {
8551            let request = client.request(proto::CancelLanguageServerWork {
8552                project_id,
8553                work: Some(
8554                    proto::cancel_language_server_work::Work::LanguageServerWork(
8555                        proto::cancel_language_server_work::LanguageServerWork {
8556                            language_server_id: server_id.to_proto(),
8557                            token: token_to_cancel,
8558                        },
8559                    ),
8560                ),
8561            });
8562            cx.background_spawn(request).detach_and_log_err(cx);
8563        }
8564    }
8565
8566    fn register_supplementary_language_server(
8567        &mut self,
8568        id: LanguageServerId,
8569        name: LanguageServerName,
8570        server: Arc<LanguageServer>,
8571        cx: &mut Context<Self>,
8572    ) {
8573        if let Some(local) = self.as_local_mut() {
8574            local
8575                .supplementary_language_servers
8576                .insert(id, (name.clone(), server));
8577            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
8578        }
8579    }
8580
8581    fn unregister_supplementary_language_server(
8582        &mut self,
8583        id: LanguageServerId,
8584        cx: &mut Context<Self>,
8585    ) {
8586        if let Some(local) = self.as_local_mut() {
8587            local.supplementary_language_servers.remove(&id);
8588            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
8589        }
8590    }
8591
8592    pub(crate) fn supplementary_language_servers(
8593        &self,
8594    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
8595        self.as_local().into_iter().flat_map(|local| {
8596            local
8597                .supplementary_language_servers
8598                .iter()
8599                .map(|(id, (name, _))| (*id, name.clone()))
8600        })
8601    }
8602
8603    pub fn language_server_adapter_for_id(
8604        &self,
8605        id: LanguageServerId,
8606    ) -> Option<Arc<CachedLspAdapter>> {
8607        self.as_local()
8608            .and_then(|local| local.language_servers.get(&id))
8609            .and_then(|language_server_state| match language_server_state {
8610                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
8611                _ => None,
8612            })
8613    }
8614
8615    pub(super) fn update_local_worktree_language_servers(
8616        &mut self,
8617        worktree_handle: &Entity<Worktree>,
8618        changes: &[(Arc<Path>, ProjectEntryId, PathChange)],
8619        cx: &mut Context<Self>,
8620    ) {
8621        if changes.is_empty() {
8622            return;
8623        }
8624
8625        let Some(local) = self.as_local() else { return };
8626
8627        local.prettier_store.update(cx, |prettier_store, cx| {
8628            prettier_store.update_prettier_settings(&worktree_handle, changes, cx)
8629        });
8630
8631        let worktree_id = worktree_handle.read(cx).id();
8632        let mut language_server_ids = local
8633            .language_server_ids
8634            .iter()
8635            .flat_map(|((server_worktree, _), server_ids)| {
8636                server_ids
8637                    .iter()
8638                    .filter_map(|server_id| server_worktree.eq(&worktree_id).then(|| *server_id))
8639            })
8640            .collect::<Vec<_>>();
8641        language_server_ids.sort();
8642        language_server_ids.dedup();
8643
8644        let abs_path = worktree_handle.read(cx).abs_path();
8645        for server_id in &language_server_ids {
8646            if let Some(LanguageServerState::Running { server, .. }) =
8647                local.language_servers.get(server_id)
8648            {
8649                if let Some(watched_paths) = local
8650                    .language_server_watched_paths
8651                    .get(server_id)
8652                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
8653                {
8654                    let params = lsp::DidChangeWatchedFilesParams {
8655                        changes: changes
8656                            .iter()
8657                            .filter_map(|(path, _, change)| {
8658                                if !watched_paths.is_match(path) {
8659                                    return None;
8660                                }
8661                                let typ = match change {
8662                                    PathChange::Loaded => return None,
8663                                    PathChange::Added => lsp::FileChangeType::CREATED,
8664                                    PathChange::Removed => lsp::FileChangeType::DELETED,
8665                                    PathChange::Updated => lsp::FileChangeType::CHANGED,
8666                                    PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
8667                                };
8668                                Some(lsp::FileEvent {
8669                                    uri: lsp::Url::from_file_path(abs_path.join(path)).unwrap(),
8670                                    typ,
8671                                })
8672                            })
8673                            .collect(),
8674                    };
8675                    if !params.changes.is_empty() {
8676                        server
8677                            .notify::<lsp::notification::DidChangeWatchedFiles>(&params)
8678                            .log_err();
8679                    }
8680                }
8681            }
8682        }
8683    }
8684
8685    pub fn wait_for_remote_buffer(
8686        &mut self,
8687        id: BufferId,
8688        cx: &mut Context<Self>,
8689    ) -> Task<Result<Entity<Buffer>>> {
8690        self.buffer_store.update(cx, |buffer_store, cx| {
8691            buffer_store.wait_for_remote_buffer(id, cx)
8692        })
8693    }
8694
8695    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
8696        proto::Symbol {
8697            language_server_name: symbol.language_server_name.0.to_string(),
8698            source_worktree_id: symbol.source_worktree_id.to_proto(),
8699            language_server_id: symbol.source_language_server_id.to_proto(),
8700            worktree_id: symbol.path.worktree_id.to_proto(),
8701            path: symbol.path.path.as_ref().to_proto(),
8702            name: symbol.name.clone(),
8703            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
8704            start: Some(proto::PointUtf16 {
8705                row: symbol.range.start.0.row,
8706                column: symbol.range.start.0.column,
8707            }),
8708            end: Some(proto::PointUtf16 {
8709                row: symbol.range.end.0.row,
8710                column: symbol.range.end.0.column,
8711            }),
8712            signature: symbol.signature.to_vec(),
8713        }
8714    }
8715
8716    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
8717        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
8718        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
8719        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
8720        let path = ProjectPath {
8721            worktree_id,
8722            path: Arc::<Path>::from_proto(serialized_symbol.path),
8723        };
8724
8725        let start = serialized_symbol
8726            .start
8727            .ok_or_else(|| anyhow!("invalid start"))?;
8728        let end = serialized_symbol
8729            .end
8730            .ok_or_else(|| anyhow!("invalid end"))?;
8731        Ok(CoreSymbol {
8732            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
8733            source_worktree_id,
8734            source_language_server_id: LanguageServerId::from_proto(
8735                serialized_symbol.language_server_id,
8736            ),
8737            path,
8738            name: serialized_symbol.name,
8739            range: Unclipped(PointUtf16::new(start.row, start.column))
8740                ..Unclipped(PointUtf16::new(end.row, end.column)),
8741            kind,
8742            signature: serialized_symbol
8743                .signature
8744                .try_into()
8745                .map_err(|_| anyhow!("invalid signature"))?,
8746        })
8747    }
8748
8749    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
8750        let mut serialized_completion = proto::Completion {
8751            old_start: Some(serialize_anchor(&completion.old_range.start)),
8752            old_end: Some(serialize_anchor(&completion.old_range.end)),
8753            new_text: completion.new_text.clone(),
8754            ..proto::Completion::default()
8755        };
8756        match &completion.source {
8757            CompletionSource::Lsp {
8758                server_id,
8759                lsp_completion,
8760                lsp_defaults,
8761                resolved,
8762            } => {
8763                serialized_completion.source = proto::completion::Source::Lsp as i32;
8764                serialized_completion.server_id = server_id.0 as u64;
8765                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
8766                serialized_completion.lsp_defaults = lsp_defaults
8767                    .as_deref()
8768                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
8769                serialized_completion.resolved = *resolved;
8770            }
8771            CompletionSource::BufferWord {
8772                word_range,
8773                resolved,
8774            } => {
8775                serialized_completion.source = proto::completion::Source::BufferWord as i32;
8776                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
8777                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
8778                serialized_completion.resolved = *resolved;
8779            }
8780            CompletionSource::Custom => {
8781                serialized_completion.source = proto::completion::Source::Custom as i32;
8782                serialized_completion.resolved = true;
8783            }
8784        }
8785
8786        serialized_completion
8787    }
8788
8789    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
8790        let old_start = completion
8791            .old_start
8792            .and_then(deserialize_anchor)
8793            .context("invalid old start")?;
8794        let old_end = completion
8795            .old_end
8796            .and_then(deserialize_anchor)
8797            .context("invalid old end")?;
8798        Ok(CoreCompletion {
8799            old_range: old_start..old_end,
8800            new_text: completion.new_text,
8801            source: match proto::completion::Source::from_i32(completion.source) {
8802                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
8803                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
8804                    server_id: LanguageServerId::from_proto(completion.server_id),
8805                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
8806                    lsp_defaults: completion
8807                        .lsp_defaults
8808                        .as_deref()
8809                        .map(serde_json::from_slice)
8810                        .transpose()?,
8811                    resolved: completion.resolved,
8812                },
8813                Some(proto::completion::Source::BufferWord) => {
8814                    let word_range = completion
8815                        .buffer_word_start
8816                        .and_then(deserialize_anchor)
8817                        .context("invalid buffer word start")?
8818                        ..completion
8819                            .buffer_word_end
8820                            .and_then(deserialize_anchor)
8821                            .context("invalid buffer word end")?;
8822                    CompletionSource::BufferWord {
8823                        word_range,
8824                        resolved: completion.resolved,
8825                    }
8826                }
8827                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
8828            },
8829        })
8830    }
8831
8832    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
8833        let (kind, lsp_action) = match &action.lsp_action {
8834            LspAction::Action(code_action) => (
8835                proto::code_action::Kind::Action as i32,
8836                serde_json::to_vec(code_action).unwrap(),
8837            ),
8838            LspAction::Command(command) => (
8839                proto::code_action::Kind::Command as i32,
8840                serde_json::to_vec(command).unwrap(),
8841            ),
8842            LspAction::CodeLens(code_lens) => (
8843                proto::code_action::Kind::CodeLens as i32,
8844                serde_json::to_vec(code_lens).unwrap(),
8845            ),
8846        };
8847
8848        proto::CodeAction {
8849            server_id: action.server_id.0 as u64,
8850            start: Some(serialize_anchor(&action.range.start)),
8851            end: Some(serialize_anchor(&action.range.end)),
8852            lsp_action,
8853            kind,
8854            resolved: action.resolved,
8855        }
8856    }
8857
8858    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
8859        let start = action
8860            .start
8861            .and_then(deserialize_anchor)
8862            .context("invalid start")?;
8863        let end = action
8864            .end
8865            .and_then(deserialize_anchor)
8866            .context("invalid end")?;
8867        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
8868            Some(proto::code_action::Kind::Action) => {
8869                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
8870            }
8871            Some(proto::code_action::Kind::Command) => {
8872                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
8873            }
8874            Some(proto::code_action::Kind::CodeLens) => {
8875                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
8876            }
8877            None => anyhow::bail!("Unknown action kind {}", action.kind),
8878        };
8879        Ok(CodeAction {
8880            server_id: LanguageServerId(action.server_id as usize),
8881            range: start..end,
8882            resolved: action.resolved,
8883            lsp_action,
8884        })
8885    }
8886
8887    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
8888        match &formatting_result {
8889            Ok(_) => self.last_formatting_failure = None,
8890            Err(error) => {
8891                let error_string = format!("{error:#}");
8892                log::error!("Formatting failed: {error_string}");
8893                self.last_formatting_failure
8894                    .replace(error_string.lines().join(" "));
8895            }
8896        }
8897    }
8898}
8899
8900fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
8901    let CompletionSource::BufferWord {
8902        word_range,
8903        resolved,
8904    } = &mut completion.source
8905    else {
8906        return;
8907    };
8908    if *resolved {
8909        return;
8910    }
8911
8912    if completion.new_text
8913        != snapshot
8914            .text_for_range(word_range.clone())
8915            .collect::<String>()
8916    {
8917        return;
8918    }
8919
8920    let mut offset = 0;
8921    for chunk in snapshot.chunks(word_range.clone(), true) {
8922        let end_offset = offset + chunk.text.len();
8923        if let Some(highlight_id) = chunk.syntax_highlight_id {
8924            completion
8925                .label
8926                .runs
8927                .push((offset..end_offset, highlight_id));
8928        }
8929        offset = end_offset;
8930    }
8931    *resolved = true;
8932}
8933
8934impl EventEmitter<LspStoreEvent> for LspStore {}
8935
8936fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
8937    hover
8938        .contents
8939        .retain(|hover_block| !hover_block.text.trim().is_empty());
8940    if hover.contents.is_empty() {
8941        None
8942    } else {
8943        Some(hover)
8944    }
8945}
8946
8947async fn populate_labels_for_completions(
8948    new_completions: Vec<CoreCompletion>,
8949    language: Option<Arc<Language>>,
8950    lsp_adapter: Option<Arc<CachedLspAdapter>>,
8951    completions: &mut Vec<Completion>,
8952) {
8953    let lsp_completions = new_completions
8954        .iter()
8955        .filter_map(|new_completion| {
8956            if let Some(lsp_completion) = new_completion.source.lsp_completion(true) {
8957                Some(lsp_completion.into_owned())
8958            } else {
8959                None
8960            }
8961        })
8962        .collect::<Vec<_>>();
8963
8964    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
8965        lsp_adapter
8966            .labels_for_completions(&lsp_completions, language)
8967            .await
8968            .log_err()
8969            .unwrap_or_default()
8970    } else {
8971        Vec::new()
8972    }
8973    .into_iter()
8974    .fuse();
8975
8976    for completion in new_completions {
8977        match completion.source.lsp_completion(true) {
8978            Some(lsp_completion) => {
8979                let documentation = if let Some(docs) = lsp_completion.documentation.clone() {
8980                    Some(docs.into())
8981                } else {
8982                    None
8983                };
8984
8985                let mut label = labels.next().flatten().unwrap_or_else(|| {
8986                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
8987                });
8988                ensure_uniform_list_compatible_label(&mut label);
8989                completions.push(Completion {
8990                    label,
8991                    documentation,
8992                    old_range: completion.old_range,
8993                    new_text: completion.new_text,
8994                    source: completion.source,
8995                    confirm: None,
8996                });
8997            }
8998            None => {
8999                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
9000                ensure_uniform_list_compatible_label(&mut label);
9001                completions.push(Completion {
9002                    label,
9003                    documentation: None,
9004                    old_range: completion.old_range,
9005                    new_text: completion.new_text,
9006                    source: completion.source,
9007                    confirm: None,
9008                });
9009            }
9010        }
9011    }
9012}
9013
9014#[derive(Debug)]
9015pub enum LanguageServerToQuery {
9016    /// Query language servers in order of users preference, up until one capable of handling the request is found.
9017    FirstCapable,
9018    /// Query a specific language server.
9019    Other(LanguageServerId),
9020}
9021
9022#[derive(Default)]
9023struct RenamePathsWatchedForServer {
9024    did_rename: Vec<RenameActionPredicate>,
9025    will_rename: Vec<RenameActionPredicate>,
9026}
9027
9028impl RenamePathsWatchedForServer {
9029    fn with_did_rename_patterns(
9030        mut self,
9031        did_rename: Option<&FileOperationRegistrationOptions>,
9032    ) -> Self {
9033        if let Some(did_rename) = did_rename {
9034            self.did_rename = did_rename
9035                .filters
9036                .iter()
9037                .filter_map(|filter| filter.try_into().log_err())
9038                .collect();
9039        }
9040        self
9041    }
9042    fn with_will_rename_patterns(
9043        mut self,
9044        will_rename: Option<&FileOperationRegistrationOptions>,
9045    ) -> Self {
9046        if let Some(will_rename) = will_rename {
9047            self.will_rename = will_rename
9048                .filters
9049                .iter()
9050                .filter_map(|filter| filter.try_into().log_err())
9051                .collect();
9052        }
9053        self
9054    }
9055
9056    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
9057        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
9058    }
9059    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
9060        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
9061    }
9062}
9063
9064impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
9065    type Error = globset::Error;
9066    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
9067        Ok(Self {
9068            kind: ops.pattern.matches.clone(),
9069            glob: GlobBuilder::new(&ops.pattern.glob)
9070                .case_insensitive(
9071                    ops.pattern
9072                        .options
9073                        .as_ref()
9074                        .map_or(false, |ops| ops.ignore_case.unwrap_or(false)),
9075                )
9076                .build()?
9077                .compile_matcher(),
9078        })
9079    }
9080}
9081struct RenameActionPredicate {
9082    glob: GlobMatcher,
9083    kind: Option<FileOperationPatternKind>,
9084}
9085
9086impl RenameActionPredicate {
9087    // Returns true if language server should be notified
9088    fn eval(&self, path: &str, is_dir: bool) -> bool {
9089        self.kind.as_ref().map_or(true, |kind| {
9090            let expected_kind = if is_dir {
9091                FileOperationPatternKind::Folder
9092            } else {
9093                FileOperationPatternKind::File
9094            };
9095            kind == &expected_kind
9096        }) && self.glob.is_match(path)
9097    }
9098}
9099
9100#[derive(Default)]
9101struct LanguageServerWatchedPaths {
9102    worktree_paths: HashMap<WorktreeId, GlobSet>,
9103    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
9104}
9105
9106#[derive(Default)]
9107struct LanguageServerWatchedPathsBuilder {
9108    worktree_paths: HashMap<WorktreeId, GlobSet>,
9109    abs_paths: HashMap<Arc<Path>, GlobSet>,
9110}
9111
9112impl LanguageServerWatchedPathsBuilder {
9113    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
9114        self.worktree_paths.insert(worktree_id, glob_set);
9115    }
9116    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
9117        self.abs_paths.insert(path, glob_set);
9118    }
9119    fn build(
9120        self,
9121        fs: Arc<dyn Fs>,
9122        language_server_id: LanguageServerId,
9123        cx: &mut Context<LspStore>,
9124    ) -> LanguageServerWatchedPaths {
9125        let project = cx.weak_entity();
9126
9127        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
9128        let abs_paths = self
9129            .abs_paths
9130            .into_iter()
9131            .map(|(abs_path, globset)| {
9132                let task = cx.spawn({
9133                    let abs_path = abs_path.clone();
9134                    let fs = fs.clone();
9135
9136                    let lsp_store = project.clone();
9137                    async move |_, cx| {
9138                        maybe!(async move {
9139                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
9140                            while let Some(update) = push_updates.0.next().await {
9141                                let action = lsp_store
9142                                    .update(cx, |this, _| {
9143                                        let Some(local) = this.as_local() else {
9144                                            return ControlFlow::Break(());
9145                                        };
9146                                        let Some(watcher) = local
9147                                            .language_server_watched_paths
9148                                            .get(&language_server_id)
9149                                        else {
9150                                            return ControlFlow::Break(());
9151                                        };
9152                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
9153                                            "Watched abs path is not registered with a watcher",
9154                                        );
9155                                        let matching_entries = update
9156                                            .into_iter()
9157                                            .filter(|event| globs.is_match(&event.path))
9158                                            .collect::<Vec<_>>();
9159                                        this.lsp_notify_abs_paths_changed(
9160                                            language_server_id,
9161                                            matching_entries,
9162                                        );
9163                                        ControlFlow::Continue(())
9164                                    })
9165                                    .ok()?;
9166
9167                                if action.is_break() {
9168                                    break;
9169                                }
9170                            }
9171                            Some(())
9172                        })
9173                        .await;
9174                    }
9175                });
9176                (abs_path, (globset, task))
9177            })
9178            .collect();
9179        LanguageServerWatchedPaths {
9180            worktree_paths: self.worktree_paths,
9181            abs_paths,
9182        }
9183    }
9184}
9185
9186struct LspBufferSnapshot {
9187    version: i32,
9188    snapshot: TextBufferSnapshot,
9189}
9190
9191/// A prompt requested by LSP server.
9192#[derive(Clone, Debug)]
9193pub struct LanguageServerPromptRequest {
9194    pub level: PromptLevel,
9195    pub message: String,
9196    pub actions: Vec<MessageActionItem>,
9197    pub lsp_name: String,
9198    pub(crate) response_channel: Sender<MessageActionItem>,
9199}
9200
9201impl LanguageServerPromptRequest {
9202    pub async fn respond(self, index: usize) -> Option<()> {
9203        if let Some(response) = self.actions.into_iter().nth(index) {
9204            self.response_channel.send(response).await.ok()
9205        } else {
9206            None
9207        }
9208    }
9209}
9210impl PartialEq for LanguageServerPromptRequest {
9211    fn eq(&self, other: &Self) -> bool {
9212        self.message == other.message && self.actions == other.actions
9213    }
9214}
9215
9216#[derive(Clone, Debug, PartialEq)]
9217pub enum LanguageServerLogType {
9218    Log(MessageType),
9219    Trace(Option<String>),
9220}
9221
9222impl LanguageServerLogType {
9223    pub fn to_proto(&self) -> proto::language_server_log::LogType {
9224        match self {
9225            Self::Log(log_type) => {
9226                let message_type = match *log_type {
9227                    MessageType::ERROR => 1,
9228                    MessageType::WARNING => 2,
9229                    MessageType::INFO => 3,
9230                    MessageType::LOG => 4,
9231                    other => {
9232                        log::warn!("Unknown lsp log message type: {:?}", other);
9233                        4
9234                    }
9235                };
9236                proto::language_server_log::LogType::LogMessageType(message_type)
9237            }
9238            Self::Trace(message) => {
9239                proto::language_server_log::LogType::LogTrace(proto::LspLogTrace {
9240                    message: message.clone(),
9241                })
9242            }
9243        }
9244    }
9245
9246    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
9247        match log_type {
9248            proto::language_server_log::LogType::LogMessageType(message_type) => {
9249                Self::Log(match message_type {
9250                    1 => MessageType::ERROR,
9251                    2 => MessageType::WARNING,
9252                    3 => MessageType::INFO,
9253                    4 => MessageType::LOG,
9254                    _ => MessageType::LOG,
9255                })
9256            }
9257            proto::language_server_log::LogType::LogTrace(trace) => Self::Trace(trace.message),
9258        }
9259    }
9260}
9261
9262pub enum LanguageServerState {
9263    Starting {
9264        startup: Task<Option<Arc<LanguageServer>>>,
9265        /// List of language servers that will be added to the workspace once it's initialization completes.
9266        pending_workspace_folders: Arc<Mutex<BTreeSet<Url>>>,
9267    },
9268
9269    Running {
9270        adapter: Arc<CachedLspAdapter>,
9271        server: Arc<LanguageServer>,
9272        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
9273    },
9274}
9275
9276impl LanguageServerState {
9277    fn add_workspace_folder(&self, uri: Url) {
9278        match self {
9279            LanguageServerState::Starting {
9280                pending_workspace_folders,
9281                ..
9282            } => {
9283                pending_workspace_folders.lock().insert(uri);
9284            }
9285            LanguageServerState::Running { server, .. } => {
9286                server.add_workspace_folder(uri);
9287            }
9288        }
9289    }
9290    fn _remove_workspace_folder(&self, uri: Url) {
9291        match self {
9292            LanguageServerState::Starting {
9293                pending_workspace_folders,
9294                ..
9295            } => {
9296                pending_workspace_folders.lock().remove(&uri);
9297            }
9298            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
9299        }
9300    }
9301    fn running(
9302        workspace_folders: BTreeSet<Url>,
9303        adapter: Arc<CachedLspAdapter>,
9304        server: Arc<LanguageServer>,
9305        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
9306    ) -> Self {
9307        server.set_workspace_folders(workspace_folders);
9308        Self::Running {
9309            adapter,
9310            server,
9311            simulate_disk_based_diagnostics_completion,
9312        }
9313    }
9314}
9315
9316impl std::fmt::Debug for LanguageServerState {
9317    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
9318        match self {
9319            LanguageServerState::Starting { .. } => {
9320                f.debug_struct("LanguageServerState::Starting").finish()
9321            }
9322            LanguageServerState::Running { .. } => {
9323                f.debug_struct("LanguageServerState::Running").finish()
9324            }
9325        }
9326    }
9327}
9328
9329#[derive(Clone, Debug, Serialize)]
9330pub struct LanguageServerProgress {
9331    pub is_disk_based_diagnostics_progress: bool,
9332    pub is_cancellable: bool,
9333    pub title: Option<String>,
9334    pub message: Option<String>,
9335    pub percentage: Option<usize>,
9336    #[serde(skip_serializing)]
9337    pub last_update_at: Instant,
9338}
9339
9340#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
9341pub struct DiagnosticSummary {
9342    pub error_count: usize,
9343    pub warning_count: usize,
9344}
9345
9346impl DiagnosticSummary {
9347    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
9348        let mut this = Self {
9349            error_count: 0,
9350            warning_count: 0,
9351        };
9352
9353        for entry in diagnostics {
9354            if entry.diagnostic.is_primary {
9355                match entry.diagnostic.severity {
9356                    DiagnosticSeverity::ERROR => this.error_count += 1,
9357                    DiagnosticSeverity::WARNING => this.warning_count += 1,
9358                    _ => {}
9359                }
9360            }
9361        }
9362
9363        this
9364    }
9365
9366    pub fn is_empty(&self) -> bool {
9367        self.error_count == 0 && self.warning_count == 0
9368    }
9369
9370    pub fn to_proto(
9371        &self,
9372        language_server_id: LanguageServerId,
9373        path: &Path,
9374    ) -> proto::DiagnosticSummary {
9375        proto::DiagnosticSummary {
9376            path: path.to_proto(),
9377            language_server_id: language_server_id.0 as u64,
9378            error_count: self.error_count as u32,
9379            warning_count: self.warning_count as u32,
9380        }
9381    }
9382}
9383
9384#[derive(Clone, Debug)]
9385pub enum CompletionDocumentation {
9386    /// There is no documentation for this completion.
9387    Undocumented,
9388    /// A single line of documentation.
9389    SingleLine(SharedString),
9390    /// Multiple lines of plain text documentation.
9391    MultiLinePlainText(SharedString),
9392    /// Markdown documentation.
9393    MultiLineMarkdown(SharedString),
9394}
9395
9396impl From<lsp::Documentation> for CompletionDocumentation {
9397    fn from(docs: lsp::Documentation) -> Self {
9398        match docs {
9399            lsp::Documentation::String(text) => {
9400                if text.lines().count() <= 1 {
9401                    CompletionDocumentation::SingleLine(text.into())
9402                } else {
9403                    CompletionDocumentation::MultiLinePlainText(text.into())
9404                }
9405            }
9406
9407            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
9408                lsp::MarkupKind::PlainText => {
9409                    if value.lines().count() <= 1 {
9410                        CompletionDocumentation::SingleLine(value.into())
9411                    } else {
9412                        CompletionDocumentation::MultiLinePlainText(value.into())
9413                    }
9414                }
9415
9416                lsp::MarkupKind::Markdown => {
9417                    CompletionDocumentation::MultiLineMarkdown(value.into())
9418                }
9419            },
9420        }
9421    }
9422}
9423
9424fn glob_literal_prefix(glob: &Path) -> PathBuf {
9425    glob.components()
9426        .take_while(|component| match component {
9427            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
9428            _ => true,
9429        })
9430        .collect()
9431}
9432
9433pub struct SshLspAdapter {
9434    name: LanguageServerName,
9435    binary: LanguageServerBinary,
9436    initialization_options: Option<String>,
9437    code_action_kinds: Option<Vec<CodeActionKind>>,
9438}
9439
9440impl SshLspAdapter {
9441    pub fn new(
9442        name: LanguageServerName,
9443        binary: LanguageServerBinary,
9444        initialization_options: Option<String>,
9445        code_action_kinds: Option<String>,
9446    ) -> Self {
9447        Self {
9448            name,
9449            binary,
9450            initialization_options,
9451            code_action_kinds: code_action_kinds
9452                .as_ref()
9453                .and_then(|c| serde_json::from_str(c).ok()),
9454        }
9455    }
9456}
9457
9458#[async_trait(?Send)]
9459impl LspAdapter for SshLspAdapter {
9460    fn name(&self) -> LanguageServerName {
9461        self.name.clone()
9462    }
9463
9464    async fn initialization_options(
9465        self: Arc<Self>,
9466        _: &dyn Fs,
9467        _: &Arc<dyn LspAdapterDelegate>,
9468    ) -> Result<Option<serde_json::Value>> {
9469        let Some(options) = &self.initialization_options else {
9470            return Ok(None);
9471        };
9472        let result = serde_json::from_str(options)?;
9473        Ok(result)
9474    }
9475
9476    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
9477        self.code_action_kinds.clone()
9478    }
9479
9480    async fn check_if_user_installed(
9481        &self,
9482        _: &dyn LspAdapterDelegate,
9483        _: Arc<dyn LanguageToolchainStore>,
9484        _: &AsyncApp,
9485    ) -> Option<LanguageServerBinary> {
9486        Some(self.binary.clone())
9487    }
9488
9489    async fn cached_server_binary(
9490        &self,
9491        _: PathBuf,
9492        _: &dyn LspAdapterDelegate,
9493    ) -> Option<LanguageServerBinary> {
9494        None
9495    }
9496
9497    async fn fetch_latest_server_version(
9498        &self,
9499        _: &dyn LspAdapterDelegate,
9500    ) -> Result<Box<dyn 'static + Send + Any>> {
9501        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
9502    }
9503
9504    async fn fetch_server_binary(
9505        &self,
9506        _: Box<dyn 'static + Send + Any>,
9507        _: PathBuf,
9508        _: &dyn LspAdapterDelegate,
9509    ) -> Result<LanguageServerBinary> {
9510        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
9511    }
9512}
9513
9514pub fn language_server_settings<'a>(
9515    delegate: &'a dyn LspAdapterDelegate,
9516    language: &LanguageServerName,
9517    cx: &'a App,
9518) -> Option<&'a LspSettings> {
9519    language_server_settings_for(
9520        SettingsLocation {
9521            worktree_id: delegate.worktree_id(),
9522            path: delegate.worktree_root_path(),
9523        },
9524        language,
9525        cx,
9526    )
9527}
9528
9529pub(crate) fn language_server_settings_for<'a>(
9530    location: SettingsLocation<'a>,
9531    language: &LanguageServerName,
9532    cx: &'a App,
9533) -> Option<&'a LspSettings> {
9534    ProjectSettings::get(Some(location), cx).lsp.get(language)
9535}
9536
9537pub struct LocalLspAdapterDelegate {
9538    lsp_store: WeakEntity<LspStore>,
9539    worktree: worktree::Snapshot,
9540    fs: Arc<dyn Fs>,
9541    http_client: Arc<dyn HttpClient>,
9542    language_registry: Arc<LanguageRegistry>,
9543    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
9544}
9545
9546impl LocalLspAdapterDelegate {
9547    pub fn new(
9548        language_registry: Arc<LanguageRegistry>,
9549        environment: &Entity<ProjectEnvironment>,
9550        lsp_store: WeakEntity<LspStore>,
9551        worktree: &Entity<Worktree>,
9552        http_client: Arc<dyn HttpClient>,
9553        fs: Arc<dyn Fs>,
9554        cx: &mut App,
9555    ) -> Arc<Self> {
9556        let (worktree_id, worktree_abs_path) = {
9557            let worktree = worktree.read(cx);
9558            (worktree.id(), worktree.abs_path())
9559        };
9560
9561        let load_shell_env_task = environment.update(cx, |env, cx| {
9562            env.get_environment(Some(worktree_id), Some(worktree_abs_path), cx)
9563        });
9564
9565        Arc::new(Self {
9566            lsp_store,
9567            worktree: worktree.read(cx).snapshot(),
9568            fs,
9569            http_client,
9570            language_registry,
9571            load_shell_env_task,
9572        })
9573    }
9574
9575    fn from_local_lsp(
9576        local: &LocalLspStore,
9577        worktree: &Entity<Worktree>,
9578        cx: &mut App,
9579    ) -> Arc<Self> {
9580        Self::new(
9581            local.languages.clone(),
9582            &local.environment,
9583            local.weak.clone(),
9584            worktree,
9585            local.http_client.clone(),
9586            local.fs.clone(),
9587            cx,
9588        )
9589    }
9590}
9591
9592#[async_trait]
9593impl LspAdapterDelegate for LocalLspAdapterDelegate {
9594    fn show_notification(&self, message: &str, cx: &mut App) {
9595        self.lsp_store
9596            .update(cx, |_, cx| {
9597                cx.emit(LspStoreEvent::Notification(message.to_owned()))
9598            })
9599            .ok();
9600    }
9601
9602    fn http_client(&self) -> Arc<dyn HttpClient> {
9603        self.http_client.clone()
9604    }
9605
9606    fn worktree_id(&self) -> WorktreeId {
9607        self.worktree.id()
9608    }
9609
9610    fn exists(&self, path: &Path, is_dir: Option<bool>) -> bool {
9611        self.worktree.entry_for_path(path).map_or(false, |entry| {
9612            is_dir.map_or(true, |is_required_to_be_dir| {
9613                is_required_to_be_dir == entry.is_dir()
9614            })
9615        })
9616    }
9617
9618    fn worktree_root_path(&self) -> &Path {
9619        self.worktree.abs_path().as_ref()
9620    }
9621
9622    async fn shell_env(&self) -> HashMap<String, String> {
9623        let task = self.load_shell_env_task.clone();
9624        task.await.unwrap_or_default()
9625    }
9626
9627    async fn npm_package_installed_version(
9628        &self,
9629        package_name: &str,
9630    ) -> Result<Option<(PathBuf, String)>> {
9631        let local_package_directory = self.worktree_root_path();
9632        let node_modules_directory = local_package_directory.join("node_modules");
9633
9634        if let Some(version) =
9635            read_package_installed_version(node_modules_directory.clone(), package_name).await?
9636        {
9637            return Ok(Some((node_modules_directory, version)));
9638        }
9639        let Some(npm) = self.which("npm".as_ref()).await else {
9640            log::warn!(
9641                "Failed to find npm executable for {:?}",
9642                local_package_directory
9643            );
9644            return Ok(None);
9645        };
9646
9647        let env = self.shell_env().await;
9648        let output = util::command::new_smol_command(&npm)
9649            .args(["root", "-g"])
9650            .envs(env)
9651            .current_dir(local_package_directory)
9652            .output()
9653            .await?;
9654        let global_node_modules =
9655            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
9656
9657        if let Some(version) =
9658            read_package_installed_version(global_node_modules.clone(), package_name).await?
9659        {
9660            return Ok(Some((global_node_modules, version)));
9661        }
9662        return Ok(None);
9663    }
9664
9665    #[cfg(not(target_os = "windows"))]
9666    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
9667        let worktree_abs_path = self.worktree.abs_path();
9668        let shell_path = self.shell_env().await.get("PATH").cloned();
9669        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
9670    }
9671
9672    #[cfg(target_os = "windows")]
9673    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
9674        // todo(windows) Getting the shell env variables in a current directory on Windows is more complicated than other platforms
9675        //               there isn't a 'default shell' necessarily. The closest would be the default profile on the windows terminal
9676        //               SEE: https://learn.microsoft.com/en-us/windows/terminal/customize-settings/startup
9677        which::which(command).ok()
9678    }
9679
9680    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
9681        let working_dir = self.worktree_root_path();
9682        let output = util::command::new_smol_command(&command.path)
9683            .args(command.arguments)
9684            .envs(command.env.clone().unwrap_or_default())
9685            .current_dir(working_dir)
9686            .output()
9687            .await?;
9688
9689        if output.status.success() {
9690            return Ok(());
9691        }
9692        Err(anyhow!(
9693            "{}, stdout: {:?}, stderr: {:?}",
9694            output.status,
9695            String::from_utf8_lossy(&output.stdout),
9696            String::from_utf8_lossy(&output.stderr)
9697        ))
9698    }
9699
9700    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
9701        self.language_registry
9702            .update_lsp_status(server_name, status);
9703    }
9704
9705    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
9706        let dir = self.language_registry.language_server_download_dir(name)?;
9707
9708        if !dir.exists() {
9709            smol::fs::create_dir_all(&dir)
9710                .await
9711                .context("failed to create container directory")
9712                .log_err()?;
9713        }
9714
9715        Some(dir)
9716    }
9717
9718    async fn read_text_file(&self, path: PathBuf) -> Result<String> {
9719        let entry = self
9720            .worktree
9721            .entry_for_path(&path)
9722            .with_context(|| format!("no worktree entry for path {path:?}"))?;
9723        let abs_path = self
9724            .worktree
9725            .absolutize(&entry.path)
9726            .with_context(|| format!("cannot absolutize path {path:?}"))?;
9727
9728        self.fs.load(&abs_path).await
9729    }
9730}
9731
9732async fn populate_labels_for_symbols(
9733    symbols: Vec<CoreSymbol>,
9734    language_registry: &Arc<LanguageRegistry>,
9735    lsp_adapter: Option<Arc<CachedLspAdapter>>,
9736    output: &mut Vec<Symbol>,
9737) {
9738    #[allow(clippy::mutable_key_type)]
9739    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
9740
9741    let mut unknown_paths = BTreeSet::new();
9742    for symbol in symbols {
9743        let language = language_registry
9744            .language_for_file_path(&symbol.path.path)
9745            .await
9746            .ok()
9747            .or_else(|| {
9748                unknown_paths.insert(symbol.path.path.clone());
9749                None
9750            });
9751        symbols_by_language
9752            .entry(language)
9753            .or_default()
9754            .push(symbol);
9755    }
9756
9757    for unknown_path in unknown_paths {
9758        log::info!(
9759            "no language found for symbol path {}",
9760            unknown_path.display()
9761        );
9762    }
9763
9764    let mut label_params = Vec::new();
9765    for (language, mut symbols) in symbols_by_language {
9766        label_params.clear();
9767        label_params.extend(
9768            symbols
9769                .iter_mut()
9770                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
9771        );
9772
9773        let mut labels = Vec::new();
9774        if let Some(language) = language {
9775            let lsp_adapter = lsp_adapter.clone().or_else(|| {
9776                language_registry
9777                    .lsp_adapters(&language.name())
9778                    .first()
9779                    .cloned()
9780            });
9781            if let Some(lsp_adapter) = lsp_adapter {
9782                labels = lsp_adapter
9783                    .labels_for_symbols(&label_params, &language)
9784                    .await
9785                    .log_err()
9786                    .unwrap_or_default();
9787            }
9788        }
9789
9790        for ((symbol, (name, _)), label) in symbols
9791            .into_iter()
9792            .zip(label_params.drain(..))
9793            .zip(labels.into_iter().chain(iter::repeat(None)))
9794        {
9795            output.push(Symbol {
9796                language_server_name: symbol.language_server_name,
9797                source_worktree_id: symbol.source_worktree_id,
9798                source_language_server_id: symbol.source_language_server_id,
9799                path: symbol.path,
9800                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
9801                name,
9802                kind: symbol.kind,
9803                range: symbol.range,
9804                signature: symbol.signature,
9805            });
9806        }
9807    }
9808}
9809
9810fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
9811    match server.capabilities().text_document_sync.as_ref()? {
9812        lsp::TextDocumentSyncCapability::Kind(kind) => match *kind {
9813            lsp::TextDocumentSyncKind::NONE => None,
9814            lsp::TextDocumentSyncKind::FULL => Some(true),
9815            lsp::TextDocumentSyncKind::INCREMENTAL => Some(false),
9816            _ => None,
9817        },
9818        lsp::TextDocumentSyncCapability::Options(options) => match options.save.as_ref()? {
9819            lsp::TextDocumentSyncSaveOptions::Supported(supported) => {
9820                if *supported {
9821                    Some(true)
9822                } else {
9823                    None
9824                }
9825            }
9826            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
9827                Some(save_options.include_text.unwrap_or(false))
9828            }
9829        },
9830    }
9831}
9832
9833/// Completion items are displayed in a `UniformList`.
9834/// Usually, those items are single-line strings, but in LSP responses,
9835/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
9836/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
9837/// All that may lead to a newline being inserted into resulting `CodeLabel.text`, which will force `UniformList` to bloat each entry to occupy more space,
9838/// breaking the completions menu presentation.
9839///
9840/// Sanitize the text to ensure there are no newlines, or, if there are some, remove them and also remove long space sequences if there were newlines.
9841fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
9842    let mut new_text = String::with_capacity(label.text.len());
9843    let mut offset_map = vec![0; label.text.len() + 1];
9844    let mut last_char_was_space = false;
9845    let mut new_idx = 0;
9846    let mut chars = label.text.char_indices().fuse();
9847    let mut newlines_removed = false;
9848
9849    while let Some((idx, c)) = chars.next() {
9850        offset_map[idx] = new_idx;
9851
9852        match c {
9853            '\n' if last_char_was_space => {
9854                newlines_removed = true;
9855            }
9856            '\t' | ' ' if last_char_was_space => {}
9857            '\n' if !last_char_was_space => {
9858                new_text.push(' ');
9859                new_idx += 1;
9860                last_char_was_space = true;
9861                newlines_removed = true;
9862            }
9863            ' ' | '\t' => {
9864                new_text.push(' ');
9865                new_idx += 1;
9866                last_char_was_space = true;
9867            }
9868            _ => {
9869                new_text.push(c);
9870                new_idx += c.len_utf8();
9871                last_char_was_space = false;
9872            }
9873        }
9874    }
9875    offset_map[label.text.len()] = new_idx;
9876
9877    // Only modify the label if newlines were removed.
9878    if !newlines_removed {
9879        return;
9880    }
9881
9882    let last_index = new_idx;
9883    let mut run_ranges_errors = Vec::new();
9884    label.runs.retain_mut(|(range, _)| {
9885        match offset_map.get(range.start) {
9886            Some(&start) => range.start = start,
9887            None => {
9888                run_ranges_errors.push(range.clone());
9889                return false;
9890            }
9891        }
9892
9893        match offset_map.get(range.end) {
9894            Some(&end) => range.end = end,
9895            None => {
9896                run_ranges_errors.push(range.clone());
9897                range.end = last_index;
9898            }
9899        }
9900        true
9901    });
9902    if !run_ranges_errors.is_empty() {
9903        log::error!(
9904            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
9905            label.text
9906        );
9907    }
9908
9909    let mut wrong_filter_range = None;
9910    if label.filter_range == (0..label.text.len()) {
9911        label.filter_range = 0..new_text.len();
9912    } else {
9913        let mut original_filter_range = Some(label.filter_range.clone());
9914        match offset_map.get(label.filter_range.start) {
9915            Some(&start) => label.filter_range.start = start,
9916            None => {
9917                wrong_filter_range = original_filter_range.take();
9918                label.filter_range.start = last_index;
9919            }
9920        }
9921
9922        match offset_map.get(label.filter_range.end) {
9923            Some(&end) => label.filter_range.end = end,
9924            None => {
9925                wrong_filter_range = original_filter_range.take();
9926                label.filter_range.end = last_index;
9927            }
9928        }
9929    }
9930    if let Some(wrong_filter_range) = wrong_filter_range {
9931        log::error!(
9932            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
9933            label.text
9934        );
9935    }
9936
9937    label.text = new_text;
9938}
9939
9940#[cfg(test)]
9941mod tests {
9942    use language::HighlightId;
9943
9944    use super::*;
9945
9946    #[test]
9947    fn test_glob_literal_prefix() {
9948        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
9949        assert_eq!(
9950            glob_literal_prefix(Path::new("node_modules/**/*.js")),
9951            Path::new("node_modules")
9952        );
9953        assert_eq!(
9954            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
9955            Path::new("foo")
9956        );
9957        assert_eq!(
9958            glob_literal_prefix(Path::new("foo/bar/baz.js")),
9959            Path::new("foo/bar/baz.js")
9960        );
9961
9962        #[cfg(target_os = "windows")]
9963        {
9964            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
9965            assert_eq!(
9966                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
9967                Path::new("node_modules")
9968            );
9969            assert_eq!(
9970                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
9971                Path::new("foo")
9972            );
9973            assert_eq!(
9974                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
9975                Path::new("foo/bar/baz.js")
9976            );
9977        }
9978    }
9979
9980    #[test]
9981    fn test_multi_len_chars_normalization() {
9982        let mut label = CodeLabel {
9983            text: "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
9984            runs: vec![(0..6, HighlightId(1))],
9985            filter_range: 0..6,
9986        };
9987        ensure_uniform_list_compatible_label(&mut label);
9988        assert_eq!(
9989            label,
9990            CodeLabel {
9991                text: "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
9992                runs: vec![(0..6, HighlightId(1))],
9993                filter_range: 0..6,
9994            }
9995        );
9996    }
9997}