lsp_store.rs

    1//! LSP store provides unified access to the language server protocol.
    2//! The consumers of LSP store can interact with language servers without knowing exactly which language server they're interacting with.
    3//!
    4//! # Local/Remote LSP Stores
    5//! This module is split up into three distinct parts:
    6//! - [`LocalLspStore`], which is ran on the host machine (either project host or SSH host), that manages the lifecycle of language servers.
    7//! - [`RemoteLspStore`], which is ran on the remote machine (project guests) which is mostly about passing through the requests via RPC.
    8//!   The remote stores don't really care about which language server they're running against - they don't usually get to decide which language server is going to responsible for handling their request.
    9//! - [`LspStore`], which unifies the two under one consistent interface for interacting with language servers.
   10//!
   11//! Most of the interesting work happens at the local layer, as bulk of the complexity is with managing the lifecycle of language servers. The actual implementation of the LSP protocol is handled by [`lsp`] crate.
   12pub mod clangd_ext;
   13pub mod json_language_server_ext;
   14pub mod lsp_ext_command;
   15pub mod rust_analyzer_ext;
   16
   17use crate::{
   18    CodeAction, ColorPresentation, Completion, CompletionResponse, CompletionSource,
   19    CoreCompletion, DocumentColor, Hover, InlayHint, LocationLink, LspAction, LspPullDiagnostics,
   20    ManifestProvidersStore, ProjectItem, ProjectPath, ProjectTransaction, PulledDiagnostics,
   21    ResolveState, Symbol,
   22    buffer_store::{BufferStore, BufferStoreEvent},
   23    environment::ProjectEnvironment,
   24    lsp_command::{self, *},
   25    lsp_store,
   26    manifest_tree::{
   27        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   28        ManifestTree,
   29    },
   30    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   31    project_settings::{LspSettings, ProjectSettings},
   32    relativize_path, resolve_path,
   33    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   34    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   35    yarn::YarnPathStore,
   36};
   37use anyhow::{Context as _, Result, anyhow};
   38use async_trait::async_trait;
   39use client::{TypedEnvelope, proto};
   40use clock::Global;
   41use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   42use futures::{
   43    AsyncWriteExt, Future, FutureExt, StreamExt,
   44    future::{Either, Shared, join_all, pending, select},
   45    select, select_biased,
   46    stream::FuturesUnordered,
   47};
   48use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   49use gpui::{
   50    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString, Task,
   51    WeakEntity,
   52};
   53use http_client::HttpClient;
   54use itertools::Itertools as _;
   55use language::{
   56    Bias, BinaryStatus, Buffer, BufferSnapshot, CachedLspAdapter, CodeLabel, Diagnostic,
   57    DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language, LanguageName,
   58    LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, ManifestDelegate, ManifestName,
   59    Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Toolchain, Transaction,
   60    Unclipped,
   61    language_settings::{
   62        FormatOnSave, Formatter, LanguageSettings, SelectedFormatter, language_settings,
   63    },
   64    point_to_lsp,
   65    proto::{
   66        deserialize_anchor, deserialize_lsp_edit, deserialize_version, serialize_anchor,
   67        serialize_lsp_edit, serialize_version,
   68    },
   69    range_from_lsp, range_to_lsp,
   70};
   71use lsp::{
   72    AdapterServerCapabilities, CodeActionKind, CompletionContext, DiagnosticSeverity,
   73    DiagnosticTag, DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter,
   74    FileOperationPatternKind, FileOperationRegistrationOptions, FileRename, FileSystemWatcher,
   75    LSP_REQUEST_TIMEOUT, LanguageServer, LanguageServerBinary, LanguageServerBinaryOptions,
   76    LanguageServerId, LanguageServerName, LanguageServerSelector, LspRequestFuture,
   77    MessageActionItem, MessageType, OneOf, RenameFilesParams, SymbolKind, TextEdit,
   78    WillRenameFiles, WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   79};
   80use node_runtime::read_package_installed_version;
   81use parking_lot::Mutex;
   82use postage::{mpsc, sink::Sink, stream::Stream, watch};
   83use rand::prelude::*;
   84
   85use rpc::{
   86    AnyProtoClient,
   87    proto::{FromProto, LspRequestId, LspRequestMessage as _, ToProto},
   88};
   89use serde::Serialize;
   90use settings::{Settings, SettingsLocation, SettingsStore};
   91use sha2::{Digest, Sha256};
   92use smol::channel::Sender;
   93use snippet::Snippet;
   94use std::{
   95    any::{Any, TypeId},
   96    borrow::Cow,
   97    cell::RefCell,
   98    cmp::{Ordering, Reverse},
   99    convert::TryInto,
  100    ffi::OsStr,
  101    future::ready,
  102    iter, mem,
  103    ops::{ControlFlow, Range},
  104    path::{self, Path, PathBuf},
  105    pin::pin,
  106    rc::Rc,
  107    sync::Arc,
  108    time::{Duration, Instant},
  109};
  110use sum_tree::Dimensions;
  111use text::{Anchor, BufferId, LineEnding, OffsetRangeExt};
  112use url::Url;
  113use util::{
  114    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  115    paths::{PathExt, SanitizedPath},
  116    post_inc,
  117};
  118
  119pub use fs::*;
  120pub use language::Location;
  121#[cfg(any(test, feature = "test-support"))]
  122pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  123pub use worktree::{
  124    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  125    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  126};
  127
  128const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  129pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  130
  131#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  132pub enum FormatTrigger {
  133    Save,
  134    Manual,
  135}
  136
  137pub enum LspFormatTarget {
  138    Buffers,
  139    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  140}
  141
  142pub type OpenLspBufferHandle = Entity<Entity<Buffer>>;
  143
  144impl FormatTrigger {
  145    fn from_proto(value: i32) -> FormatTrigger {
  146        match value {
  147            0 => FormatTrigger::Save,
  148            1 => FormatTrigger::Manual,
  149            _ => FormatTrigger::Save,
  150        }
  151    }
  152}
  153
  154#[derive(Clone)]
  155struct UnifiedLanguageServer {
  156    id: LanguageServerId,
  157    project_roots: HashSet<Arc<Path>>,
  158}
  159
  160#[derive(Clone, Hash, PartialEq, Eq)]
  161struct LanguageServerSeed {
  162    worktree_id: WorktreeId,
  163    name: LanguageServerName,
  164    toolchain: Option<Toolchain>,
  165    settings: Arc<LspSettings>,
  166}
  167
  168#[derive(Debug)]
  169pub struct DocumentDiagnosticsUpdate<'a, D> {
  170    pub diagnostics: D,
  171    pub result_id: Option<String>,
  172    pub server_id: LanguageServerId,
  173    pub disk_based_sources: Cow<'a, [String]>,
  174}
  175
  176pub struct DocumentDiagnostics {
  177    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  178    document_abs_path: PathBuf,
  179    version: Option<i32>,
  180}
  181
  182pub struct LocalLspStore {
  183    weak: WeakEntity<LspStore>,
  184    worktree_store: Entity<WorktreeStore>,
  185    toolchain_store: Entity<LocalToolchainStore>,
  186    http_client: Arc<dyn HttpClient>,
  187    environment: Entity<ProjectEnvironment>,
  188    fs: Arc<dyn Fs>,
  189    languages: Arc<LanguageRegistry>,
  190    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  191    yarn: Entity<YarnPathStore>,
  192    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  193    buffers_being_formatted: HashSet<BufferId>,
  194    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  195    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  196    watched_manifest_filenames: HashSet<ManifestName>,
  197    language_server_paths_watched_for_rename:
  198        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  199    language_server_watcher_registrations:
  200        HashMap<LanguageServerId, HashMap<String, Vec<FileSystemWatcher>>>,
  201    supplementary_language_servers:
  202        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  203    prettier_store: Entity<PrettierStore>,
  204    next_diagnostic_group_id: usize,
  205    diagnostics: HashMap<
  206        WorktreeId,
  207        HashMap<
  208            Arc<Path>,
  209            Vec<(
  210                LanguageServerId,
  211                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  212            )>,
  213        >,
  214    >,
  215    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  216    _subscription: gpui::Subscription,
  217    lsp_tree: LanguageServerTree,
  218    registered_buffers: HashMap<BufferId, usize>,
  219    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  220    buffer_pull_diagnostics_result_ids: HashMap<LanguageServerId, HashMap<PathBuf, Option<String>>>,
  221}
  222
  223impl LocalLspStore {
  224    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  225    pub fn running_language_server_for_id(
  226        &self,
  227        id: LanguageServerId,
  228    ) -> Option<&Arc<LanguageServer>> {
  229        let language_server_state = self.language_servers.get(&id)?;
  230
  231        match language_server_state {
  232            LanguageServerState::Running { server, .. } => Some(server),
  233            LanguageServerState::Starting { .. } => None,
  234        }
  235    }
  236
  237    fn get_or_insert_language_server(
  238        &mut self,
  239        worktree_handle: &Entity<Worktree>,
  240        delegate: Arc<LocalLspAdapterDelegate>,
  241        disposition: &Arc<LaunchDisposition>,
  242        language_name: &LanguageName,
  243        cx: &mut App,
  244    ) -> LanguageServerId {
  245        let key = LanguageServerSeed {
  246            worktree_id: worktree_handle.read(cx).id(),
  247            name: disposition.server_name.clone(),
  248            settings: disposition.settings.clone(),
  249            toolchain: disposition.toolchain.clone(),
  250        };
  251        if let Some(state) = self.language_server_ids.get_mut(&key) {
  252            state.project_roots.insert(disposition.path.path.clone());
  253            state.id
  254        } else {
  255            let adapter = self
  256                .languages
  257                .lsp_adapters(language_name)
  258                .into_iter()
  259                .find(|adapter| adapter.name() == disposition.server_name)
  260                .expect("To find LSP adapter");
  261            let new_language_server_id = self.start_language_server(
  262                worktree_handle,
  263                delegate,
  264                adapter,
  265                disposition.settings.clone(),
  266                key.clone(),
  267                cx,
  268            );
  269            if let Some(state) = self.language_server_ids.get_mut(&key) {
  270                state.project_roots.insert(disposition.path.path.clone());
  271            } else {
  272                debug_assert!(
  273                    false,
  274                    "Expected `start_language_server` to ensure that `key` exists in a map"
  275                );
  276            }
  277            new_language_server_id
  278        }
  279    }
  280
  281    fn start_language_server(
  282        &mut self,
  283        worktree_handle: &Entity<Worktree>,
  284        delegate: Arc<LocalLspAdapterDelegate>,
  285        adapter: Arc<CachedLspAdapter>,
  286        settings: Arc<LspSettings>,
  287        key: LanguageServerSeed,
  288        cx: &mut App,
  289    ) -> LanguageServerId {
  290        let worktree = worktree_handle.read(cx);
  291
  292        let root_path = worktree.abs_path();
  293        let toolchain = key.toolchain.clone();
  294        let override_options = settings.initialization_options.clone();
  295
  296        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  297
  298        let server_id = self.languages.next_language_server_id();
  299        log::trace!(
  300            "attempting to start language server {:?}, path: {root_path:?}, id: {server_id}",
  301            adapter.name.0
  302        );
  303
  304        let binary = self.get_language_server_binary(
  305            adapter.clone(),
  306            settings,
  307            toolchain.clone(),
  308            delegate.clone(),
  309            true,
  310            cx,
  311        );
  312        let pending_workspace_folders: Arc<Mutex<BTreeSet<Url>>> = Default::default();
  313
  314        let pending_server = cx.spawn({
  315            let adapter = adapter.clone();
  316            let server_name = adapter.name.clone();
  317            let stderr_capture = stderr_capture.clone();
  318            #[cfg(any(test, feature = "test-support"))]
  319            let lsp_store = self.weak.clone();
  320            let pending_workspace_folders = pending_workspace_folders.clone();
  321            async move |cx| {
  322                let binary = binary.await?;
  323                #[cfg(any(test, feature = "test-support"))]
  324                if let Some(server) = lsp_store
  325                    .update(&mut cx.clone(), |this, cx| {
  326                        this.languages.create_fake_language_server(
  327                            server_id,
  328                            &server_name,
  329                            binary.clone(),
  330                            &mut cx.to_async(),
  331                        )
  332                    })
  333                    .ok()
  334                    .flatten()
  335                {
  336                    return Ok(server);
  337                }
  338
  339                let code_action_kinds = adapter.code_action_kinds();
  340                lsp::LanguageServer::new(
  341                    stderr_capture,
  342                    server_id,
  343                    server_name,
  344                    binary,
  345                    &root_path,
  346                    code_action_kinds,
  347                    Some(pending_workspace_folders),
  348                    cx,
  349                )
  350            }
  351        });
  352
  353        let startup = {
  354            let server_name = adapter.name.0.clone();
  355            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  356            let key = key.clone();
  357            let adapter = adapter.clone();
  358            let lsp_store = self.weak.clone();
  359            let pending_workspace_folders = pending_workspace_folders.clone();
  360            let fs = self.fs.clone();
  361            let pull_diagnostics = ProjectSettings::get_global(cx)
  362                .diagnostics
  363                .lsp_pull_diagnostics
  364                .enabled;
  365            cx.spawn(async move |cx| {
  366                let result = async {
  367                    let language_server = pending_server.await?;
  368
  369                    let workspace_config = Self::workspace_configuration_for_adapter(
  370                        adapter.adapter.clone(),
  371                        fs.as_ref(),
  372                        &delegate,
  373                        toolchain,
  374                        cx,
  375                    )
  376                    .await?;
  377
  378                    let mut initialization_options = Self::initialization_options_for_adapter(
  379                        adapter.adapter.clone(),
  380                        fs.as_ref(),
  381                        &delegate,
  382                    )
  383                    .await?;
  384
  385                    match (&mut initialization_options, override_options) {
  386                        (Some(initialization_options), Some(override_options)) => {
  387                            merge_json_value_into(override_options, initialization_options);
  388                        }
  389                        (None, override_options) => initialization_options = override_options,
  390                        _ => {}
  391                    }
  392
  393                    let initialization_params = cx.update(|cx| {
  394                        let mut params =
  395                            language_server.default_initialize_params(pull_diagnostics, cx);
  396                        params.initialization_options = initialization_options;
  397                        adapter.adapter.prepare_initialize_params(params, cx)
  398                    })??;
  399
  400                    Self::setup_lsp_messages(
  401                        lsp_store.clone(),
  402                        fs,
  403                        &language_server,
  404                        delegate.clone(),
  405                        adapter.clone(),
  406                    );
  407
  408                    let did_change_configuration_params =
  409                        Arc::new(lsp::DidChangeConfigurationParams {
  410                            settings: workspace_config,
  411                        });
  412                    let language_server = cx
  413                        .update(|cx| {
  414                            language_server.initialize(
  415                                initialization_params,
  416                                did_change_configuration_params.clone(),
  417                                cx,
  418                            )
  419                        })?
  420                        .await
  421                        .inspect_err(|_| {
  422                            if let Some(lsp_store) = lsp_store.upgrade() {
  423                                lsp_store
  424                                    .update(cx, |lsp_store, cx| {
  425                                        lsp_store.cleanup_lsp_data(server_id);
  426                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  427                                    })
  428                                    .ok();
  429                            }
  430                        })?;
  431
  432                    language_server
  433                        .notify::<lsp::notification::DidChangeConfiguration>(
  434                            &did_change_configuration_params,
  435                        )
  436                        .ok();
  437
  438                    anyhow::Ok(language_server)
  439                }
  440                .await;
  441
  442                match result {
  443                    Ok(server) => {
  444                        lsp_store
  445                            .update(cx, |lsp_store, cx| {
  446                                lsp_store.insert_newly_running_language_server(
  447                                    adapter,
  448                                    server.clone(),
  449                                    server_id,
  450                                    key,
  451                                    pending_workspace_folders,
  452                                    cx,
  453                                );
  454                            })
  455                            .ok();
  456                        stderr_capture.lock().take();
  457                        Some(server)
  458                    }
  459
  460                    Err(err) => {
  461                        let log = stderr_capture.lock().take().unwrap_or_default();
  462                        delegate.update_status(
  463                            adapter.name(),
  464                            BinaryStatus::Failed {
  465                                error: if log.is_empty() {
  466                                    format!("{err:#}")
  467                                } else {
  468                                    format!("{err:#}\n-- stderr --\n{log}")
  469                                },
  470                            },
  471                        );
  472                        log::error!("Failed to start language server {server_name:?}: {err:?}");
  473                        if !log.is_empty() {
  474                            log::error!("server stderr: {log}");
  475                        }
  476                        None
  477                    }
  478                }
  479            })
  480        };
  481        let state = LanguageServerState::Starting {
  482            startup,
  483            pending_workspace_folders,
  484        };
  485
  486        self.languages
  487            .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  488
  489        self.language_servers.insert(server_id, state);
  490        self.language_server_ids
  491            .entry(key)
  492            .or_insert(UnifiedLanguageServer {
  493                id: server_id,
  494                project_roots: Default::default(),
  495            });
  496        server_id
  497    }
  498
  499    fn get_language_server_binary(
  500        &self,
  501        adapter: Arc<CachedLspAdapter>,
  502        settings: Arc<LspSettings>,
  503        toolchain: Option<Toolchain>,
  504        delegate: Arc<dyn LspAdapterDelegate>,
  505        allow_binary_download: bool,
  506        cx: &mut App,
  507    ) -> Task<Result<LanguageServerBinary>> {
  508        if let Some(settings) = settings.binary.as_ref()
  509            && settings.path.is_some()
  510        {
  511            let settings = settings.clone();
  512
  513            return cx.background_spawn(async move {
  514                let mut env = delegate.shell_env().await;
  515                env.extend(settings.env.unwrap_or_default());
  516
  517                Ok(LanguageServerBinary {
  518                    path: PathBuf::from(&settings.path.unwrap()),
  519                    env: Some(env),
  520                    arguments: settings
  521                        .arguments
  522                        .unwrap_or_default()
  523                        .iter()
  524                        .map(Into::into)
  525                        .collect(),
  526                })
  527            });
  528        }
  529        let lsp_binary_options = LanguageServerBinaryOptions {
  530            allow_path_lookup: !settings
  531                .binary
  532                .as_ref()
  533                .and_then(|b| b.ignore_system_version)
  534                .unwrap_or_default(),
  535            allow_binary_download,
  536        };
  537
  538        cx.spawn(async move |cx| {
  539            let binary_result = adapter
  540                .clone()
  541                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  542                .await;
  543
  544            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  545
  546            let mut binary = binary_result?;
  547            let mut shell_env = delegate.shell_env().await;
  548
  549            shell_env.extend(binary.env.unwrap_or_default());
  550
  551            if let Some(settings) = settings.binary.as_ref() {
  552                if let Some(arguments) = &settings.arguments {
  553                    binary.arguments = arguments.iter().map(Into::into).collect();
  554                }
  555                if let Some(env) = &settings.env {
  556                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  557                }
  558            }
  559
  560            binary.env = Some(shell_env);
  561            Ok(binary)
  562        })
  563    }
  564
  565    fn setup_lsp_messages(
  566        this: WeakEntity<LspStore>,
  567        fs: Arc<dyn Fs>,
  568        language_server: &LanguageServer,
  569        delegate: Arc<dyn LspAdapterDelegate>,
  570        adapter: Arc<CachedLspAdapter>,
  571    ) {
  572        let name = language_server.name();
  573        let server_id = language_server.server_id();
  574        language_server
  575            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  576                let adapter = adapter.clone();
  577                let this = this.clone();
  578                move |mut params, cx| {
  579                    let adapter = adapter.clone();
  580                    if let Some(this) = this.upgrade() {
  581                        this.update(cx, |this, cx| {
  582                            {
  583                                let buffer = params
  584                                    .uri
  585                                    .to_file_path()
  586                                    .map(|file_path| this.get_buffer(&file_path, cx))
  587                                    .ok()
  588                                    .flatten();
  589                                adapter.process_diagnostics(&mut params, server_id, buffer);
  590                            }
  591
  592                            this.merge_lsp_diagnostics(
  593                                DiagnosticSourceKind::Pushed,
  594                                vec![DocumentDiagnosticsUpdate {
  595                                    server_id,
  596                                    diagnostics: params,
  597                                    result_id: None,
  598                                    disk_based_sources: Cow::Borrowed(
  599                                        &adapter.disk_based_diagnostic_sources,
  600                                    ),
  601                                }],
  602                                |_, diagnostic, cx| match diagnostic.source_kind {
  603                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  604                                        adapter.retain_old_diagnostic(diagnostic, cx)
  605                                    }
  606                                    DiagnosticSourceKind::Pulled => true,
  607                                },
  608                                cx,
  609                            )
  610                            .log_err();
  611                        })
  612                        .ok();
  613                    }
  614                }
  615            })
  616            .detach();
  617        language_server
  618            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  619                let adapter = adapter.adapter.clone();
  620                let delegate = delegate.clone();
  621                let this = this.clone();
  622                let fs = fs.clone();
  623                move |params, cx| {
  624                    let adapter = adapter.clone();
  625                    let delegate = delegate.clone();
  626                    let this = this.clone();
  627                    let fs = fs.clone();
  628                    let mut cx = cx.clone();
  629                    async move {
  630                        let toolchain_for_id = this
  631                            .update(&mut cx, |this, _| {
  632                                this.as_local()?.language_server_ids.iter().find_map(
  633                                    |(seed, value)| {
  634                                        (value.id == server_id).then(|| seed.toolchain.clone())
  635                                    },
  636                                )
  637                            })?
  638                            .context("Expected the LSP store to be in a local mode")?;
  639                        let workspace_config = Self::workspace_configuration_for_adapter(
  640                            adapter.clone(),
  641                            fs.as_ref(),
  642                            &delegate,
  643                            toolchain_for_id,
  644                            &mut cx,
  645                        )
  646                        .await?;
  647
  648                        Ok(params
  649                            .items
  650                            .into_iter()
  651                            .map(|item| {
  652                                if let Some(section) = &item.section {
  653                                    workspace_config
  654                                        .get(section)
  655                                        .cloned()
  656                                        .unwrap_or(serde_json::Value::Null)
  657                                } else {
  658                                    workspace_config.clone()
  659                                }
  660                            })
  661                            .collect())
  662                    }
  663                }
  664            })
  665            .detach();
  666
  667        language_server
  668            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  669                let this = this.clone();
  670                move |_, cx| {
  671                    let this = this.clone();
  672                    let cx = cx.clone();
  673                    async move {
  674                        let Some(server) =
  675                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  676                        else {
  677                            return Ok(None);
  678                        };
  679                        let root = server.workspace_folders();
  680                        Ok(Some(
  681                            root.into_iter()
  682                                .map(|uri| WorkspaceFolder {
  683                                    uri,
  684                                    name: Default::default(),
  685                                })
  686                                .collect(),
  687                        ))
  688                    }
  689                }
  690            })
  691            .detach();
  692        // Even though we don't have handling for these requests, respond to them to
  693        // avoid stalling any language server like `gopls` which waits for a response
  694        // to these requests when initializing.
  695        language_server
  696            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  697                let this = this.clone();
  698                move |params, cx| {
  699                    let this = this.clone();
  700                    let mut cx = cx.clone();
  701                    async move {
  702                        this.update(&mut cx, |this, _| {
  703                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  704                                && let lsp::NumberOrString::String(token) = params.token
  705                            {
  706                                status.progress_tokens.insert(token);
  707                            }
  708                        })?;
  709
  710                        Ok(())
  711                    }
  712                }
  713            })
  714            .detach();
  715
  716        language_server
  717            .on_request::<lsp::request::RegisterCapability, _, _>({
  718                let lsp_store = this.clone();
  719                move |params, cx| {
  720                    let lsp_store = lsp_store.clone();
  721                    let mut cx = cx.clone();
  722                    async move {
  723                        lsp_store
  724                            .update(&mut cx, |lsp_store, cx| {
  725                                if lsp_store.as_local().is_some() {
  726                                    match lsp_store
  727                                        .register_server_capabilities(server_id, params, cx)
  728                                    {
  729                                        Ok(()) => {}
  730                                        Err(e) => {
  731                                            log::error!(
  732                                                "Failed to register server capabilities: {e:#}"
  733                                            );
  734                                        }
  735                                    };
  736                                }
  737                            })
  738                            .ok();
  739                        Ok(())
  740                    }
  741                }
  742            })
  743            .detach();
  744
  745        language_server
  746            .on_request::<lsp::request::UnregisterCapability, _, _>({
  747                let lsp_store = this.clone();
  748                move |params, cx| {
  749                    let lsp_store = lsp_store.clone();
  750                    let mut cx = cx.clone();
  751                    async move {
  752                        lsp_store
  753                            .update(&mut cx, |lsp_store, cx| {
  754                                if lsp_store.as_local().is_some() {
  755                                    match lsp_store
  756                                        .unregister_server_capabilities(server_id, params, cx)
  757                                    {
  758                                        Ok(()) => {}
  759                                        Err(e) => {
  760                                            log::error!(
  761                                                "Failed to unregister server capabilities: {e:#}"
  762                                            );
  763                                        }
  764                                    }
  765                                }
  766                            })
  767                            .ok();
  768                        Ok(())
  769                    }
  770                }
  771            })
  772            .detach();
  773
  774        language_server
  775            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  776                let this = this.clone();
  777                move |params, cx| {
  778                    let mut cx = cx.clone();
  779                    let this = this.clone();
  780                    async move {
  781                        LocalLspStore::on_lsp_workspace_edit(
  782                            this.clone(),
  783                            params,
  784                            server_id,
  785                            &mut cx,
  786                        )
  787                        .await
  788                    }
  789                }
  790            })
  791            .detach();
  792
  793        language_server
  794            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  795                let this = this.clone();
  796                move |(), cx| {
  797                    let this = this.clone();
  798                    let mut cx = cx.clone();
  799                    async move {
  800                        this.update(&mut cx, |this, cx| {
  801                            cx.emit(LspStoreEvent::RefreshInlayHints);
  802                            this.downstream_client.as_ref().map(|(client, project_id)| {
  803                                client.send(proto::RefreshInlayHints {
  804                                    project_id: *project_id,
  805                                })
  806                            })
  807                        })?
  808                        .transpose()?;
  809                        Ok(())
  810                    }
  811                }
  812            })
  813            .detach();
  814
  815        language_server
  816            .on_request::<lsp::request::CodeLensRefresh, _, _>({
  817                let this = this.clone();
  818                move |(), cx| {
  819                    let this = this.clone();
  820                    let mut cx = cx.clone();
  821                    async move {
  822                        this.update(&mut cx, |this, cx| {
  823                            cx.emit(LspStoreEvent::RefreshCodeLens);
  824                            this.downstream_client.as_ref().map(|(client, project_id)| {
  825                                client.send(proto::RefreshCodeLens {
  826                                    project_id: *project_id,
  827                                })
  828                            })
  829                        })?
  830                        .transpose()?;
  831                        Ok(())
  832                    }
  833                }
  834            })
  835            .detach();
  836
  837        language_server
  838            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
  839                let this = this.clone();
  840                move |(), cx| {
  841                    let this = this.clone();
  842                    let mut cx = cx.clone();
  843                    async move {
  844                        this.update(&mut cx, |lsp_store, _| {
  845                            lsp_store.pull_workspace_diagnostics(server_id);
  846                            lsp_store
  847                                .downstream_client
  848                                .as_ref()
  849                                .map(|(client, project_id)| {
  850                                    client.send(proto::PullWorkspaceDiagnostics {
  851                                        project_id: *project_id,
  852                                        server_id: server_id.to_proto(),
  853                                    })
  854                                })
  855                        })?
  856                        .transpose()?;
  857                        Ok(())
  858                    }
  859                }
  860            })
  861            .detach();
  862
  863        language_server
  864            .on_request::<lsp::request::ShowMessageRequest, _, _>({
  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                    async move {
  872                        let actions = params.actions.unwrap_or_default();
  873                        let (tx, rx) = smol::channel::bounded(1);
  874                        let request = LanguageServerPromptRequest {
  875                            level: match params.typ {
  876                                lsp::MessageType::ERROR => PromptLevel::Critical,
  877                                lsp::MessageType::WARNING => PromptLevel::Warning,
  878                                _ => PromptLevel::Info,
  879                            },
  880                            message: params.message,
  881                            actions,
  882                            response_channel: tx,
  883                            lsp_name: name.clone(),
  884                        };
  885
  886                        let did_update = this
  887                            .update(&mut cx, |_, cx| {
  888                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
  889                            })
  890                            .is_ok();
  891                        if did_update {
  892                            let response = rx.recv().await.ok();
  893                            Ok(response)
  894                        } else {
  895                            Ok(None)
  896                        }
  897                    }
  898                }
  899            })
  900            .detach();
  901        language_server
  902            .on_notification::<lsp::notification::ShowMessage, _>({
  903                let this = this.clone();
  904                let name = name.to_string();
  905                move |params, cx| {
  906                    let this = this.clone();
  907                    let name = name.to_string();
  908                    let mut cx = cx.clone();
  909
  910                    let (tx, _) = smol::channel::bounded(1);
  911                    let request = LanguageServerPromptRequest {
  912                        level: match params.typ {
  913                            lsp::MessageType::ERROR => PromptLevel::Critical,
  914                            lsp::MessageType::WARNING => PromptLevel::Warning,
  915                            _ => PromptLevel::Info,
  916                        },
  917                        message: params.message,
  918                        actions: vec![],
  919                        response_channel: tx,
  920                        lsp_name: name,
  921                    };
  922
  923                    let _ = this.update(&mut cx, |_, cx| {
  924                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
  925                    });
  926                }
  927            })
  928            .detach();
  929
  930        let disk_based_diagnostics_progress_token =
  931            adapter.disk_based_diagnostics_progress_token.clone();
  932
  933        language_server
  934            .on_notification::<lsp::notification::Progress, _>({
  935                let this = this.clone();
  936                move |params, cx| {
  937                    if let Some(this) = this.upgrade() {
  938                        this.update(cx, |this, cx| {
  939                            this.on_lsp_progress(
  940                                params,
  941                                server_id,
  942                                disk_based_diagnostics_progress_token.clone(),
  943                                cx,
  944                            );
  945                        })
  946                        .ok();
  947                    }
  948                }
  949            })
  950            .detach();
  951
  952        language_server
  953            .on_notification::<lsp::notification::LogMessage, _>({
  954                let this = this.clone();
  955                move |params, cx| {
  956                    if let Some(this) = this.upgrade() {
  957                        this.update(cx, |_, cx| {
  958                            cx.emit(LspStoreEvent::LanguageServerLog(
  959                                server_id,
  960                                LanguageServerLogType::Log(params.typ),
  961                                params.message,
  962                            ));
  963                        })
  964                        .ok();
  965                    }
  966                }
  967            })
  968            .detach();
  969
  970        language_server
  971            .on_notification::<lsp::notification::LogTrace, _>({
  972                let this = this.clone();
  973                move |params, cx| {
  974                    let mut cx = cx.clone();
  975                    if let Some(this) = this.upgrade() {
  976                        this.update(&mut cx, |_, cx| {
  977                            cx.emit(LspStoreEvent::LanguageServerLog(
  978                                server_id,
  979                                LanguageServerLogType::Trace(params.verbose),
  980                                params.message,
  981                            ));
  982                        })
  983                        .ok();
  984                    }
  985                }
  986            })
  987            .detach();
  988
  989        json_language_server_ext::register_requests(this.clone(), language_server);
  990        rust_analyzer_ext::register_notifications(this.clone(), language_server);
  991        clangd_ext::register_notifications(this, language_server, adapter);
  992    }
  993
  994    fn shutdown_language_servers_on_quit(
  995        &mut self,
  996        _: &mut Context<LspStore>,
  997    ) -> impl Future<Output = ()> + use<> {
  998        let shutdown_futures = self
  999            .language_servers
 1000            .drain()
 1001            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1002            .collect::<Vec<_>>();
 1003
 1004        async move {
 1005            join_all(shutdown_futures).await;
 1006        }
 1007    }
 1008
 1009    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1010        match server_state {
 1011            LanguageServerState::Running { server, .. } => {
 1012                if let Some(shutdown) = server.shutdown() {
 1013                    shutdown.await;
 1014                }
 1015            }
 1016            LanguageServerState::Starting { startup, .. } => {
 1017                if let Some(server) = startup.await
 1018                    && let Some(shutdown) = server.shutdown()
 1019                {
 1020                    shutdown.await;
 1021                }
 1022            }
 1023        }
 1024        Ok(())
 1025    }
 1026
 1027    fn language_servers_for_worktree(
 1028        &self,
 1029        worktree_id: WorktreeId,
 1030    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1031        self.language_server_ids
 1032            .iter()
 1033            .filter_map(move |(seed, state)| {
 1034                if seed.worktree_id != worktree_id {
 1035                    return None;
 1036                }
 1037
 1038                if let Some(LanguageServerState::Running { server, .. }) =
 1039                    self.language_servers.get(&state.id)
 1040                {
 1041                    Some(server)
 1042                } else {
 1043                    None
 1044                }
 1045            })
 1046    }
 1047
 1048    fn language_server_ids_for_project_path(
 1049        &self,
 1050        project_path: ProjectPath,
 1051        language: &Language,
 1052        cx: &mut App,
 1053    ) -> Vec<LanguageServerId> {
 1054        let Some(worktree) = self
 1055            .worktree_store
 1056            .read(cx)
 1057            .worktree_for_id(project_path.worktree_id, cx)
 1058        else {
 1059            return Vec::new();
 1060        };
 1061        let delegate: Arc<dyn ManifestDelegate> =
 1062            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1063
 1064        self.lsp_tree
 1065            .get(
 1066                project_path,
 1067                language.name(),
 1068                language.manifest(),
 1069                &delegate,
 1070                cx,
 1071            )
 1072            .collect::<Vec<_>>()
 1073    }
 1074
 1075    fn language_server_ids_for_buffer(
 1076        &self,
 1077        buffer: &Buffer,
 1078        cx: &mut App,
 1079    ) -> Vec<LanguageServerId> {
 1080        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1081            let worktree_id = file.worktree_id(cx);
 1082
 1083            let path: Arc<Path> = file
 1084                .path()
 1085                .parent()
 1086                .map(Arc::from)
 1087                .unwrap_or_else(|| file.path().clone());
 1088            let worktree_path = ProjectPath { worktree_id, path };
 1089            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1090        } else {
 1091            Vec::new()
 1092        }
 1093    }
 1094
 1095    fn language_servers_for_buffer<'a>(
 1096        &'a self,
 1097        buffer: &'a Buffer,
 1098        cx: &'a mut App,
 1099    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1100        self.language_server_ids_for_buffer(buffer, cx)
 1101            .into_iter()
 1102            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1103                LanguageServerState::Running {
 1104                    adapter, server, ..
 1105                } => Some((adapter, server)),
 1106                _ => None,
 1107            })
 1108    }
 1109
 1110    async fn execute_code_action_kind_locally(
 1111        lsp_store: WeakEntity<LspStore>,
 1112        mut buffers: Vec<Entity<Buffer>>,
 1113        kind: CodeActionKind,
 1114        push_to_history: bool,
 1115        cx: &mut AsyncApp,
 1116    ) -> anyhow::Result<ProjectTransaction> {
 1117        // Do not allow multiple concurrent code actions requests for the
 1118        // same buffer.
 1119        lsp_store.update(cx, |this, cx| {
 1120            let this = this.as_local_mut().unwrap();
 1121            buffers.retain(|buffer| {
 1122                this.buffers_being_formatted
 1123                    .insert(buffer.read(cx).remote_id())
 1124            });
 1125        })?;
 1126        let _cleanup = defer({
 1127            let this = lsp_store.clone();
 1128            let mut cx = cx.clone();
 1129            let buffers = &buffers;
 1130            move || {
 1131                this.update(&mut cx, |this, cx| {
 1132                    let this = this.as_local_mut().unwrap();
 1133                    for buffer in buffers {
 1134                        this.buffers_being_formatted
 1135                            .remove(&buffer.read(cx).remote_id());
 1136                    }
 1137                })
 1138                .ok();
 1139            }
 1140        });
 1141        let mut project_transaction = ProjectTransaction::default();
 1142
 1143        for buffer in &buffers {
 1144            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1145                buffer.update(cx, |buffer, cx| {
 1146                    lsp_store
 1147                        .as_local()
 1148                        .unwrap()
 1149                        .language_servers_for_buffer(buffer, cx)
 1150                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1151                        .collect::<Vec<_>>()
 1152                })
 1153            })?;
 1154            for (_, language_server) in adapters_and_servers.iter() {
 1155                let actions = Self::get_server_code_actions_from_action_kinds(
 1156                    &lsp_store,
 1157                    language_server.server_id(),
 1158                    vec![kind.clone()],
 1159                    buffer,
 1160                    cx,
 1161                )
 1162                .await?;
 1163                Self::execute_code_actions_on_server(
 1164                    &lsp_store,
 1165                    language_server,
 1166                    actions,
 1167                    push_to_history,
 1168                    &mut project_transaction,
 1169                    cx,
 1170                )
 1171                .await?;
 1172            }
 1173        }
 1174        Ok(project_transaction)
 1175    }
 1176
 1177    async fn format_locally(
 1178        lsp_store: WeakEntity<LspStore>,
 1179        mut buffers: Vec<FormattableBuffer>,
 1180        push_to_history: bool,
 1181        trigger: FormatTrigger,
 1182        logger: zlog::Logger,
 1183        cx: &mut AsyncApp,
 1184    ) -> anyhow::Result<ProjectTransaction> {
 1185        // Do not allow multiple concurrent formatting requests for the
 1186        // same buffer.
 1187        lsp_store.update(cx, |this, cx| {
 1188            let this = this.as_local_mut().unwrap();
 1189            buffers.retain(|buffer| {
 1190                this.buffers_being_formatted
 1191                    .insert(buffer.handle.read(cx).remote_id())
 1192            });
 1193        })?;
 1194
 1195        let _cleanup = defer({
 1196            let this = lsp_store.clone();
 1197            let mut cx = cx.clone();
 1198            let buffers = &buffers;
 1199            move || {
 1200                this.update(&mut cx, |this, cx| {
 1201                    let this = this.as_local_mut().unwrap();
 1202                    for buffer in buffers {
 1203                        this.buffers_being_formatted
 1204                            .remove(&buffer.handle.read(cx).remote_id());
 1205                    }
 1206                })
 1207                .ok();
 1208            }
 1209        });
 1210
 1211        let mut project_transaction = ProjectTransaction::default();
 1212
 1213        for buffer in &buffers {
 1214            zlog::debug!(
 1215                logger =>
 1216                "formatting buffer '{:?}'",
 1217                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1218            );
 1219            // Create an empty transaction to hold all of the formatting edits.
 1220            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1221                // ensure no transactions created while formatting are
 1222                // grouped with the previous transaction in the history
 1223                // based on the transaction group interval
 1224                buffer.finalize_last_transaction();
 1225                buffer
 1226                    .start_transaction()
 1227                    .context("transaction already open")?;
 1228                buffer.end_transaction(cx);
 1229                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1230                buffer.finalize_last_transaction();
 1231                anyhow::Ok(transaction_id)
 1232            })??;
 1233
 1234            let result = Self::format_buffer_locally(
 1235                lsp_store.clone(),
 1236                buffer,
 1237                formatting_transaction_id,
 1238                trigger,
 1239                logger,
 1240                cx,
 1241            )
 1242            .await;
 1243
 1244            buffer.handle.update(cx, |buffer, cx| {
 1245                let Some(formatting_transaction) =
 1246                    buffer.get_transaction(formatting_transaction_id).cloned()
 1247                else {
 1248                    zlog::warn!(logger => "no formatting transaction");
 1249                    return;
 1250                };
 1251                if formatting_transaction.edit_ids.is_empty() {
 1252                    zlog::debug!(logger => "no changes made while formatting");
 1253                    buffer.forget_transaction(formatting_transaction_id);
 1254                    return;
 1255                }
 1256                if !push_to_history {
 1257                    zlog::trace!(logger => "forgetting format transaction");
 1258                    buffer.forget_transaction(formatting_transaction.id);
 1259                }
 1260                project_transaction
 1261                    .0
 1262                    .insert(cx.entity(), formatting_transaction);
 1263            })?;
 1264
 1265            result?;
 1266        }
 1267
 1268        Ok(project_transaction)
 1269    }
 1270
 1271    async fn format_buffer_locally(
 1272        lsp_store: WeakEntity<LspStore>,
 1273        buffer: &FormattableBuffer,
 1274        formatting_transaction_id: clock::Lamport,
 1275        trigger: FormatTrigger,
 1276        logger: zlog::Logger,
 1277        cx: &mut AsyncApp,
 1278    ) -> Result<()> {
 1279        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1280            buffer.handle.update(cx, |buffer, cx| {
 1281                let adapters_and_servers = lsp_store
 1282                    .as_local()
 1283                    .unwrap()
 1284                    .language_servers_for_buffer(buffer, cx)
 1285                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1286                    .collect::<Vec<_>>();
 1287                let settings =
 1288                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1289                        .into_owned();
 1290                (adapters_and_servers, settings)
 1291            })
 1292        })?;
 1293
 1294        /// Apply edits to the buffer that will become part of the formatting transaction.
 1295        /// Fails if the buffer has been edited since the start of that transaction.
 1296        fn extend_formatting_transaction(
 1297            buffer: &FormattableBuffer,
 1298            formatting_transaction_id: text::TransactionId,
 1299            cx: &mut AsyncApp,
 1300            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1301        ) -> anyhow::Result<()> {
 1302            buffer.handle.update(cx, |buffer, cx| {
 1303                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1304                if last_transaction_id != Some(formatting_transaction_id) {
 1305                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1306                }
 1307                buffer.start_transaction();
 1308                operation(buffer, cx);
 1309                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1310                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1311                }
 1312                Ok(())
 1313            })?
 1314        }
 1315
 1316        // handle whitespace formatting
 1317        if settings.remove_trailing_whitespace_on_save {
 1318            zlog::trace!(logger => "removing trailing whitespace");
 1319            let diff = buffer
 1320                .handle
 1321                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))?
 1322                .await;
 1323            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1324                buffer.apply_diff(diff, cx);
 1325            })?;
 1326        }
 1327
 1328        if settings.ensure_final_newline_on_save {
 1329            zlog::trace!(logger => "ensuring final newline");
 1330            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1331                buffer.ensure_final_newline(cx);
 1332            })?;
 1333        }
 1334
 1335        // Formatter for `code_actions_on_format` that runs before
 1336        // the rest of the formatters
 1337        let mut code_actions_on_format_formatter = None;
 1338        let should_run_code_actions_on_format = !matches!(
 1339            (trigger, &settings.format_on_save),
 1340            (FormatTrigger::Save, &FormatOnSave::Off)
 1341        );
 1342        if should_run_code_actions_on_format {
 1343            let have_code_actions_to_run_on_format = settings
 1344                .code_actions_on_format
 1345                .values()
 1346                .any(|enabled| *enabled);
 1347            if have_code_actions_to_run_on_format {
 1348                zlog::trace!(logger => "going to run code actions on format");
 1349                code_actions_on_format_formatter = Some(Formatter::CodeActions(
 1350                    settings.code_actions_on_format.clone(),
 1351                ));
 1352            }
 1353        }
 1354
 1355        let formatters = match (trigger, &settings.format_on_save) {
 1356            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1357            (FormatTrigger::Save, FormatOnSave::List(formatters)) => formatters.as_ref(),
 1358            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1359                match &settings.formatter {
 1360                    SelectedFormatter::Auto => {
 1361                        if settings.prettier.allowed {
 1362                            zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1363                            std::slice::from_ref(&Formatter::Prettier)
 1364                        } else {
 1365                            zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1366                            std::slice::from_ref(&Formatter::LanguageServer { name: None })
 1367                        }
 1368                    }
 1369                    SelectedFormatter::List(formatter_list) => formatter_list.as_ref(),
 1370                }
 1371            }
 1372        };
 1373
 1374        let formatters = code_actions_on_format_formatter.iter().chain(formatters);
 1375
 1376        for formatter in formatters {
 1377            match formatter {
 1378                Formatter::Prettier => {
 1379                    let logger = zlog::scoped!(logger => "prettier");
 1380                    zlog::trace!(logger => "formatting");
 1381                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1382
 1383                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1384                        lsp_store.prettier_store().unwrap().downgrade()
 1385                    })?;
 1386                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1387                        .await
 1388                        .transpose()?;
 1389                    let Some(diff) = diff else {
 1390                        zlog::trace!(logger => "No changes");
 1391                        continue;
 1392                    };
 1393
 1394                    extend_formatting_transaction(
 1395                        buffer,
 1396                        formatting_transaction_id,
 1397                        cx,
 1398                        |buffer, cx| {
 1399                            buffer.apply_diff(diff, cx);
 1400                        },
 1401                    )?;
 1402                }
 1403                Formatter::External { command, arguments } => {
 1404                    let logger = zlog::scoped!(logger => "command");
 1405                    zlog::trace!(logger => "formatting");
 1406                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1407
 1408                    let diff = Self::format_via_external_command(
 1409                        buffer,
 1410                        command.as_ref(),
 1411                        arguments.as_deref(),
 1412                        cx,
 1413                    )
 1414                    .await
 1415                    .with_context(|| {
 1416                        format!("Failed to format buffer via external command: {}", command)
 1417                    })?;
 1418                    let Some(diff) = diff else {
 1419                        zlog::trace!(logger => "No changes");
 1420                        continue;
 1421                    };
 1422
 1423                    extend_formatting_transaction(
 1424                        buffer,
 1425                        formatting_transaction_id,
 1426                        cx,
 1427                        |buffer, cx| {
 1428                            buffer.apply_diff(diff, cx);
 1429                        },
 1430                    )?;
 1431                }
 1432                Formatter::LanguageServer { name } => {
 1433                    let logger = zlog::scoped!(logger => "language-server");
 1434                    zlog::trace!(logger => "formatting");
 1435                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1436
 1437                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1438                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1439                        continue;
 1440                    };
 1441
 1442                    let language_server = if let Some(name) = name.as_deref() {
 1443                        adapters_and_servers.iter().find_map(|(adapter, server)| {
 1444                            if adapter.name.0.as_ref() == name {
 1445                                Some(server.clone())
 1446                            } else {
 1447                                None
 1448                            }
 1449                        })
 1450                    } else {
 1451                        adapters_and_servers.first().map(|e| e.1.clone())
 1452                    };
 1453
 1454                    let Some(language_server) = language_server else {
 1455                        log::debug!(
 1456                            "No language server found to format buffer '{:?}'. Skipping",
 1457                            buffer_path_abs.as_path().to_string_lossy()
 1458                        );
 1459                        continue;
 1460                    };
 1461
 1462                    zlog::trace!(
 1463                        logger =>
 1464                        "Formatting buffer '{:?}' using language server '{:?}'",
 1465                        buffer_path_abs.as_path().to_string_lossy(),
 1466                        language_server.name()
 1467                    );
 1468
 1469                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1470                        zlog::trace!(logger => "formatting ranges");
 1471                        Self::format_ranges_via_lsp(
 1472                            &lsp_store,
 1473                            &buffer.handle,
 1474                            ranges,
 1475                            buffer_path_abs,
 1476                            &language_server,
 1477                            &settings,
 1478                            cx,
 1479                        )
 1480                        .await
 1481                        .context("Failed to format ranges via language server")?
 1482                    } else {
 1483                        zlog::trace!(logger => "formatting full");
 1484                        Self::format_via_lsp(
 1485                            &lsp_store,
 1486                            &buffer.handle,
 1487                            buffer_path_abs,
 1488                            &language_server,
 1489                            &settings,
 1490                            cx,
 1491                        )
 1492                        .await
 1493                        .context("failed to format via language server")?
 1494                    };
 1495
 1496                    if edits.is_empty() {
 1497                        zlog::trace!(logger => "No changes");
 1498                        continue;
 1499                    }
 1500                    extend_formatting_transaction(
 1501                        buffer,
 1502                        formatting_transaction_id,
 1503                        cx,
 1504                        |buffer, cx| {
 1505                            buffer.edit(edits, None, cx);
 1506                        },
 1507                    )?;
 1508                }
 1509                Formatter::CodeActions(code_actions) => {
 1510                    let logger = zlog::scoped!(logger => "code-actions");
 1511                    zlog::trace!(logger => "formatting");
 1512                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1513
 1514                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1515                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1516                        continue;
 1517                    };
 1518                    let code_action_kinds = code_actions
 1519                        .iter()
 1520                        .filter_map(|(action_kind, enabled)| {
 1521                            enabled.then_some(action_kind.clone().into())
 1522                        })
 1523                        .collect::<Vec<_>>();
 1524                    if code_action_kinds.is_empty() {
 1525                        zlog::trace!(logger => "No code action kinds enabled, skipping");
 1526                        continue;
 1527                    }
 1528                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kinds);
 1529
 1530                    let mut actions_and_servers = Vec::new();
 1531
 1532                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1533                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1534                            &lsp_store,
 1535                            language_server.server_id(),
 1536                            code_action_kinds.clone(),
 1537                            &buffer.handle,
 1538                            cx,
 1539                        )
 1540                        .await
 1541                        .with_context(
 1542                            || format!("Failed to resolve code actions with kinds {:?} for language server {}",
 1543                                code_action_kinds.iter().map(|kind| kind.as_str()).join(", "),
 1544                                language_server.name())
 1545                        );
 1546                        let Ok(actions) = actions_result else {
 1547                            // note: it may be better to set result to the error and break formatters here
 1548                            // but for now we try to execute the actions that we can resolve and skip the rest
 1549                            zlog::error!(
 1550                                logger =>
 1551                                "Failed to resolve code actions with kinds {:?} with language server {}",
 1552                                code_action_kinds.iter().map(|kind| kind.as_str()).join(", "),
 1553                                language_server.name()
 1554                            );
 1555                            continue;
 1556                        };
 1557                        for action in actions {
 1558                            actions_and_servers.push((action, index));
 1559                        }
 1560                    }
 1561
 1562                    if actions_and_servers.is_empty() {
 1563                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1564                        continue;
 1565                    }
 1566
 1567                    'actions: for (mut action, server_index) in actions_and_servers {
 1568                        let server = &adapters_and_servers[server_index].1;
 1569
 1570                        let describe_code_action = |action: &CodeAction| {
 1571                            format!(
 1572                                "code action '{}' with title \"{}\" on server {}",
 1573                                action
 1574                                    .lsp_action
 1575                                    .action_kind()
 1576                                    .unwrap_or("unknown".into())
 1577                                    .as_str(),
 1578                                action.lsp_action.title(),
 1579                                server.name(),
 1580                            )
 1581                        };
 1582
 1583                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1584
 1585                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1586                            zlog::error!(
 1587                                logger =>
 1588                                "Failed to resolve {}. Error: {}",
 1589                                describe_code_action(&action),
 1590                                err
 1591                            );
 1592                            continue;
 1593                        }
 1594
 1595                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1596                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1597                            // but filters out and logs warnings for code actions that cause unreasonably
 1598                            // difficult handling on our part, such as:
 1599                            // - applying edits that call commands
 1600                            //   which can result in arbitrary workspace edits being sent from the server that
 1601                            //   have no way of being tied back to the command that initiated them (i.e. we
 1602                            //   can't know which edits are part of the format request, or if the server is done sending
 1603                            //   actions in response to the command)
 1604                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1605                            //   as we then would need to handle such changes correctly in the local history as well
 1606                            //   as the remote history through the ProjectTransaction
 1607                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1608                            // Supporting these actions is not impossible, but not supported as of yet.
 1609                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1610                                zlog::trace!(
 1611                                    logger =>
 1612                                    "No changes for code action. Skipping {}",
 1613                                    describe_code_action(&action),
 1614                                );
 1615                                continue;
 1616                            }
 1617
 1618                            let mut operations = Vec::new();
 1619                            if let Some(document_changes) = edit.document_changes {
 1620                                match document_changes {
 1621                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1622                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1623                                    ),
 1624                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1625                                }
 1626                            } else if let Some(changes) = edit.changes {
 1627                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1628                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1629                                        text_document:
 1630                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1631                                                uri,
 1632                                                version: None,
 1633                                            },
 1634                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1635                                    })
 1636                                }));
 1637                            }
 1638
 1639                            let mut edits = Vec::with_capacity(operations.len());
 1640
 1641                            if operations.is_empty() {
 1642                                zlog::trace!(
 1643                                    logger =>
 1644                                    "No changes for code action. Skipping {}",
 1645                                    describe_code_action(&action),
 1646                                );
 1647                                continue;
 1648                            }
 1649                            for operation in operations {
 1650                                let op = match operation {
 1651                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1652                                    lsp::DocumentChangeOperation::Op(_) => {
 1653                                        zlog::warn!(
 1654                                            logger =>
 1655                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1656                                            describe_code_action(&action),
 1657                                        );
 1658                                        continue 'actions;
 1659                                    }
 1660                                };
 1661                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1662                                    zlog::warn!(
 1663                                        logger =>
 1664                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1665                                        &op.text_document.uri,
 1666                                        describe_code_action(&action),
 1667                                    );
 1668                                    continue 'actions;
 1669                                };
 1670                                if &file_path != buffer_path_abs {
 1671                                    zlog::warn!(
 1672                                        logger =>
 1673                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1674                                        file_path,
 1675                                        buffer_path_abs,
 1676                                        describe_code_action(&action),
 1677                                    );
 1678                                    continue 'actions;
 1679                                }
 1680
 1681                                let mut lsp_edits = Vec::new();
 1682                                for edit in op.edits {
 1683                                    match edit {
 1684                                        Edit::Plain(edit) => {
 1685                                            if !lsp_edits.contains(&edit) {
 1686                                                lsp_edits.push(edit);
 1687                                            }
 1688                                        }
 1689                                        Edit::Annotated(edit) => {
 1690                                            if !lsp_edits.contains(&edit.text_edit) {
 1691                                                lsp_edits.push(edit.text_edit);
 1692                                            }
 1693                                        }
 1694                                        Edit::Snippet(_) => {
 1695                                            zlog::warn!(
 1696                                                logger =>
 1697                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1698                                                describe_code_action(&action),
 1699                                            );
 1700                                            continue 'actions;
 1701                                        }
 1702                                    }
 1703                                }
 1704                                let edits_result = lsp_store
 1705                                    .update(cx, |lsp_store, cx| {
 1706                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1707                                            &buffer.handle,
 1708                                            lsp_edits,
 1709                                            server.server_id(),
 1710                                            op.text_document.version,
 1711                                            cx,
 1712                                        )
 1713                                    })?
 1714                                    .await;
 1715                                let Ok(resolved_edits) = edits_result else {
 1716                                    zlog::warn!(
 1717                                        logger =>
 1718                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1719                                        buffer_path_abs.as_path(),
 1720                                        describe_code_action(&action),
 1721                                    );
 1722                                    continue 'actions;
 1723                                };
 1724                                edits.extend(resolved_edits);
 1725                            }
 1726
 1727                            if edits.is_empty() {
 1728                                zlog::warn!(logger => "No edits resolved from LSP");
 1729                                continue;
 1730                            }
 1731
 1732                            extend_formatting_transaction(
 1733                                buffer,
 1734                                formatting_transaction_id,
 1735                                cx,
 1736                                |buffer, cx| {
 1737                                    buffer.edit(edits, None, cx);
 1738                                },
 1739                            )?;
 1740                        }
 1741
 1742                        if let Some(command) = action.lsp_action.command() {
 1743                            zlog::warn!(
 1744                                logger =>
 1745                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1746                                &command.command,
 1747                            );
 1748
 1749                            // bail early if command is invalid
 1750                            let server_capabilities = server.capabilities();
 1751                            let available_commands = server_capabilities
 1752                                .execute_command_provider
 1753                                .as_ref()
 1754                                .map(|options| options.commands.as_slice())
 1755                                .unwrap_or_default();
 1756                            if !available_commands.contains(&command.command) {
 1757                                zlog::warn!(
 1758                                    logger =>
 1759                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1760                                    command.command,
 1761                                    server.name(),
 1762                                );
 1763                                continue;
 1764                            }
 1765
 1766                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 1767                            extend_formatting_transaction(
 1768                                buffer,
 1769                                formatting_transaction_id,
 1770                                cx,
 1771                                |_, _| {},
 1772                            )?;
 1773                            zlog::info!(logger => "Executing command {}", &command.command);
 1774
 1775                            lsp_store.update(cx, |this, _| {
 1776                                this.as_local_mut()
 1777                                    .unwrap()
 1778                                    .last_workspace_edits_by_language_server
 1779                                    .remove(&server.server_id());
 1780                            })?;
 1781
 1782                            let execute_command_result = server
 1783                                .request::<lsp::request::ExecuteCommand>(
 1784                                    lsp::ExecuteCommandParams {
 1785                                        command: command.command.clone(),
 1786                                        arguments: command.arguments.clone().unwrap_or_default(),
 1787                                        ..Default::default()
 1788                                    },
 1789                                )
 1790                                .await
 1791                                .into_response();
 1792
 1793                            if execute_command_result.is_err() {
 1794                                zlog::error!(
 1795                                    logger =>
 1796                                    "Failed to execute command '{}' as part of {}",
 1797                                    &command.command,
 1798                                    describe_code_action(&action),
 1799                                );
 1800                                continue 'actions;
 1801                            }
 1802
 1803                            let mut project_transaction_command =
 1804                                lsp_store.update(cx, |this, _| {
 1805                                    this.as_local_mut()
 1806                                        .unwrap()
 1807                                        .last_workspace_edits_by_language_server
 1808                                        .remove(&server.server_id())
 1809                                        .unwrap_or_default()
 1810                                })?;
 1811
 1812                            if let Some(transaction) =
 1813                                project_transaction_command.0.remove(&buffer.handle)
 1814                            {
 1815                                zlog::trace!(
 1816                                    logger =>
 1817                                    "Successfully captured {} edits that resulted from command {}",
 1818                                    transaction.edit_ids.len(),
 1819                                    &command.command,
 1820                                );
 1821                                let transaction_id_project_transaction = transaction.id;
 1822                                buffer.handle.update(cx, |buffer, _| {
 1823                                    // it may have been removed from history if push_to_history was
 1824                                    // false in deserialize_workspace_edit. If so push it so we
 1825                                    // can merge it with the format transaction
 1826                                    // and pop the combined transaction off the history stack
 1827                                    // later if push_to_history is false
 1828                                    if buffer.get_transaction(transaction.id).is_none() {
 1829                                        buffer.push_transaction(transaction, Instant::now());
 1830                                    }
 1831                                    buffer.merge_transactions(
 1832                                        transaction_id_project_transaction,
 1833                                        formatting_transaction_id,
 1834                                    );
 1835                                })?;
 1836                            }
 1837
 1838                            if !project_transaction_command.0.is_empty() {
 1839                                let extra_buffers = project_transaction_command
 1840                                    .0
 1841                                    .keys()
 1842                                    .filter_map(|buffer_handle| {
 1843                                        buffer_handle
 1844                                            .read_with(cx, |b, cx| b.project_path(cx))
 1845                                            .ok()
 1846                                            .flatten()
 1847                                    })
 1848                                    .map(|p| p.path.to_sanitized_string())
 1849                                    .join(", ");
 1850                                zlog::warn!(
 1851                                    logger =>
 1852                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 1853                                    &command.command,
 1854                                    extra_buffers,
 1855                                );
 1856                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 1857                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 1858                                // add it so it's included, and merge it into the format transaction when its created later
 1859                            }
 1860                        }
 1861                    }
 1862                }
 1863            }
 1864        }
 1865
 1866        Ok(())
 1867    }
 1868
 1869    pub async fn format_ranges_via_lsp(
 1870        this: &WeakEntity<LspStore>,
 1871        buffer_handle: &Entity<Buffer>,
 1872        ranges: &[Range<Anchor>],
 1873        abs_path: &Path,
 1874        language_server: &Arc<LanguageServer>,
 1875        settings: &LanguageSettings,
 1876        cx: &mut AsyncApp,
 1877    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 1878        let capabilities = &language_server.capabilities();
 1879        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 1880        if range_formatting_provider == Some(&OneOf::Left(false)) {
 1881            anyhow::bail!(
 1882                "{} language server does not support range formatting",
 1883                language_server.name()
 1884            );
 1885        }
 1886
 1887        let uri = file_path_to_lsp_url(abs_path)?;
 1888        let text_document = lsp::TextDocumentIdentifier::new(uri);
 1889
 1890        let lsp_edits = {
 1891            let mut lsp_ranges = Vec::new();
 1892            this.update(cx, |_this, cx| {
 1893                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 1894                // not have been sent to the language server. This seems like a fairly systemic
 1895                // issue, though, the resolution probably is not specific to formatting.
 1896                //
 1897                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 1898                // LSP.
 1899                let snapshot = buffer_handle.read(cx).snapshot();
 1900                for range in ranges {
 1901                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 1902                }
 1903                anyhow::Ok(())
 1904            })??;
 1905
 1906            let mut edits = None;
 1907            for range in lsp_ranges {
 1908                if let Some(mut edit) = language_server
 1909                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 1910                        text_document: text_document.clone(),
 1911                        range,
 1912                        options: lsp_command::lsp_formatting_options(settings),
 1913                        work_done_progress_params: Default::default(),
 1914                    })
 1915                    .await
 1916                    .into_response()?
 1917                {
 1918                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 1919                }
 1920            }
 1921            edits
 1922        };
 1923
 1924        if let Some(lsp_edits) = lsp_edits {
 1925            this.update(cx, |this, cx| {
 1926                this.as_local_mut().unwrap().edits_from_lsp(
 1927                    buffer_handle,
 1928                    lsp_edits,
 1929                    language_server.server_id(),
 1930                    None,
 1931                    cx,
 1932                )
 1933            })?
 1934            .await
 1935        } else {
 1936            Ok(Vec::with_capacity(0))
 1937        }
 1938    }
 1939
 1940    async fn format_via_lsp(
 1941        this: &WeakEntity<LspStore>,
 1942        buffer: &Entity<Buffer>,
 1943        abs_path: &Path,
 1944        language_server: &Arc<LanguageServer>,
 1945        settings: &LanguageSettings,
 1946        cx: &mut AsyncApp,
 1947    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 1948        let logger = zlog::scoped!("lsp_format");
 1949        zlog::info!(logger => "Formatting via LSP");
 1950
 1951        let uri = file_path_to_lsp_url(abs_path)?;
 1952        let text_document = lsp::TextDocumentIdentifier::new(uri);
 1953        let capabilities = &language_server.capabilities();
 1954
 1955        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 1956        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 1957
 1958        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 1959            let _timer = zlog::time!(logger => "format-full");
 1960            language_server
 1961                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 1962                    text_document,
 1963                    options: lsp_command::lsp_formatting_options(settings),
 1964                    work_done_progress_params: Default::default(),
 1965                })
 1966                .await
 1967                .into_response()?
 1968        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 1969            let _timer = zlog::time!(logger => "format-range");
 1970            let buffer_start = lsp::Position::new(0, 0);
 1971            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 1972            language_server
 1973                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 1974                    text_document: text_document.clone(),
 1975                    range: lsp::Range::new(buffer_start, buffer_end),
 1976                    options: lsp_command::lsp_formatting_options(settings),
 1977                    work_done_progress_params: Default::default(),
 1978                })
 1979                .await
 1980                .into_response()?
 1981        } else {
 1982            None
 1983        };
 1984
 1985        if let Some(lsp_edits) = lsp_edits {
 1986            this.update(cx, |this, cx| {
 1987                this.as_local_mut().unwrap().edits_from_lsp(
 1988                    buffer,
 1989                    lsp_edits,
 1990                    language_server.server_id(),
 1991                    None,
 1992                    cx,
 1993                )
 1994            })?
 1995            .await
 1996        } else {
 1997            Ok(Vec::with_capacity(0))
 1998        }
 1999    }
 2000
 2001    async fn format_via_external_command(
 2002        buffer: &FormattableBuffer,
 2003        command: &str,
 2004        arguments: Option<&[String]>,
 2005        cx: &mut AsyncApp,
 2006    ) -> Result<Option<Diff>> {
 2007        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2008            let file = File::from_dyn(buffer.file())?;
 2009            let worktree = file.worktree.read(cx);
 2010            let mut worktree_path = worktree.abs_path().to_path_buf();
 2011            if worktree.root_entry()?.is_file() {
 2012                worktree_path.pop();
 2013            }
 2014            Some(worktree_path)
 2015        })?;
 2016
 2017        let mut child = util::command::new_smol_command(command);
 2018
 2019        if let Some(buffer_env) = buffer.env.as_ref() {
 2020            child.envs(buffer_env);
 2021        }
 2022
 2023        if let Some(working_dir_path) = working_dir_path {
 2024            child.current_dir(working_dir_path);
 2025        }
 2026
 2027        if let Some(arguments) = arguments {
 2028            child.args(arguments.iter().map(|arg| {
 2029                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2030                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2031                } else {
 2032                    arg.replace("{buffer_path}", "Untitled")
 2033                }
 2034            }));
 2035        }
 2036
 2037        let mut child = child
 2038            .stdin(smol::process::Stdio::piped())
 2039            .stdout(smol::process::Stdio::piped())
 2040            .stderr(smol::process::Stdio::piped())
 2041            .spawn()?;
 2042
 2043        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2044        let text = buffer
 2045            .handle
 2046            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2047        for chunk in text.chunks() {
 2048            stdin.write_all(chunk.as_bytes()).await?;
 2049        }
 2050        stdin.flush().await?;
 2051
 2052        let output = child.output().await?;
 2053        anyhow::ensure!(
 2054            output.status.success(),
 2055            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2056            output.status.code(),
 2057            String::from_utf8_lossy(&output.stdout),
 2058            String::from_utf8_lossy(&output.stderr),
 2059        );
 2060
 2061        let stdout = String::from_utf8(output.stdout)?;
 2062        Ok(Some(
 2063            buffer
 2064                .handle
 2065                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2066                .await,
 2067        ))
 2068    }
 2069
 2070    async fn try_resolve_code_action(
 2071        lang_server: &LanguageServer,
 2072        action: &mut CodeAction,
 2073    ) -> anyhow::Result<()> {
 2074        match &mut action.lsp_action {
 2075            LspAction::Action(lsp_action) => {
 2076                if !action.resolved
 2077                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2078                    && lsp_action.data.is_some()
 2079                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2080                {
 2081                    *lsp_action = Box::new(
 2082                        lang_server
 2083                            .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2084                            .await
 2085                            .into_response()?,
 2086                    );
 2087                }
 2088            }
 2089            LspAction::CodeLens(lens) => {
 2090                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2091                    *lens = lang_server
 2092                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2093                        .await
 2094                        .into_response()?;
 2095                }
 2096            }
 2097            LspAction::Command(_) => {}
 2098        }
 2099
 2100        action.resolved = true;
 2101        anyhow::Ok(())
 2102    }
 2103
 2104    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2105        let buffer = buffer_handle.read(cx);
 2106
 2107        let file = buffer.file().cloned();
 2108
 2109        let Some(file) = File::from_dyn(file.as_ref()) else {
 2110            return;
 2111        };
 2112        if !file.is_local() {
 2113            return;
 2114        }
 2115        let path = ProjectPath::from_file(file, cx);
 2116        let worktree_id = file.worktree_id(cx);
 2117        let language = buffer.language().cloned();
 2118
 2119        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2120            for (server_id, diagnostics) in
 2121                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2122            {
 2123                self.update_buffer_diagnostics(
 2124                    buffer_handle,
 2125                    server_id,
 2126                    None,
 2127                    None,
 2128                    diagnostics,
 2129                    Vec::new(),
 2130                    cx,
 2131                )
 2132                .log_err();
 2133            }
 2134        }
 2135        let Some(language) = language else {
 2136            return;
 2137        };
 2138        let Some(snapshot) = self
 2139            .worktree_store
 2140            .read(cx)
 2141            .worktree_for_id(worktree_id, cx)
 2142            .map(|worktree| worktree.read(cx).snapshot())
 2143        else {
 2144            return;
 2145        };
 2146        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2147
 2148        for server_id in
 2149            self.lsp_tree
 2150                .get(path, language.name(), language.manifest(), &delegate, cx)
 2151        {
 2152            let server = self
 2153                .language_servers
 2154                .get(&server_id)
 2155                .and_then(|server_state| {
 2156                    if let LanguageServerState::Running { server, .. } = server_state {
 2157                        Some(server.clone())
 2158                    } else {
 2159                        None
 2160                    }
 2161                });
 2162            let server = match server {
 2163                Some(server) => server,
 2164                None => continue,
 2165            };
 2166
 2167            buffer_handle.update(cx, |buffer, cx| {
 2168                buffer.set_completion_triggers(
 2169                    server.server_id(),
 2170                    server
 2171                        .capabilities()
 2172                        .completion_provider
 2173                        .as_ref()
 2174                        .and_then(|provider| {
 2175                            provider
 2176                                .trigger_characters
 2177                                .as_ref()
 2178                                .map(|characters| characters.iter().cloned().collect())
 2179                        })
 2180                        .unwrap_or_default(),
 2181                    cx,
 2182                );
 2183            });
 2184        }
 2185    }
 2186
 2187    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2188        buffer.update(cx, |buffer, cx| {
 2189            let Some(language) = buffer.language() else {
 2190                return;
 2191            };
 2192            let path = ProjectPath {
 2193                worktree_id: old_file.worktree_id(cx),
 2194                path: old_file.path.clone(),
 2195            };
 2196            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2197                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2198                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2199            }
 2200        });
 2201    }
 2202
 2203    fn update_buffer_diagnostics(
 2204        &mut self,
 2205        buffer: &Entity<Buffer>,
 2206        server_id: LanguageServerId,
 2207        result_id: Option<String>,
 2208        version: Option<i32>,
 2209        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2210        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2211        cx: &mut Context<LspStore>,
 2212    ) -> Result<()> {
 2213        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2214            Ordering::Equal
 2215                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2216                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2217                .then_with(|| a.severity.cmp(&b.severity))
 2218                .then_with(|| a.message.cmp(&b.message))
 2219        }
 2220
 2221        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2222        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2223        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2224
 2225        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2226            Ordering::Equal
 2227                .then_with(|| a.range.start.cmp(&b.range.start))
 2228                .then_with(|| b.range.end.cmp(&a.range.end))
 2229                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2230        });
 2231
 2232        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2233
 2234        let edits_since_save = std::cell::LazyCell::new(|| {
 2235            let saved_version = buffer.read(cx).saved_version();
 2236            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2237        });
 2238
 2239        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2240
 2241        for (new_diagnostic, entry) in diagnostics {
 2242            let start;
 2243            let end;
 2244            if new_diagnostic && entry.diagnostic.is_disk_based {
 2245                // Some diagnostics are based on files on disk instead of buffers'
 2246                // current contents. Adjust these diagnostics' ranges to reflect
 2247                // any unsaved edits.
 2248                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2249                // and were properly adjusted on reuse.
 2250                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2251                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2252            } else {
 2253                start = entry.range.start;
 2254                end = entry.range.end;
 2255            }
 2256
 2257            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2258                ..snapshot.clip_point_utf16(end, Bias::Right);
 2259
 2260            // Expand empty ranges by one codepoint
 2261            if range.start == range.end {
 2262                // This will be go to the next boundary when being clipped
 2263                range.end.column += 1;
 2264                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2265                if range.start == range.end && range.end.column > 0 {
 2266                    range.start.column -= 1;
 2267                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2268                }
 2269            }
 2270
 2271            sanitized_diagnostics.push(DiagnosticEntry {
 2272                range,
 2273                diagnostic: entry.diagnostic,
 2274            });
 2275        }
 2276        drop(edits_since_save);
 2277
 2278        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2279        buffer.update(cx, |buffer, cx| {
 2280            if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2281                self.buffer_pull_diagnostics_result_ids
 2282                    .entry(server_id)
 2283                    .or_default()
 2284                    .insert(abs_path, result_id);
 2285            }
 2286
 2287            buffer.update_diagnostics(server_id, set, cx)
 2288        });
 2289
 2290        Ok(())
 2291    }
 2292
 2293    fn register_language_server_for_invisible_worktree(
 2294        &mut self,
 2295        worktree: &Entity<Worktree>,
 2296        language_server_id: LanguageServerId,
 2297        cx: &mut App,
 2298    ) {
 2299        let worktree = worktree.read(cx);
 2300        let worktree_id = worktree.id();
 2301        debug_assert!(!worktree.is_visible());
 2302        let Some(mut origin_seed) = self
 2303            .language_server_ids
 2304            .iter()
 2305            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2306        else {
 2307            return;
 2308        };
 2309        origin_seed.worktree_id = worktree_id;
 2310        self.language_server_ids
 2311            .entry(origin_seed)
 2312            .or_insert_with(|| UnifiedLanguageServer {
 2313                id: language_server_id,
 2314                project_roots: Default::default(),
 2315            });
 2316    }
 2317
 2318    fn register_buffer_with_language_servers(
 2319        &mut self,
 2320        buffer_handle: &Entity<Buffer>,
 2321        only_register_servers: HashSet<LanguageServerSelector>,
 2322        cx: &mut Context<LspStore>,
 2323    ) {
 2324        let buffer = buffer_handle.read(cx);
 2325        let buffer_id = buffer.remote_id();
 2326
 2327        let Some(file) = File::from_dyn(buffer.file()) else {
 2328            return;
 2329        };
 2330        if !file.is_local() {
 2331            return;
 2332        }
 2333
 2334        let abs_path = file.abs_path(cx);
 2335        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2336            return;
 2337        };
 2338        let initial_snapshot = buffer.text_snapshot();
 2339        let worktree_id = file.worktree_id(cx);
 2340
 2341        let Some(language) = buffer.language().cloned() else {
 2342            return;
 2343        };
 2344        let path: Arc<Path> = file
 2345            .path()
 2346            .parent()
 2347            .map(Arc::from)
 2348            .unwrap_or_else(|| file.path().clone());
 2349        let Some(worktree) = self
 2350            .worktree_store
 2351            .read(cx)
 2352            .worktree_for_id(worktree_id, cx)
 2353        else {
 2354            return;
 2355        };
 2356        let language_name = language.name();
 2357        let (reused, delegate, servers) = self
 2358            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2359            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2360            .unwrap_or_else(|| {
 2361                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2362                let delegate: Arc<dyn ManifestDelegate> =
 2363                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2364
 2365                let servers = self
 2366                    .lsp_tree
 2367                    .walk(
 2368                        ProjectPath { worktree_id, path },
 2369                        language.name(),
 2370                        language.manifest(),
 2371                        &delegate,
 2372                        cx,
 2373                    )
 2374                    .collect::<Vec<_>>();
 2375                (false, lsp_delegate, servers)
 2376            });
 2377        let servers_and_adapters = servers
 2378            .into_iter()
 2379            .filter_map(|server_node| {
 2380                if reused && server_node.server_id().is_none() {
 2381                    return None;
 2382                }
 2383                if !only_register_servers.is_empty() {
 2384                    if let Some(server_id) = server_node.server_id()
 2385                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2386                    {
 2387                        return None;
 2388                    }
 2389                    if let Some(name) = server_node.name()
 2390                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2391                    {
 2392                        return None;
 2393                    }
 2394                }
 2395
 2396                let server_id = server_node.server_id_or_init(|disposition| {
 2397                    let path = &disposition.path;
 2398
 2399                    {
 2400                        let uri =
 2401                            Url::from_file_path(worktree.read(cx).abs_path().join(&path.path));
 2402
 2403                        let server_id = self.get_or_insert_language_server(
 2404                            &worktree,
 2405                            delegate.clone(),
 2406                            disposition,
 2407                            &language_name,
 2408                            cx,
 2409                        );
 2410
 2411                        if let Some(state) = self.language_servers.get(&server_id)
 2412                            && let Ok(uri) = uri
 2413                        {
 2414                            state.add_workspace_folder(uri);
 2415                        };
 2416                        server_id
 2417                    }
 2418                })?;
 2419                let server_state = self.language_servers.get(&server_id)?;
 2420                if let LanguageServerState::Running {
 2421                    server, adapter, ..
 2422                } = server_state
 2423                {
 2424                    Some((server.clone(), adapter.clone()))
 2425                } else {
 2426                    None
 2427                }
 2428            })
 2429            .collect::<Vec<_>>();
 2430        for (server, adapter) in servers_and_adapters {
 2431            buffer_handle.update(cx, |buffer, cx| {
 2432                buffer.set_completion_triggers(
 2433                    server.server_id(),
 2434                    server
 2435                        .capabilities()
 2436                        .completion_provider
 2437                        .as_ref()
 2438                        .and_then(|provider| {
 2439                            provider
 2440                                .trigger_characters
 2441                                .as_ref()
 2442                                .map(|characters| characters.iter().cloned().collect())
 2443                        })
 2444                        .unwrap_or_default(),
 2445                    cx,
 2446                );
 2447            });
 2448
 2449            let snapshot = LspBufferSnapshot {
 2450                version: 0,
 2451                snapshot: initial_snapshot.clone(),
 2452            };
 2453
 2454            let mut registered = false;
 2455            self.buffer_snapshots
 2456                .entry(buffer_id)
 2457                .or_default()
 2458                .entry(server.server_id())
 2459                .or_insert_with(|| {
 2460                    registered = true;
 2461                    server.register_buffer(
 2462                        uri.clone(),
 2463                        adapter.language_id(&language.name()),
 2464                        0,
 2465                        initial_snapshot.text(),
 2466                    );
 2467
 2468                    vec![snapshot]
 2469                });
 2470
 2471            self.buffers_opened_in_servers
 2472                .entry(buffer_id)
 2473                .or_default()
 2474                .insert(server.server_id());
 2475            if registered {
 2476                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2477                    language_server_id: server.server_id(),
 2478                    name: None,
 2479                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2480                        proto::RegisteredForBuffer {
 2481                            buffer_abs_path: abs_path.to_string_lossy().to_string(),
 2482                            buffer_id: buffer_id.to_proto(),
 2483                        },
 2484                    ),
 2485                });
 2486            }
 2487        }
 2488    }
 2489
 2490    fn reuse_existing_language_server<'lang_name>(
 2491        &self,
 2492        server_tree: &LanguageServerTree,
 2493        worktree: &Entity<Worktree>,
 2494        language_name: &'lang_name LanguageName,
 2495        cx: &mut App,
 2496    ) -> Option<(
 2497        Arc<LocalLspAdapterDelegate>,
 2498        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2499    )> {
 2500        if worktree.read(cx).is_visible() {
 2501            return None;
 2502        }
 2503
 2504        let worktree_store = self.worktree_store.read(cx);
 2505        let servers = server_tree
 2506            .instances
 2507            .iter()
 2508            .filter(|(worktree_id, _)| {
 2509                worktree_store
 2510                    .worktree_for_id(**worktree_id, cx)
 2511                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2512            })
 2513            .flat_map(|(worktree_id, servers)| {
 2514                servers
 2515                    .roots
 2516                    .iter()
 2517                    .flat_map(|(_, language_servers)| language_servers)
 2518                    .map(move |(_, (server_node, server_languages))| {
 2519                        (worktree_id, server_node, server_languages)
 2520                    })
 2521                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2522                    .map(|(worktree_id, server_node, _)| {
 2523                        (
 2524                            *worktree_id,
 2525                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2526                        )
 2527                    })
 2528            })
 2529            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2530                acc.entry(worktree_id)
 2531                    .or_insert_with(Vec::new)
 2532                    .push(server_node);
 2533                acc
 2534            })
 2535            .into_values()
 2536            .max_by_key(|servers| servers.len())?;
 2537
 2538        let worktree_id = worktree.read(cx).id();
 2539        let apply = move |tree: &mut LanguageServerTree| {
 2540            for server_node in &servers {
 2541                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2542            }
 2543            servers
 2544        };
 2545
 2546        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2547        Some((delegate, apply))
 2548    }
 2549
 2550    pub(crate) fn unregister_old_buffer_from_language_servers(
 2551        &mut self,
 2552        buffer: &Entity<Buffer>,
 2553        old_file: &File,
 2554        cx: &mut App,
 2555    ) {
 2556        let old_path = match old_file.as_local() {
 2557            Some(local) => local.abs_path(cx),
 2558            None => return,
 2559        };
 2560
 2561        let Ok(file_url) = lsp::Url::from_file_path(old_path.as_path()) else {
 2562            debug_panic!(
 2563                "`{}` is not parseable as an URI",
 2564                old_path.to_string_lossy()
 2565            );
 2566            return;
 2567        };
 2568        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2569    }
 2570
 2571    pub(crate) fn unregister_buffer_from_language_servers(
 2572        &mut self,
 2573        buffer: &Entity<Buffer>,
 2574        file_url: &lsp::Url,
 2575        cx: &mut App,
 2576    ) {
 2577        buffer.update(cx, |buffer, cx| {
 2578            let _ = self.buffer_snapshots.remove(&buffer.remote_id());
 2579
 2580            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2581                language_server.unregister_buffer(file_url.clone());
 2582            }
 2583        });
 2584    }
 2585
 2586    fn buffer_snapshot_for_lsp_version(
 2587        &mut self,
 2588        buffer: &Entity<Buffer>,
 2589        server_id: LanguageServerId,
 2590        version: Option<i32>,
 2591        cx: &App,
 2592    ) -> Result<TextBufferSnapshot> {
 2593        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2594
 2595        if let Some(version) = version {
 2596            let buffer_id = buffer.read(cx).remote_id();
 2597            let snapshots = if let Some(snapshots) = self
 2598                .buffer_snapshots
 2599                .get_mut(&buffer_id)
 2600                .and_then(|m| m.get_mut(&server_id))
 2601            {
 2602                snapshots
 2603            } else if version == 0 {
 2604                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2605                // We detect this case and treat it as if the version was `None`.
 2606                return Ok(buffer.read(cx).text_snapshot());
 2607            } else {
 2608                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2609            };
 2610
 2611            let found_snapshot = snapshots
 2612                    .binary_search_by_key(&version, |e| e.version)
 2613                    .map(|ix| snapshots[ix].snapshot.clone())
 2614                    .map_err(|_| {
 2615                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2616                    })?;
 2617
 2618            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2619            Ok(found_snapshot)
 2620        } else {
 2621            Ok((buffer.read(cx)).text_snapshot())
 2622        }
 2623    }
 2624
 2625    async fn get_server_code_actions_from_action_kinds(
 2626        lsp_store: &WeakEntity<LspStore>,
 2627        language_server_id: LanguageServerId,
 2628        code_action_kinds: Vec<lsp::CodeActionKind>,
 2629        buffer: &Entity<Buffer>,
 2630        cx: &mut AsyncApp,
 2631    ) -> Result<Vec<CodeAction>> {
 2632        let actions = lsp_store
 2633            .update(cx, move |this, cx| {
 2634                let request = GetCodeActions {
 2635                    range: text::Anchor::MIN..text::Anchor::MAX,
 2636                    kinds: Some(code_action_kinds),
 2637                };
 2638                let server = LanguageServerToQuery::Other(language_server_id);
 2639                this.request_lsp(buffer.clone(), server, request, cx)
 2640            })?
 2641            .await?;
 2642        Ok(actions)
 2643    }
 2644
 2645    pub async fn execute_code_actions_on_server(
 2646        lsp_store: &WeakEntity<LspStore>,
 2647        language_server: &Arc<LanguageServer>,
 2648
 2649        actions: Vec<CodeAction>,
 2650        push_to_history: bool,
 2651        project_transaction: &mut ProjectTransaction,
 2652        cx: &mut AsyncApp,
 2653    ) -> anyhow::Result<()> {
 2654        for mut action in actions {
 2655            Self::try_resolve_code_action(language_server, &mut action)
 2656                .await
 2657                .context("resolving a formatting code action")?;
 2658
 2659            if let Some(edit) = action.lsp_action.edit() {
 2660                if edit.changes.is_none() && edit.document_changes.is_none() {
 2661                    continue;
 2662                }
 2663
 2664                let new = Self::deserialize_workspace_edit(
 2665                    lsp_store.upgrade().context("project dropped")?,
 2666                    edit.clone(),
 2667                    push_to_history,
 2668                    language_server.clone(),
 2669                    cx,
 2670                )
 2671                .await?;
 2672                project_transaction.0.extend(new.0);
 2673            }
 2674
 2675            if let Some(command) = action.lsp_action.command() {
 2676                let server_capabilities = language_server.capabilities();
 2677                let available_commands = server_capabilities
 2678                    .execute_command_provider
 2679                    .as_ref()
 2680                    .map(|options| options.commands.as_slice())
 2681                    .unwrap_or_default();
 2682                if available_commands.contains(&command.command) {
 2683                    lsp_store.update(cx, |lsp_store, _| {
 2684                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2685                            mode.last_workspace_edits_by_language_server
 2686                                .remove(&language_server.server_id());
 2687                        }
 2688                    })?;
 2689
 2690                    language_server
 2691                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2692                            command: command.command.clone(),
 2693                            arguments: command.arguments.clone().unwrap_or_default(),
 2694                            ..Default::default()
 2695                        })
 2696                        .await
 2697                        .into_response()
 2698                        .context("execute command")?;
 2699
 2700                    lsp_store.update(cx, |this, _| {
 2701                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2702                            project_transaction.0.extend(
 2703                                mode.last_workspace_edits_by_language_server
 2704                                    .remove(&language_server.server_id())
 2705                                    .unwrap_or_default()
 2706                                    .0,
 2707                            )
 2708                        }
 2709                    })?;
 2710                } else {
 2711                    log::warn!(
 2712                        "Cannot execute a command {} not listed in the language server capabilities",
 2713                        command.command
 2714                    )
 2715                }
 2716            }
 2717        }
 2718        Ok(())
 2719    }
 2720
 2721    pub async fn deserialize_text_edits(
 2722        this: Entity<LspStore>,
 2723        buffer_to_edit: Entity<Buffer>,
 2724        edits: Vec<lsp::TextEdit>,
 2725        push_to_history: bool,
 2726        _: Arc<CachedLspAdapter>,
 2727        language_server: Arc<LanguageServer>,
 2728        cx: &mut AsyncApp,
 2729    ) -> Result<Option<Transaction>> {
 2730        let edits = this
 2731            .update(cx, |this, cx| {
 2732                this.as_local_mut().unwrap().edits_from_lsp(
 2733                    &buffer_to_edit,
 2734                    edits,
 2735                    language_server.server_id(),
 2736                    None,
 2737                    cx,
 2738                )
 2739            })?
 2740            .await?;
 2741
 2742        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2743            buffer.finalize_last_transaction();
 2744            buffer.start_transaction();
 2745            for (range, text) in edits {
 2746                buffer.edit([(range, text)], None, cx);
 2747            }
 2748
 2749            if buffer.end_transaction(cx).is_some() {
 2750                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2751                if !push_to_history {
 2752                    buffer.forget_transaction(transaction.id);
 2753                }
 2754                Some(transaction)
 2755            } else {
 2756                None
 2757            }
 2758        })?;
 2759
 2760        Ok(transaction)
 2761    }
 2762
 2763    #[allow(clippy::type_complexity)]
 2764    pub(crate) fn edits_from_lsp(
 2765        &mut self,
 2766        buffer: &Entity<Buffer>,
 2767        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2768        server_id: LanguageServerId,
 2769        version: Option<i32>,
 2770        cx: &mut Context<LspStore>,
 2771    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 2772        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 2773        cx.background_spawn(async move {
 2774            let snapshot = snapshot?;
 2775            let mut lsp_edits = lsp_edits
 2776                .into_iter()
 2777                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 2778                .collect::<Vec<_>>();
 2779
 2780            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 2781
 2782            let mut lsp_edits = lsp_edits.into_iter().peekable();
 2783            let mut edits = Vec::new();
 2784            while let Some((range, mut new_text)) = lsp_edits.next() {
 2785                // Clip invalid ranges provided by the language server.
 2786                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 2787                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 2788
 2789                // Combine any LSP edits that are adjacent.
 2790                //
 2791                // Also, combine LSP edits that are separated from each other by only
 2792                // a newline. This is important because for some code actions,
 2793                // Rust-analyzer rewrites the entire buffer via a series of edits that
 2794                // are separated by unchanged newline characters.
 2795                //
 2796                // In order for the diffing logic below to work properly, any edits that
 2797                // cancel each other out must be combined into one.
 2798                while let Some((next_range, next_text)) = lsp_edits.peek() {
 2799                    if next_range.start.0 > range.end {
 2800                        if next_range.start.0.row > range.end.row + 1
 2801                            || next_range.start.0.column > 0
 2802                            || snapshot.clip_point_utf16(
 2803                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 2804                                Bias::Left,
 2805                            ) > range.end
 2806                        {
 2807                            break;
 2808                        }
 2809                        new_text.push('\n');
 2810                    }
 2811                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 2812                    new_text.push_str(next_text);
 2813                    lsp_edits.next();
 2814                }
 2815
 2816                // For multiline edits, perform a diff of the old and new text so that
 2817                // we can identify the changes more precisely, preserving the locations
 2818                // of any anchors positioned in the unchanged regions.
 2819                if range.end.row > range.start.row {
 2820                    let offset = range.start.to_offset(&snapshot);
 2821                    let old_text = snapshot.text_for_range(range).collect::<String>();
 2822                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 2823                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 2824                        (
 2825                            snapshot.anchor_after(offset + range.start)
 2826                                ..snapshot.anchor_before(offset + range.end),
 2827                            replacement,
 2828                        )
 2829                    }));
 2830                } else if range.end == range.start {
 2831                    let anchor = snapshot.anchor_after(range.start);
 2832                    edits.push((anchor..anchor, new_text.into()));
 2833                } else {
 2834                    let edit_start = snapshot.anchor_after(range.start);
 2835                    let edit_end = snapshot.anchor_before(range.end);
 2836                    edits.push((edit_start..edit_end, new_text.into()));
 2837                }
 2838            }
 2839
 2840            Ok(edits)
 2841        })
 2842    }
 2843
 2844    pub(crate) async fn deserialize_workspace_edit(
 2845        this: Entity<LspStore>,
 2846        edit: lsp::WorkspaceEdit,
 2847        push_to_history: bool,
 2848        language_server: Arc<LanguageServer>,
 2849        cx: &mut AsyncApp,
 2850    ) -> Result<ProjectTransaction> {
 2851        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 2852
 2853        let mut operations = Vec::new();
 2854        if let Some(document_changes) = edit.document_changes {
 2855            match document_changes {
 2856                lsp::DocumentChanges::Edits(edits) => {
 2857                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 2858                }
 2859                lsp::DocumentChanges::Operations(ops) => operations = ops,
 2860            }
 2861        } else if let Some(changes) = edit.changes {
 2862            operations.extend(changes.into_iter().map(|(uri, edits)| {
 2863                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 2864                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 2865                        uri,
 2866                        version: None,
 2867                    },
 2868                    edits: edits.into_iter().map(Edit::Plain).collect(),
 2869                })
 2870            }));
 2871        }
 2872
 2873        let mut project_transaction = ProjectTransaction::default();
 2874        for operation in operations {
 2875            match operation {
 2876                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 2877                    let abs_path = op
 2878                        .uri
 2879                        .to_file_path()
 2880                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2881
 2882                    if let Some(parent_path) = abs_path.parent() {
 2883                        fs.create_dir(parent_path).await?;
 2884                    }
 2885                    if abs_path.ends_with("/") {
 2886                        fs.create_dir(&abs_path).await?;
 2887                    } else {
 2888                        fs.create_file(
 2889                            &abs_path,
 2890                            op.options
 2891                                .map(|options| fs::CreateOptions {
 2892                                    overwrite: options.overwrite.unwrap_or(false),
 2893                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 2894                                })
 2895                                .unwrap_or_default(),
 2896                        )
 2897                        .await?;
 2898                    }
 2899                }
 2900
 2901                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 2902                    let source_abs_path = op
 2903                        .old_uri
 2904                        .to_file_path()
 2905                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2906                    let target_abs_path = op
 2907                        .new_uri
 2908                        .to_file_path()
 2909                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2910                    fs.rename(
 2911                        &source_abs_path,
 2912                        &target_abs_path,
 2913                        op.options
 2914                            .map(|options| fs::RenameOptions {
 2915                                overwrite: options.overwrite.unwrap_or(false),
 2916                                ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 2917                            })
 2918                            .unwrap_or_default(),
 2919                    )
 2920                    .await?;
 2921                }
 2922
 2923                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 2924                    let abs_path = op
 2925                        .uri
 2926                        .to_file_path()
 2927                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2928                    let options = op
 2929                        .options
 2930                        .map(|options| fs::RemoveOptions {
 2931                            recursive: options.recursive.unwrap_or(false),
 2932                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 2933                        })
 2934                        .unwrap_or_default();
 2935                    if abs_path.ends_with("/") {
 2936                        fs.remove_dir(&abs_path, options).await?;
 2937                    } else {
 2938                        fs.remove_file(&abs_path, options).await?;
 2939                    }
 2940                }
 2941
 2942                lsp::DocumentChangeOperation::Edit(op) => {
 2943                    let buffer_to_edit = this
 2944                        .update(cx, |this, cx| {
 2945                            this.open_local_buffer_via_lsp(
 2946                                op.text_document.uri.clone(),
 2947                                language_server.server_id(),
 2948                                cx,
 2949                            )
 2950                        })?
 2951                        .await?;
 2952
 2953                    let edits = this
 2954                        .update(cx, |this, cx| {
 2955                            let path = buffer_to_edit.read(cx).project_path(cx);
 2956                            let active_entry = this.active_entry;
 2957                            let is_active_entry = path.is_some_and(|project_path| {
 2958                                this.worktree_store
 2959                                    .read(cx)
 2960                                    .entry_for_path(&project_path, cx)
 2961                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 2962                            });
 2963                            let local = this.as_local_mut().unwrap();
 2964
 2965                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 2966                            for edit in op.edits {
 2967                                match edit {
 2968                                    Edit::Plain(edit) => {
 2969                                        if !edits.contains(&edit) {
 2970                                            edits.push(edit)
 2971                                        }
 2972                                    }
 2973                                    Edit::Annotated(edit) => {
 2974                                        if !edits.contains(&edit.text_edit) {
 2975                                            edits.push(edit.text_edit)
 2976                                        }
 2977                                    }
 2978                                    Edit::Snippet(edit) => {
 2979                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 2980                                        else {
 2981                                            continue;
 2982                                        };
 2983
 2984                                        if is_active_entry {
 2985                                            snippet_edits.push((edit.range, snippet));
 2986                                        } else {
 2987                                            // Since this buffer is not focused, apply a normal edit.
 2988                                            let new_edit = TextEdit {
 2989                                                range: edit.range,
 2990                                                new_text: snippet.text,
 2991                                            };
 2992                                            if !edits.contains(&new_edit) {
 2993                                                edits.push(new_edit);
 2994                                            }
 2995                                        }
 2996                                    }
 2997                                }
 2998                            }
 2999                            if !snippet_edits.is_empty() {
 3000                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3001                                let version = if let Some(buffer_version) = op.text_document.version
 3002                                {
 3003                                    local
 3004                                        .buffer_snapshot_for_lsp_version(
 3005                                            &buffer_to_edit,
 3006                                            language_server.server_id(),
 3007                                            Some(buffer_version),
 3008                                            cx,
 3009                                        )
 3010                                        .ok()
 3011                                        .map(|snapshot| snapshot.version)
 3012                                } else {
 3013                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3014                                };
 3015
 3016                                let most_recent_edit = version.and_then(|version| {
 3017                                    version.iter().max_by_key(|timestamp| timestamp.value)
 3018                                });
 3019                                // Check if the edit that triggered that edit has been made by this participant.
 3020
 3021                                if let Some(most_recent_edit) = most_recent_edit {
 3022                                    cx.emit(LspStoreEvent::SnippetEdit {
 3023                                        buffer_id,
 3024                                        edits: snippet_edits,
 3025                                        most_recent_edit,
 3026                                    });
 3027                                }
 3028                            }
 3029
 3030                            local.edits_from_lsp(
 3031                                &buffer_to_edit,
 3032                                edits,
 3033                                language_server.server_id(),
 3034                                op.text_document.version,
 3035                                cx,
 3036                            )
 3037                        })?
 3038                        .await?;
 3039
 3040                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3041                        buffer.finalize_last_transaction();
 3042                        buffer.start_transaction();
 3043                        for (range, text) in edits {
 3044                            buffer.edit([(range, text)], None, cx);
 3045                        }
 3046
 3047                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3048                            if push_to_history {
 3049                                buffer.finalize_last_transaction();
 3050                                buffer.get_transaction(transaction_id).cloned()
 3051                            } else {
 3052                                buffer.forget_transaction(transaction_id)
 3053                            }
 3054                        })
 3055                    })?;
 3056                    if let Some(transaction) = transaction {
 3057                        project_transaction.0.insert(buffer_to_edit, transaction);
 3058                    }
 3059                }
 3060            }
 3061        }
 3062
 3063        Ok(project_transaction)
 3064    }
 3065
 3066    async fn on_lsp_workspace_edit(
 3067        this: WeakEntity<LspStore>,
 3068        params: lsp::ApplyWorkspaceEditParams,
 3069        server_id: LanguageServerId,
 3070        cx: &mut AsyncApp,
 3071    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3072        let this = this.upgrade().context("project project closed")?;
 3073        let language_server = this
 3074            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3075            .context("language server not found")?;
 3076        let transaction = Self::deserialize_workspace_edit(
 3077            this.clone(),
 3078            params.edit,
 3079            true,
 3080            language_server.clone(),
 3081            cx,
 3082        )
 3083        .await
 3084        .log_err();
 3085        this.update(cx, |this, _| {
 3086            if let Some(transaction) = transaction {
 3087                this.as_local_mut()
 3088                    .unwrap()
 3089                    .last_workspace_edits_by_language_server
 3090                    .insert(server_id, transaction);
 3091            }
 3092        })?;
 3093        Ok(lsp::ApplyWorkspaceEditResponse {
 3094            applied: true,
 3095            failed_change: None,
 3096            failure_reason: None,
 3097        })
 3098    }
 3099
 3100    fn remove_worktree(
 3101        &mut self,
 3102        id_to_remove: WorktreeId,
 3103        cx: &mut Context<LspStore>,
 3104    ) -> Vec<LanguageServerId> {
 3105        self.diagnostics.remove(&id_to_remove);
 3106        self.prettier_store.update(cx, |prettier_store, cx| {
 3107            prettier_store.remove_worktree(id_to_remove, cx);
 3108        });
 3109
 3110        let mut servers_to_remove = BTreeSet::default();
 3111        let mut servers_to_preserve = HashSet::default();
 3112        for (seed, state) in &self.language_server_ids {
 3113            if seed.worktree_id == id_to_remove {
 3114                servers_to_remove.insert(state.id);
 3115            } else {
 3116                servers_to_preserve.insert(state.id);
 3117            }
 3118        }
 3119        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3120        self.language_server_ids
 3121            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3122        for server_id_to_remove in &servers_to_remove {
 3123            self.language_server_watched_paths
 3124                .remove(server_id_to_remove);
 3125            self.language_server_paths_watched_for_rename
 3126                .remove(server_id_to_remove);
 3127            self.last_workspace_edits_by_language_server
 3128                .remove(server_id_to_remove);
 3129            self.language_servers.remove(server_id_to_remove);
 3130            self.buffer_pull_diagnostics_result_ids
 3131                .remove(server_id_to_remove);
 3132            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3133                buffer_servers.remove(server_id_to_remove);
 3134            }
 3135            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3136        }
 3137        servers_to_remove.into_iter().collect()
 3138    }
 3139
 3140    fn rebuild_watched_paths_inner<'a>(
 3141        &'a self,
 3142        language_server_id: LanguageServerId,
 3143        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3144        cx: &mut Context<LspStore>,
 3145    ) -> LanguageServerWatchedPathsBuilder {
 3146        let worktrees = self
 3147            .worktree_store
 3148            .read(cx)
 3149            .worktrees()
 3150            .filter_map(|worktree| {
 3151                self.language_servers_for_worktree(worktree.read(cx).id())
 3152                    .find(|server| server.server_id() == language_server_id)
 3153                    .map(|_| worktree)
 3154            })
 3155            .collect::<Vec<_>>();
 3156
 3157        let mut worktree_globs = HashMap::default();
 3158        let mut abs_globs = HashMap::default();
 3159        log::trace!(
 3160            "Processing new watcher paths for language server with id {}",
 3161            language_server_id
 3162        );
 3163
 3164        for watcher in watchers {
 3165            if let Some((worktree, literal_prefix, pattern)) =
 3166                self.worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3167            {
 3168                worktree.update(cx, |worktree, _| {
 3169                    if let Some((tree, glob)) =
 3170                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3171                    {
 3172                        tree.add_path_prefix_to_scan(literal_prefix.into());
 3173                        worktree_globs
 3174                            .entry(tree.id())
 3175                            .or_insert_with(GlobSetBuilder::new)
 3176                            .add(glob);
 3177                    }
 3178                });
 3179            } else {
 3180                let (path, pattern) = match &watcher.glob_pattern {
 3181                    lsp::GlobPattern::String(s) => {
 3182                        let watcher_path = SanitizedPath::from(s);
 3183                        let path = glob_literal_prefix(watcher_path.as_path());
 3184                        let pattern = watcher_path
 3185                            .as_path()
 3186                            .strip_prefix(&path)
 3187                            .map(|p| p.to_string_lossy().to_string())
 3188                            .unwrap_or_else(|e| {
 3189                                debug_panic!(
 3190                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3191                                    s,
 3192                                    path.display(),
 3193                                    e
 3194                                );
 3195                                watcher_path.as_path().to_string_lossy().to_string()
 3196                            });
 3197                        (path, pattern)
 3198                    }
 3199                    lsp::GlobPattern::Relative(rp) => {
 3200                        let Ok(mut base_uri) = match &rp.base_uri {
 3201                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3202                            lsp::OneOf::Right(base_uri) => base_uri,
 3203                        }
 3204                        .to_file_path() else {
 3205                            continue;
 3206                        };
 3207
 3208                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3209                        let pattern = Path::new(&rp.pattern)
 3210                            .strip_prefix(&path)
 3211                            .map(|p| p.to_string_lossy().to_string())
 3212                            .unwrap_or_else(|e| {
 3213                                debug_panic!(
 3214                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3215                                    rp.pattern,
 3216                                    path.display(),
 3217                                    e
 3218                                );
 3219                                rp.pattern.clone()
 3220                            });
 3221                        base_uri.push(path);
 3222                        (base_uri, pattern)
 3223                    }
 3224                };
 3225
 3226                if let Some(glob) = Glob::new(&pattern).log_err() {
 3227                    if !path
 3228                        .components()
 3229                        .any(|c| matches!(c, path::Component::Normal(_)))
 3230                    {
 3231                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3232                        // rather than adding a new watcher for `/`.
 3233                        for worktree in &worktrees {
 3234                            worktree_globs
 3235                                .entry(worktree.read(cx).id())
 3236                                .or_insert_with(GlobSetBuilder::new)
 3237                                .add(glob.clone());
 3238                        }
 3239                    } else {
 3240                        abs_globs
 3241                            .entry(path.into())
 3242                            .or_insert_with(GlobSetBuilder::new)
 3243                            .add(glob);
 3244                    }
 3245                }
 3246            }
 3247        }
 3248
 3249        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3250        for (worktree_id, builder) in worktree_globs {
 3251            if let Ok(globset) = builder.build() {
 3252                watch_builder.watch_worktree(worktree_id, globset);
 3253            }
 3254        }
 3255        for (abs_path, builder) in abs_globs {
 3256            if let Ok(globset) = builder.build() {
 3257                watch_builder.watch_abs_path(abs_path, globset);
 3258            }
 3259        }
 3260        watch_builder
 3261    }
 3262
 3263    fn worktree_and_path_for_file_watcher(
 3264        &self,
 3265        worktrees: &[Entity<Worktree>],
 3266        watcher: &FileSystemWatcher,
 3267        cx: &App,
 3268    ) -> Option<(Entity<Worktree>, PathBuf, String)> {
 3269        worktrees.iter().find_map(|worktree| {
 3270            let tree = worktree.read(cx);
 3271            let worktree_root_path = tree.abs_path();
 3272            match &watcher.glob_pattern {
 3273                lsp::GlobPattern::String(s) => {
 3274                    let watcher_path = SanitizedPath::from(s);
 3275                    let relative = watcher_path
 3276                        .as_path()
 3277                        .strip_prefix(&worktree_root_path)
 3278                        .ok()?;
 3279                    let literal_prefix = glob_literal_prefix(relative);
 3280                    Some((
 3281                        worktree.clone(),
 3282                        literal_prefix,
 3283                        relative.to_string_lossy().to_string(),
 3284                    ))
 3285                }
 3286                lsp::GlobPattern::Relative(rp) => {
 3287                    let base_uri = match &rp.base_uri {
 3288                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3289                        lsp::OneOf::Right(base_uri) => base_uri,
 3290                    }
 3291                    .to_file_path()
 3292                    .ok()?;
 3293                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3294                    let mut literal_prefix = relative.to_owned();
 3295                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3296                    Some((worktree.clone(), literal_prefix, rp.pattern.clone()))
 3297                }
 3298            }
 3299        })
 3300    }
 3301
 3302    fn rebuild_watched_paths(
 3303        &mut self,
 3304        language_server_id: LanguageServerId,
 3305        cx: &mut Context<LspStore>,
 3306    ) {
 3307        let Some(watchers) = self
 3308            .language_server_watcher_registrations
 3309            .get(&language_server_id)
 3310        else {
 3311            return;
 3312        };
 3313
 3314        let watch_builder =
 3315            self.rebuild_watched_paths_inner(language_server_id, watchers.values().flatten(), cx);
 3316        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3317        self.language_server_watched_paths
 3318            .insert(language_server_id, watcher);
 3319
 3320        cx.notify();
 3321    }
 3322
 3323    fn on_lsp_did_change_watched_files(
 3324        &mut self,
 3325        language_server_id: LanguageServerId,
 3326        registration_id: &str,
 3327        params: DidChangeWatchedFilesRegistrationOptions,
 3328        cx: &mut Context<LspStore>,
 3329    ) {
 3330        let registrations = self
 3331            .language_server_watcher_registrations
 3332            .entry(language_server_id)
 3333            .or_default();
 3334
 3335        registrations.insert(registration_id.to_string(), params.watchers);
 3336
 3337        self.rebuild_watched_paths(language_server_id, cx);
 3338    }
 3339
 3340    fn on_lsp_unregister_did_change_watched_files(
 3341        &mut self,
 3342        language_server_id: LanguageServerId,
 3343        registration_id: &str,
 3344        cx: &mut Context<LspStore>,
 3345    ) {
 3346        let registrations = self
 3347            .language_server_watcher_registrations
 3348            .entry(language_server_id)
 3349            .or_default();
 3350
 3351        if registrations.remove(registration_id).is_some() {
 3352            log::info!(
 3353                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3354                language_server_id,
 3355                registration_id
 3356            );
 3357        } else {
 3358            log::warn!(
 3359                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3360                language_server_id,
 3361                registration_id
 3362            );
 3363        }
 3364
 3365        self.rebuild_watched_paths(language_server_id, cx);
 3366    }
 3367
 3368    async fn initialization_options_for_adapter(
 3369        adapter: Arc<dyn LspAdapter>,
 3370        fs: &dyn Fs,
 3371        delegate: &Arc<dyn LspAdapterDelegate>,
 3372    ) -> Result<Option<serde_json::Value>> {
 3373        let Some(mut initialization_config) =
 3374            adapter.clone().initialization_options(fs, delegate).await?
 3375        else {
 3376            return Ok(None);
 3377        };
 3378
 3379        for other_adapter in delegate.registered_lsp_adapters() {
 3380            if other_adapter.name() == adapter.name() {
 3381                continue;
 3382            }
 3383            if let Ok(Some(target_config)) = other_adapter
 3384                .clone()
 3385                .additional_initialization_options(adapter.name(), fs, delegate)
 3386                .await
 3387            {
 3388                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3389            }
 3390        }
 3391
 3392        Ok(Some(initialization_config))
 3393    }
 3394
 3395    fn toolchain_store(&self) -> &Entity<LocalToolchainStore> {
 3396        &self.toolchain_store
 3397    }
 3398
 3399    async fn workspace_configuration_for_adapter(
 3400        adapter: Arc<dyn LspAdapter>,
 3401        fs: &dyn Fs,
 3402        delegate: &Arc<dyn LspAdapterDelegate>,
 3403        toolchain: Option<Toolchain>,
 3404        cx: &mut AsyncApp,
 3405    ) -> Result<serde_json::Value> {
 3406        let mut workspace_config = adapter
 3407            .clone()
 3408            .workspace_configuration(fs, delegate, toolchain, cx)
 3409            .await?;
 3410
 3411        for other_adapter in delegate.registered_lsp_adapters() {
 3412            if other_adapter.name() == adapter.name() {
 3413                continue;
 3414            }
 3415            if let Ok(Some(target_config)) = other_adapter
 3416                .clone()
 3417                .additional_workspace_configuration(adapter.name(), fs, delegate, cx)
 3418                .await
 3419            {
 3420                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3421            }
 3422        }
 3423
 3424        Ok(workspace_config)
 3425    }
 3426
 3427    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3428        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3429            Some(server.clone())
 3430        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3431            Some(Arc::clone(server))
 3432        } else {
 3433            None
 3434        }
 3435    }
 3436}
 3437
 3438fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3439    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3440        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3441            language_server_id: server.server_id(),
 3442            name: Some(server.name()),
 3443            message: proto::update_language_server::Variant::MetadataUpdated(
 3444                proto::ServerMetadataUpdated {
 3445                    capabilities: Some(capabilities),
 3446                },
 3447            ),
 3448        });
 3449    }
 3450}
 3451
 3452#[derive(Debug)]
 3453pub struct FormattableBuffer {
 3454    handle: Entity<Buffer>,
 3455    abs_path: Option<PathBuf>,
 3456    env: Option<HashMap<String, String>>,
 3457    ranges: Option<Vec<Range<Anchor>>>,
 3458}
 3459
 3460pub struct RemoteLspStore {
 3461    upstream_client: Option<AnyProtoClient>,
 3462    upstream_project_id: u64,
 3463}
 3464
 3465pub(crate) enum LspStoreMode {
 3466    Local(LocalLspStore),   // ssh host and collab host
 3467    Remote(RemoteLspStore), // collab guest
 3468}
 3469
 3470impl LspStoreMode {
 3471    fn is_local(&self) -> bool {
 3472        matches!(self, LspStoreMode::Local(_))
 3473    }
 3474}
 3475
 3476pub struct LspStore {
 3477    mode: LspStoreMode,
 3478    last_formatting_failure: Option<String>,
 3479    downstream_client: Option<(AnyProtoClient, u64)>,
 3480    nonce: u128,
 3481    buffer_store: Entity<BufferStore>,
 3482    worktree_store: Entity<WorktreeStore>,
 3483    pub languages: Arc<LanguageRegistry>,
 3484    language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3485    active_entry: Option<ProjectEntryId>,
 3486    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3487    _maintain_buffer_languages: Task<()>,
 3488    diagnostic_summaries:
 3489        HashMap<WorktreeId, HashMap<Arc<Path>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3490    pub(super) lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3491    lsp_document_colors: HashMap<BufferId, DocumentColorData>,
 3492    lsp_code_lens: HashMap<BufferId, CodeLensData>,
 3493    running_lsp_requests: HashMap<TypeId, (Global, HashMap<LspRequestId, Task<()>>)>,
 3494}
 3495
 3496#[derive(Debug, Default, Clone)]
 3497pub struct DocumentColors {
 3498    pub colors: HashSet<DocumentColor>,
 3499    pub cache_version: Option<usize>,
 3500}
 3501
 3502type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3503type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3504
 3505#[derive(Debug, Default)]
 3506struct DocumentColorData {
 3507    colors_for_version: Global,
 3508    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3509    cache_version: usize,
 3510    colors_update: Option<(Global, DocumentColorTask)>,
 3511}
 3512
 3513#[derive(Debug, Default)]
 3514struct CodeLensData {
 3515    lens_for_version: Global,
 3516    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3517    update: Option<(Global, CodeLensTask)>,
 3518}
 3519
 3520#[derive(Debug, PartialEq, Eq, Clone, Copy)]
 3521pub enum LspFetchStrategy {
 3522    IgnoreCache,
 3523    UseCache { known_cache_version: Option<usize> },
 3524}
 3525
 3526#[derive(Debug)]
 3527pub enum LspStoreEvent {
 3528    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3529    LanguageServerRemoved(LanguageServerId),
 3530    LanguageServerUpdate {
 3531        language_server_id: LanguageServerId,
 3532        name: Option<LanguageServerName>,
 3533        message: proto::update_language_server::Variant,
 3534    },
 3535    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3536    LanguageServerPrompt(LanguageServerPromptRequest),
 3537    LanguageDetected {
 3538        buffer: Entity<Buffer>,
 3539        new_language: Option<Arc<Language>>,
 3540    },
 3541    Notification(String),
 3542    RefreshInlayHints,
 3543    RefreshCodeLens,
 3544    DiagnosticsUpdated {
 3545        server_id: LanguageServerId,
 3546        paths: Vec<ProjectPath>,
 3547    },
 3548    DiskBasedDiagnosticsStarted {
 3549        language_server_id: LanguageServerId,
 3550    },
 3551    DiskBasedDiagnosticsFinished {
 3552        language_server_id: LanguageServerId,
 3553    },
 3554    SnippetEdit {
 3555        buffer_id: BufferId,
 3556        edits: Vec<(lsp::Range, Snippet)>,
 3557        most_recent_edit: clock::Lamport,
 3558    },
 3559}
 3560
 3561#[derive(Clone, Debug, Serialize)]
 3562pub struct LanguageServerStatus {
 3563    pub name: LanguageServerName,
 3564    pub pending_work: BTreeMap<String, LanguageServerProgress>,
 3565    pub has_pending_diagnostic_updates: bool,
 3566    progress_tokens: HashSet<String>,
 3567}
 3568
 3569#[derive(Clone, Debug)]
 3570struct CoreSymbol {
 3571    pub language_server_name: LanguageServerName,
 3572    pub source_worktree_id: WorktreeId,
 3573    pub source_language_server_id: LanguageServerId,
 3574    pub path: ProjectPath,
 3575    pub name: String,
 3576    pub kind: lsp::SymbolKind,
 3577    pub range: Range<Unclipped<PointUtf16>>,
 3578    pub signature: [u8; 32],
 3579}
 3580
 3581impl LspStore {
 3582    pub fn init(client: &AnyProtoClient) {
 3583        client.add_entity_request_handler(Self::handle_lsp_query);
 3584        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3585        client.add_entity_request_handler(Self::handle_multi_lsp_query);
 3586        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3587        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3588        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3589        client.add_entity_message_handler(Self::handle_start_language_server);
 3590        client.add_entity_message_handler(Self::handle_update_language_server);
 3591        client.add_entity_message_handler(Self::handle_language_server_log);
 3592        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3593        client.add_entity_request_handler(Self::handle_format_buffers);
 3594        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3595        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3596        client.add_entity_request_handler(Self::handle_apply_code_action);
 3597        client.add_entity_request_handler(Self::handle_inlay_hints);
 3598        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3599        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3600        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3601        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3602        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3603        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3604        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3605        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3606        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3607        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3608        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3609        client.add_entity_request_handler(Self::handle_lsp_command::<GetCodeActions>);
 3610        client.add_entity_request_handler(Self::handle_lsp_command::<GetCompletions>);
 3611        client.add_entity_request_handler(Self::handle_lsp_command::<GetHover>);
 3612        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3613        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3614        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3615        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3616        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3617
 3618        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3619        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3620        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3621        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3622        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3623        client.add_entity_request_handler(
 3624            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3625        );
 3626        client.add_entity_request_handler(
 3627            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3628        );
 3629        client.add_entity_request_handler(
 3630            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3631        );
 3632        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentDiagnostics>);
 3633    }
 3634
 3635    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3636        match &self.mode {
 3637            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3638            _ => None,
 3639        }
 3640    }
 3641
 3642    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3643        match &self.mode {
 3644            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3645            _ => None,
 3646        }
 3647    }
 3648
 3649    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3650        match &mut self.mode {
 3651            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3652            _ => None,
 3653        }
 3654    }
 3655
 3656    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3657        match &self.mode {
 3658            LspStoreMode::Remote(RemoteLspStore {
 3659                upstream_client: Some(upstream_client),
 3660                upstream_project_id,
 3661                ..
 3662            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3663
 3664            LspStoreMode::Remote(RemoteLspStore {
 3665                upstream_client: None,
 3666                ..
 3667            }) => None,
 3668            LspStoreMode::Local(_) => None,
 3669        }
 3670    }
 3671
 3672    pub fn new_local(
 3673        buffer_store: Entity<BufferStore>,
 3674        worktree_store: Entity<WorktreeStore>,
 3675        prettier_store: Entity<PrettierStore>,
 3676        toolchain_store: Entity<LocalToolchainStore>,
 3677        environment: Entity<ProjectEnvironment>,
 3678        manifest_tree: Entity<ManifestTree>,
 3679        languages: Arc<LanguageRegistry>,
 3680        http_client: Arc<dyn HttpClient>,
 3681        fs: Arc<dyn Fs>,
 3682        cx: &mut Context<Self>,
 3683    ) -> Self {
 3684        let yarn = YarnPathStore::new(fs.clone(), cx);
 3685        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3686            .detach();
 3687        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3688            .detach();
 3689        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 3690            .detach();
 3691        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 3692            .detach();
 3693        if let Some(extension_events) = extension::ExtensionEvents::try_global(cx).as_ref() {
 3694            cx.subscribe(
 3695                extension_events,
 3696                Self::reload_zed_json_schemas_on_extensions_changed,
 3697            )
 3698            .detach();
 3699        } else {
 3700            log::debug!("No extension events global found. Skipping JSON schema auto-reload setup");
 3701        }
 3702        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 3703            .detach();
 3704        subscribe_to_binary_statuses(&languages, cx).detach();
 3705
 3706        let _maintain_workspace_config = {
 3707            let (sender, receiver) = watch::channel();
 3708            (
 3709                Self::maintain_workspace_config(fs.clone(), receiver, cx),
 3710                sender,
 3711            )
 3712        };
 3713
 3714        Self {
 3715            mode: LspStoreMode::Local(LocalLspStore {
 3716                weak: cx.weak_entity(),
 3717                worktree_store: worktree_store.clone(),
 3718
 3719                supplementary_language_servers: Default::default(),
 3720                languages: languages.clone(),
 3721                language_server_ids: Default::default(),
 3722                language_servers: Default::default(),
 3723                last_workspace_edits_by_language_server: Default::default(),
 3724                language_server_watched_paths: Default::default(),
 3725                language_server_paths_watched_for_rename: Default::default(),
 3726                language_server_watcher_registrations: Default::default(),
 3727                buffers_being_formatted: Default::default(),
 3728                buffer_snapshots: Default::default(),
 3729                prettier_store,
 3730                environment,
 3731                http_client,
 3732                fs,
 3733                yarn,
 3734                next_diagnostic_group_id: Default::default(),
 3735                diagnostics: Default::default(),
 3736                _subscription: cx.on_app_quit(|this, cx| {
 3737                    this.as_local_mut()
 3738                        .unwrap()
 3739                        .shutdown_language_servers_on_quit(cx)
 3740                }),
 3741                lsp_tree: LanguageServerTree::new(
 3742                    manifest_tree,
 3743                    languages.clone(),
 3744                    toolchain_store.clone(),
 3745                ),
 3746                toolchain_store,
 3747                registered_buffers: HashMap::default(),
 3748                buffers_opened_in_servers: HashMap::default(),
 3749                buffer_pull_diagnostics_result_ids: HashMap::default(),
 3750                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 3751                    .manifest_file_names(),
 3752            }),
 3753            last_formatting_failure: None,
 3754            downstream_client: None,
 3755            buffer_store,
 3756            worktree_store,
 3757            languages: languages.clone(),
 3758            language_server_statuses: Default::default(),
 3759            nonce: StdRng::from_entropy().r#gen(),
 3760            diagnostic_summaries: HashMap::default(),
 3761            lsp_server_capabilities: HashMap::default(),
 3762            lsp_document_colors: HashMap::default(),
 3763            lsp_code_lens: HashMap::default(),
 3764            running_lsp_requests: HashMap::default(),
 3765            active_entry: None,
 3766            _maintain_workspace_config,
 3767            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 3768        }
 3769    }
 3770
 3771    fn send_lsp_proto_request<R: LspCommand>(
 3772        &self,
 3773        buffer: Entity<Buffer>,
 3774        client: AnyProtoClient,
 3775        upstream_project_id: u64,
 3776        request: R,
 3777        cx: &mut Context<LspStore>,
 3778    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 3779        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 3780            return Task::ready(Ok(R::Response::default()));
 3781        }
 3782        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 3783        cx.spawn(async move |this, cx| {
 3784            let response = client.request(message).await?;
 3785            let this = this.upgrade().context("project dropped")?;
 3786            request
 3787                .response_from_proto(response, this, buffer, cx.clone())
 3788                .await
 3789        })
 3790    }
 3791
 3792    pub(super) fn new_remote(
 3793        buffer_store: Entity<BufferStore>,
 3794        worktree_store: Entity<WorktreeStore>,
 3795        languages: Arc<LanguageRegistry>,
 3796        upstream_client: AnyProtoClient,
 3797        project_id: u64,
 3798        fs: Arc<dyn Fs>,
 3799        cx: &mut Context<Self>,
 3800    ) -> Self {
 3801        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3802            .detach();
 3803        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3804            .detach();
 3805        subscribe_to_binary_statuses(&languages, cx).detach();
 3806        let _maintain_workspace_config = {
 3807            let (sender, receiver) = watch::channel();
 3808            (Self::maintain_workspace_config(fs, receiver, cx), sender)
 3809        };
 3810        Self {
 3811            mode: LspStoreMode::Remote(RemoteLspStore {
 3812                upstream_client: Some(upstream_client),
 3813                upstream_project_id: project_id,
 3814            }),
 3815            downstream_client: None,
 3816            last_formatting_failure: None,
 3817            buffer_store,
 3818            worktree_store,
 3819            languages: languages.clone(),
 3820            language_server_statuses: Default::default(),
 3821            nonce: StdRng::from_entropy().r#gen(),
 3822            diagnostic_summaries: HashMap::default(),
 3823            lsp_server_capabilities: HashMap::default(),
 3824            lsp_document_colors: HashMap::default(),
 3825            lsp_code_lens: HashMap::default(),
 3826            running_lsp_requests: HashMap::default(),
 3827            active_entry: None,
 3828
 3829            _maintain_workspace_config,
 3830            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 3831        }
 3832    }
 3833
 3834    fn on_buffer_store_event(
 3835        &mut self,
 3836        _: Entity<BufferStore>,
 3837        event: &BufferStoreEvent,
 3838        cx: &mut Context<Self>,
 3839    ) {
 3840        match event {
 3841            BufferStoreEvent::BufferAdded(buffer) => {
 3842                self.on_buffer_added(buffer, cx).log_err();
 3843            }
 3844            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 3845                let buffer_id = buffer.read(cx).remote_id();
 3846                if let Some(local) = self.as_local_mut()
 3847                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 3848                {
 3849                    local.reset_buffer(buffer, old_file, cx);
 3850
 3851                    if local.registered_buffers.contains_key(&buffer_id) {
 3852                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 3853                    }
 3854                }
 3855
 3856                self.detect_language_for_buffer(buffer, cx);
 3857                if let Some(local) = self.as_local_mut() {
 3858                    local.initialize_buffer(buffer, cx);
 3859                    if local.registered_buffers.contains_key(&buffer_id) {
 3860                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 3861                    }
 3862                }
 3863            }
 3864            _ => {}
 3865        }
 3866    }
 3867
 3868    fn on_worktree_store_event(
 3869        &mut self,
 3870        _: Entity<WorktreeStore>,
 3871        event: &WorktreeStoreEvent,
 3872        cx: &mut Context<Self>,
 3873    ) {
 3874        match event {
 3875            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 3876                if !worktree.read(cx).is_local() {
 3877                    return;
 3878                }
 3879                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 3880                    worktree::Event::UpdatedEntries(changes) => {
 3881                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 3882                    }
 3883                    worktree::Event::UpdatedGitRepositories(_)
 3884                    | worktree::Event::DeletedEntry(_) => {}
 3885                })
 3886                .detach()
 3887            }
 3888            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 3889            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 3890                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 3891            }
 3892            WorktreeStoreEvent::WorktreeReleased(..)
 3893            | WorktreeStoreEvent::WorktreeOrderChanged
 3894            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 3895            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 3896            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 3897        }
 3898    }
 3899
 3900    fn on_prettier_store_event(
 3901        &mut self,
 3902        _: Entity<PrettierStore>,
 3903        event: &PrettierStoreEvent,
 3904        cx: &mut Context<Self>,
 3905    ) {
 3906        match event {
 3907            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 3908                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 3909            }
 3910            PrettierStoreEvent::LanguageServerAdded {
 3911                new_server_id,
 3912                name,
 3913                prettier_server,
 3914            } => {
 3915                self.register_supplementary_language_server(
 3916                    *new_server_id,
 3917                    name.clone(),
 3918                    prettier_server.clone(),
 3919                    cx,
 3920                );
 3921            }
 3922        }
 3923    }
 3924
 3925    fn on_toolchain_store_event(
 3926        &mut self,
 3927        _: Entity<LocalToolchainStore>,
 3928        event: &ToolchainStoreEvent,
 3929        _: &mut Context<Self>,
 3930    ) {
 3931        match event {
 3932            ToolchainStoreEvent::ToolchainActivated => self.request_workspace_config_refresh(),
 3933        }
 3934    }
 3935
 3936    fn request_workspace_config_refresh(&mut self) {
 3937        *self._maintain_workspace_config.1.borrow_mut() = ();
 3938    }
 3939
 3940    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 3941        self.as_local().map(|local| local.prettier_store.clone())
 3942    }
 3943
 3944    fn on_buffer_event(
 3945        &mut self,
 3946        buffer: Entity<Buffer>,
 3947        event: &language::BufferEvent,
 3948        cx: &mut Context<Self>,
 3949    ) {
 3950        match event {
 3951            language::BufferEvent::Edited => {
 3952                self.on_buffer_edited(buffer, cx);
 3953            }
 3954
 3955            language::BufferEvent::Saved => {
 3956                self.on_buffer_saved(buffer, cx);
 3957            }
 3958
 3959            _ => {}
 3960        }
 3961    }
 3962
 3963    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 3964        buffer
 3965            .read(cx)
 3966            .set_language_registry(self.languages.clone());
 3967
 3968        cx.subscribe(buffer, |this, buffer, event, cx| {
 3969            this.on_buffer_event(buffer, event, cx);
 3970        })
 3971        .detach();
 3972
 3973        self.detect_language_for_buffer(buffer, cx);
 3974        if let Some(local) = self.as_local_mut() {
 3975            local.initialize_buffer(buffer, cx);
 3976        }
 3977
 3978        Ok(())
 3979    }
 3980
 3981    pub fn reload_zed_json_schemas_on_extensions_changed(
 3982        &mut self,
 3983        _: Entity<extension::ExtensionEvents>,
 3984        evt: &extension::Event,
 3985        cx: &mut Context<Self>,
 3986    ) {
 3987        match evt {
 3988            extension::Event::ExtensionInstalled(_)
 3989            | extension::Event::ExtensionUninstalled(_)
 3990            | extension::Event::ConfigureExtensionRequested(_) => return,
 3991            extension::Event::ExtensionsInstalledChanged => {}
 3992        }
 3993        if self.as_local().is_none() {
 3994            return;
 3995        }
 3996        cx.spawn(async move |this, cx| {
 3997            let weak_ref = this.clone();
 3998
 3999            let servers = this
 4000                .update(cx, |this, cx| {
 4001                    let local = this.as_local()?;
 4002
 4003                    let mut servers = Vec::new();
 4004                    for (seed, state) in &local.language_server_ids {
 4005
 4006                            let Some(states) = local.language_servers.get(&state.id) else {
 4007                                continue;
 4008                            };
 4009                            let (json_adapter, json_server) = match states {
 4010                                LanguageServerState::Running {
 4011                                    adapter, server, ..
 4012                                } if adapter.adapter.is_primary_zed_json_schema_adapter() => {
 4013                                    (adapter.adapter.clone(), server.clone())
 4014                                }
 4015                                _ => continue,
 4016                            };
 4017
 4018                            let Some(worktree) = this
 4019                                .worktree_store
 4020                                .read(cx)
 4021                                .worktree_for_id(seed.worktree_id, cx)
 4022                            else {
 4023                                continue;
 4024                            };
 4025                            let json_delegate: Arc<dyn LspAdapterDelegate> =
 4026                                LocalLspAdapterDelegate::new(
 4027                                    local.languages.clone(),
 4028                                    &local.environment,
 4029                                    weak_ref.clone(),
 4030                                    &worktree,
 4031                                    local.http_client.clone(),
 4032                                    local.fs.clone(),
 4033                                    cx,
 4034                                );
 4035
 4036                            servers.push((json_adapter, json_server, json_delegate));
 4037
 4038                    }
 4039                    Some(servers)
 4040                })
 4041                .ok()
 4042                .flatten();
 4043
 4044            let Some(servers) = servers else {
 4045                return;
 4046            };
 4047
 4048            let Ok(Some((fs, _))) = this.read_with(cx, |this, _| {
 4049                let local = this.as_local()?;
 4050                let toolchain_store = local.toolchain_store().clone();
 4051                Some((local.fs.clone(), toolchain_store))
 4052            }) else {
 4053                return;
 4054            };
 4055            for (adapter, server, delegate) in servers {
 4056                adapter.clear_zed_json_schema_cache().await;
 4057
 4058                let Some(json_workspace_config) = LocalLspStore::workspace_configuration_for_adapter(
 4059                        adapter,
 4060                        fs.as_ref(),
 4061                        &delegate,
 4062                        None,
 4063                        cx,
 4064                    )
 4065                    .await
 4066                    .context("generate new workspace configuration for JSON language server while trying to refresh JSON Schemas")
 4067                    .ok()
 4068                else {
 4069                    continue;
 4070                };
 4071                server
 4072                    .notify::<lsp::notification::DidChangeConfiguration>(
 4073                        &lsp::DidChangeConfigurationParams {
 4074                            settings: json_workspace_config,
 4075                        },
 4076                    )
 4077                    .ok();
 4078            }
 4079        })
 4080        .detach();
 4081    }
 4082
 4083    pub(crate) fn register_buffer_with_language_servers(
 4084        &mut self,
 4085        buffer: &Entity<Buffer>,
 4086        only_register_servers: HashSet<LanguageServerSelector>,
 4087        ignore_refcounts: bool,
 4088        cx: &mut Context<Self>,
 4089    ) -> OpenLspBufferHandle {
 4090        let buffer_id = buffer.read(cx).remote_id();
 4091        let handle = cx.new(|_| buffer.clone());
 4092        if let Some(local) = self.as_local_mut() {
 4093            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4094            if !ignore_refcounts {
 4095                *refcount += 1;
 4096            }
 4097
 4098            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4099            // When a new unnamed buffer is created and saved, we will start loading it's language. Once the language is loaded, we go over all "language-less" buffers and try to fit that new language
 4100            // with them. However, we do that only for the buffers that we think are open in at least one editor; thus, we need to keep tab of unnamed buffers as well, even though they're not actually registered with any language
 4101            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4102            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4103                return handle;
 4104            };
 4105            if !file.is_local() {
 4106                return handle;
 4107            }
 4108
 4109            if ignore_refcounts || *refcount == 1 {
 4110                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4111            }
 4112            if !ignore_refcounts {
 4113                cx.observe_release(&handle, move |lsp_store, buffer, cx| {
 4114                    let refcount = {
 4115                        let local = lsp_store.as_local_mut().unwrap();
 4116                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4117                            debug_panic!("bad refcounting");
 4118                            return;
 4119                        };
 4120
 4121                        *refcount -= 1;
 4122                        *refcount
 4123                    };
 4124                    if refcount == 0 {
 4125                        lsp_store.lsp_document_colors.remove(&buffer_id);
 4126                        lsp_store.lsp_code_lens.remove(&buffer_id);
 4127                        let local = lsp_store.as_local_mut().unwrap();
 4128                        local.registered_buffers.remove(&buffer_id);
 4129                        local.buffers_opened_in_servers.remove(&buffer_id);
 4130                        if let Some(file) = File::from_dyn(buffer.read(cx).file()).cloned() {
 4131                            local.unregister_old_buffer_from_language_servers(buffer, &file, cx);
 4132                        }
 4133                    }
 4134                })
 4135                .detach();
 4136            }
 4137        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4138            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4139            cx.background_spawn(async move {
 4140                upstream_client
 4141                    .request(proto::RegisterBufferWithLanguageServers {
 4142                        project_id: upstream_project_id,
 4143                        buffer_id,
 4144                        only_servers: only_register_servers
 4145                            .into_iter()
 4146                            .map(|selector| {
 4147                                let selector = match selector {
 4148                                    LanguageServerSelector::Id(language_server_id) => {
 4149                                        proto::language_server_selector::Selector::ServerId(
 4150                                            language_server_id.to_proto(),
 4151                                        )
 4152                                    }
 4153                                    LanguageServerSelector::Name(language_server_name) => {
 4154                                        proto::language_server_selector::Selector::Name(
 4155                                            language_server_name.to_string(),
 4156                                        )
 4157                                    }
 4158                                };
 4159                                proto::LanguageServerSelector {
 4160                                    selector: Some(selector),
 4161                                }
 4162                            })
 4163                            .collect(),
 4164                    })
 4165                    .await
 4166            })
 4167            .detach();
 4168        } else {
 4169            panic!("oops!");
 4170        }
 4171        handle
 4172    }
 4173
 4174    fn maintain_buffer_languages(
 4175        languages: Arc<LanguageRegistry>,
 4176        cx: &mut Context<Self>,
 4177    ) -> Task<()> {
 4178        let mut subscription = languages.subscribe();
 4179        let mut prev_reload_count = languages.reload_count();
 4180        cx.spawn(async move |this, cx| {
 4181            while let Some(()) = subscription.next().await {
 4182                if let Some(this) = this.upgrade() {
 4183                    // If the language registry has been reloaded, then remove and
 4184                    // re-assign the languages on all open buffers.
 4185                    let reload_count = languages.reload_count();
 4186                    if reload_count > prev_reload_count {
 4187                        prev_reload_count = reload_count;
 4188                        this.update(cx, |this, cx| {
 4189                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4190                                for buffer in buffer_store.buffers() {
 4191                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4192                                    {
 4193                                        buffer
 4194                                            .update(cx, |buffer, cx| buffer.set_language(None, cx));
 4195                                        if let Some(local) = this.as_local_mut() {
 4196                                            local.reset_buffer(&buffer, &f, cx);
 4197
 4198                                            if local
 4199                                                .registered_buffers
 4200                                                .contains_key(&buffer.read(cx).remote_id())
 4201                                                && let Some(file_url) =
 4202                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4203                                            {
 4204                                                local.unregister_buffer_from_language_servers(
 4205                                                    &buffer, &file_url, cx,
 4206                                                );
 4207                                            }
 4208                                        }
 4209                                    }
 4210                                }
 4211                            });
 4212                        })
 4213                        .ok();
 4214                    }
 4215
 4216                    this.update(cx, |this, cx| {
 4217                        let mut plain_text_buffers = Vec::new();
 4218                        let mut buffers_with_unknown_injections = Vec::new();
 4219                        for handle in this.buffer_store.read(cx).buffers() {
 4220                            let buffer = handle.read(cx);
 4221                            if buffer.language().is_none()
 4222                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4223                            {
 4224                                plain_text_buffers.push(handle);
 4225                            } else if buffer.contains_unknown_injections() {
 4226                                buffers_with_unknown_injections.push(handle);
 4227                            }
 4228                        }
 4229
 4230                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4231                        // and reused later in the invisible worktrees.
 4232                        plain_text_buffers.sort_by_key(|buffer| {
 4233                            Reverse(
 4234                                File::from_dyn(buffer.read(cx).file())
 4235                                    .map(|file| file.worktree.read(cx).is_visible()),
 4236                            )
 4237                        });
 4238
 4239                        for buffer in plain_text_buffers {
 4240                            this.detect_language_for_buffer(&buffer, cx);
 4241                            if let Some(local) = this.as_local_mut() {
 4242                                local.initialize_buffer(&buffer, cx);
 4243                                if local
 4244                                    .registered_buffers
 4245                                    .contains_key(&buffer.read(cx).remote_id())
 4246                                {
 4247                                    local.register_buffer_with_language_servers(
 4248                                        &buffer,
 4249                                        HashSet::default(),
 4250                                        cx,
 4251                                    );
 4252                                }
 4253                            }
 4254                        }
 4255
 4256                        for buffer in buffers_with_unknown_injections {
 4257                            buffer.update(cx, |buffer, cx| buffer.reparse(cx));
 4258                        }
 4259                    })
 4260                    .ok();
 4261                }
 4262            }
 4263        })
 4264    }
 4265
 4266    fn detect_language_for_buffer(
 4267        &mut self,
 4268        buffer_handle: &Entity<Buffer>,
 4269        cx: &mut Context<Self>,
 4270    ) -> Option<language::AvailableLanguage> {
 4271        // If the buffer has a language, set it and start the language server if we haven't already.
 4272        let buffer = buffer_handle.read(cx);
 4273        let file = buffer.file()?;
 4274
 4275        let content = buffer.as_rope();
 4276        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4277        if let Some(available_language) = &available_language {
 4278            if let Some(Ok(Ok(new_language))) = self
 4279                .languages
 4280                .load_language(available_language)
 4281                .now_or_never()
 4282            {
 4283                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4284            }
 4285        } else {
 4286            cx.emit(LspStoreEvent::LanguageDetected {
 4287                buffer: buffer_handle.clone(),
 4288                new_language: None,
 4289            });
 4290        }
 4291
 4292        available_language
 4293    }
 4294
 4295    pub(crate) fn set_language_for_buffer(
 4296        &mut self,
 4297        buffer_entity: &Entity<Buffer>,
 4298        new_language: Arc<Language>,
 4299        cx: &mut Context<Self>,
 4300    ) {
 4301        let buffer = buffer_entity.read(cx);
 4302        let buffer_file = buffer.file().cloned();
 4303        let buffer_id = buffer.remote_id();
 4304        if let Some(local_store) = self.as_local_mut()
 4305            && local_store.registered_buffers.contains_key(&buffer_id)
 4306            && let Some(abs_path) =
 4307                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4308            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4309        {
 4310            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4311        }
 4312        buffer_entity.update(cx, |buffer, cx| {
 4313            if buffer
 4314                .language()
 4315                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4316            {
 4317                buffer.set_language(Some(new_language.clone()), cx);
 4318            }
 4319        });
 4320
 4321        let settings =
 4322            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4323        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4324
 4325        let worktree_id = if let Some(file) = buffer_file {
 4326            let worktree = file.worktree.clone();
 4327
 4328            if let Some(local) = self.as_local_mut()
 4329                && local.registered_buffers.contains_key(&buffer_id)
 4330            {
 4331                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4332            }
 4333            Some(worktree.read(cx).id())
 4334        } else {
 4335            None
 4336        };
 4337
 4338        if settings.prettier.allowed
 4339            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4340        {
 4341            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4342            if let Some(prettier_store) = prettier_store {
 4343                prettier_store.update(cx, |prettier_store, cx| {
 4344                    prettier_store.install_default_prettier(
 4345                        worktree_id,
 4346                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4347                        cx,
 4348                    )
 4349                })
 4350            }
 4351        }
 4352
 4353        cx.emit(LspStoreEvent::LanguageDetected {
 4354            buffer: buffer_entity.clone(),
 4355            new_language: Some(new_language),
 4356        })
 4357    }
 4358
 4359    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4360        self.buffer_store.clone()
 4361    }
 4362
 4363    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4364        self.active_entry = active_entry;
 4365    }
 4366
 4367    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4368        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4369            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4370        {
 4371            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4372                summaries
 4373                    .iter()
 4374                    .map(|(server_id, summary)| summary.to_proto(*server_id, path))
 4375            });
 4376            if let Some(summary) = summaries.next() {
 4377                client
 4378                    .send(proto::UpdateDiagnosticSummary {
 4379                        project_id: downstream_project_id,
 4380                        worktree_id: worktree.id().to_proto(),
 4381                        summary: Some(summary),
 4382                        more_summaries: summaries.collect(),
 4383                    })
 4384                    .log_err();
 4385            }
 4386        }
 4387    }
 4388
 4389    fn is_capable_for_proto_request<R>(
 4390        &self,
 4391        buffer: &Entity<Buffer>,
 4392        request: &R,
 4393        cx: &Context<Self>,
 4394    ) -> bool
 4395    where
 4396        R: LspCommand,
 4397    {
 4398        self.check_if_capable_for_proto_request(
 4399            buffer,
 4400            |capabilities| {
 4401                request.check_capabilities(AdapterServerCapabilities {
 4402                    server_capabilities: capabilities.clone(),
 4403                    code_action_kinds: None,
 4404                })
 4405            },
 4406            cx,
 4407        )
 4408    }
 4409
 4410    fn check_if_capable_for_proto_request<F>(
 4411        &self,
 4412        buffer: &Entity<Buffer>,
 4413        check: F,
 4414        cx: &Context<Self>,
 4415    ) -> bool
 4416    where
 4417        F: Fn(&lsp::ServerCapabilities) -> bool,
 4418    {
 4419        let Some(language) = buffer.read(cx).language().cloned() else {
 4420            return false;
 4421        };
 4422        let relevant_language_servers = self
 4423            .languages
 4424            .lsp_adapters(&language.name())
 4425            .into_iter()
 4426            .map(|lsp_adapter| lsp_adapter.name())
 4427            .collect::<HashSet<_>>();
 4428        self.language_server_statuses
 4429            .iter()
 4430            .filter_map(|(server_id, server_status)| {
 4431                relevant_language_servers
 4432                    .contains(&server_status.name)
 4433                    .then_some(server_id)
 4434            })
 4435            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4436            .any(check)
 4437    }
 4438
 4439    pub fn request_lsp<R>(
 4440        &mut self,
 4441        buffer: Entity<Buffer>,
 4442        server: LanguageServerToQuery,
 4443        request: R,
 4444        cx: &mut Context<Self>,
 4445    ) -> Task<Result<R::Response>>
 4446    where
 4447        R: LspCommand,
 4448        <R::LspRequest as lsp::request::Request>::Result: Send,
 4449        <R::LspRequest as lsp::request::Request>::Params: Send,
 4450    {
 4451        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4452            return self.send_lsp_proto_request(
 4453                buffer,
 4454                upstream_client,
 4455                upstream_project_id,
 4456                request,
 4457                cx,
 4458            );
 4459        }
 4460
 4461        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4462            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4463                local
 4464                    .language_servers_for_buffer(buffer, cx)
 4465                    .find(|(_, server)| {
 4466                        request.check_capabilities(server.adapter_server_capabilities())
 4467                    })
 4468                    .map(|(_, server)| server.clone())
 4469            }),
 4470            LanguageServerToQuery::Other(id) => self
 4471                .language_server_for_local_buffer(buffer, id, cx)
 4472                .and_then(|(_, server)| {
 4473                    request
 4474                        .check_capabilities(server.adapter_server_capabilities())
 4475                        .then(|| Arc::clone(server))
 4476                }),
 4477        }) else {
 4478            return Task::ready(Ok(Default::default()));
 4479        };
 4480
 4481        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4482
 4483        let Some(file) = file else {
 4484            return Task::ready(Ok(Default::default()));
 4485        };
 4486
 4487        let lsp_params = match request.to_lsp_params_or_response(
 4488            &file.abs_path(cx),
 4489            buffer.read(cx),
 4490            &language_server,
 4491            cx,
 4492        ) {
 4493            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4494            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4495
 4496            Err(err) => {
 4497                let message = format!(
 4498                    "{} via {} failed: {}",
 4499                    request.display_name(),
 4500                    language_server.name(),
 4501                    err
 4502                );
 4503                log::warn!("{message}");
 4504                return Task::ready(Err(anyhow!(message)));
 4505            }
 4506        };
 4507
 4508        let status = request.status();
 4509        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4510            return Task::ready(Ok(Default::default()));
 4511        }
 4512        cx.spawn(async move |this, cx| {
 4513            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4514
 4515            let id = lsp_request.id();
 4516            let _cleanup = if status.is_some() {
 4517                cx.update(|cx| {
 4518                    this.update(cx, |this, cx| {
 4519                        this.on_lsp_work_start(
 4520                            language_server.server_id(),
 4521                            id.to_string(),
 4522                            LanguageServerProgress {
 4523                                is_disk_based_diagnostics_progress: false,
 4524                                is_cancellable: false,
 4525                                title: None,
 4526                                message: status.clone(),
 4527                                percentage: None,
 4528                                last_update_at: cx.background_executor().now(),
 4529                            },
 4530                            cx,
 4531                        );
 4532                    })
 4533                })
 4534                .log_err();
 4535
 4536                Some(defer(|| {
 4537                    cx.update(|cx| {
 4538                        this.update(cx, |this, cx| {
 4539                            this.on_lsp_work_end(language_server.server_id(), id.to_string(), cx);
 4540                        })
 4541                    })
 4542                    .log_err();
 4543                }))
 4544            } else {
 4545                None
 4546            };
 4547
 4548            let result = lsp_request.await.into_response();
 4549
 4550            let response = result.map_err(|err| {
 4551                let message = format!(
 4552                    "{} via {} failed: {}",
 4553                    request.display_name(),
 4554                    language_server.name(),
 4555                    err
 4556                );
 4557                log::warn!("{message}");
 4558                anyhow::anyhow!(message)
 4559            })?;
 4560
 4561            request
 4562                .response_from_lsp(
 4563                    response,
 4564                    this.upgrade().context("no app context")?,
 4565                    buffer,
 4566                    language_server.server_id(),
 4567                    cx.clone(),
 4568                )
 4569                .await
 4570        })
 4571    }
 4572
 4573    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4574        let mut language_formatters_to_check = Vec::new();
 4575        for buffer in self.buffer_store.read(cx).buffers() {
 4576            let buffer = buffer.read(cx);
 4577            let buffer_file = File::from_dyn(buffer.file());
 4578            let buffer_language = buffer.language();
 4579            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4580            if buffer_language.is_some() {
 4581                language_formatters_to_check.push((
 4582                    buffer_file.map(|f| f.worktree_id(cx)),
 4583                    settings.into_owned(),
 4584                ));
 4585            }
 4586        }
 4587
 4588        self.request_workspace_config_refresh();
 4589
 4590        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4591            prettier_store.update(cx, |prettier_store, cx| {
 4592                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4593            })
 4594        }
 4595
 4596        cx.notify();
 4597    }
 4598
 4599    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4600        let buffer_store = self.buffer_store.clone();
 4601        let Some(local) = self.as_local_mut() else {
 4602            return;
 4603        };
 4604        let mut adapters = BTreeMap::default();
 4605        let get_adapter = {
 4606            let languages = local.languages.clone();
 4607            let environment = local.environment.clone();
 4608            let weak = local.weak.clone();
 4609            let worktree_store = local.worktree_store.clone();
 4610            let http_client = local.http_client.clone();
 4611            let fs = local.fs.clone();
 4612            move |worktree_id, cx: &mut App| {
 4613                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4614                Some(LocalLspAdapterDelegate::new(
 4615                    languages.clone(),
 4616                    &environment,
 4617                    weak.clone(),
 4618                    &worktree,
 4619                    http_client.clone(),
 4620                    fs.clone(),
 4621                    cx,
 4622                ))
 4623            }
 4624        };
 4625
 4626        let mut messages_to_report = Vec::new();
 4627        let (new_tree, to_stop) = {
 4628            let mut rebase = local.lsp_tree.rebase();
 4629            let buffers = buffer_store
 4630                .read(cx)
 4631                .buffers()
 4632                .filter_map(|buffer| {
 4633                    let raw_buffer = buffer.read(cx);
 4634                    if !local
 4635                        .registered_buffers
 4636                        .contains_key(&raw_buffer.remote_id())
 4637                    {
 4638                        return None;
 4639                    }
 4640                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4641                    let language = raw_buffer.language().cloned()?;
 4642                    Some((file, language, raw_buffer.remote_id()))
 4643                })
 4644                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4645            for (file, language, buffer_id) in buffers {
 4646                let worktree_id = file.worktree_id(cx);
 4647                let Some(worktree) = local
 4648                    .worktree_store
 4649                    .read(cx)
 4650                    .worktree_for_id(worktree_id, cx)
 4651                else {
 4652                    continue;
 4653                };
 4654
 4655                if let Some((_, apply)) = local.reuse_existing_language_server(
 4656                    rebase.server_tree(),
 4657                    &worktree,
 4658                    &language.name(),
 4659                    cx,
 4660                ) {
 4661                    (apply)(rebase.server_tree());
 4662                } else if let Some(lsp_delegate) = adapters
 4663                    .entry(worktree_id)
 4664                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4665                    .clone()
 4666                {
 4667                    let delegate =
 4668                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4669                    let path = file
 4670                        .path()
 4671                        .parent()
 4672                        .map(Arc::from)
 4673                        .unwrap_or_else(|| file.path().clone());
 4674                    let worktree_path = ProjectPath { worktree_id, path };
 4675                    let abs_path = file.abs_path(cx);
 4676                    let worktree_root = worktree.read(cx).abs_path();
 4677                    let nodes = rebase
 4678                        .walk(
 4679                            worktree_path,
 4680                            language.name(),
 4681                            language.manifest(),
 4682                            delegate.clone(),
 4683                            cx,
 4684                        )
 4685                        .collect::<Vec<_>>();
 4686                    for node in nodes {
 4687                        let server_id = node.server_id_or_init(|disposition| {
 4688                            let path = &disposition.path;
 4689                            let uri = Url::from_file_path(worktree_root.join(&path.path));
 4690                            let key = LanguageServerSeed {
 4691                                worktree_id,
 4692                                name: disposition.server_name.clone(),
 4693                                settings: disposition.settings.clone(),
 4694                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4695                                    path.worktree_id,
 4696                                    &path.path,
 4697                                    language.name(),
 4698                                ),
 4699                            };
 4700                            local.language_server_ids.remove(&key);
 4701
 4702                            let server_id = local.get_or_insert_language_server(
 4703                                &worktree,
 4704                                lsp_delegate.clone(),
 4705                                disposition,
 4706                                &language.name(),
 4707                                cx,
 4708                            );
 4709                            if let Some(state) = local.language_servers.get(&server_id)
 4710                                && let Ok(uri) = uri
 4711                            {
 4712                                state.add_workspace_folder(uri);
 4713                            };
 4714                            server_id
 4715                        });
 4716
 4717                        if let Some(language_server_id) = server_id {
 4718                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 4719                                language_server_id,
 4720                                name: node.name(),
 4721                                message:
 4722                                    proto::update_language_server::Variant::RegisteredForBuffer(
 4723                                        proto::RegisteredForBuffer {
 4724                                            buffer_abs_path: abs_path.to_string_lossy().to_string(),
 4725                                            buffer_id: buffer_id.to_proto(),
 4726                                        },
 4727                                    ),
 4728                            });
 4729                        }
 4730                    }
 4731                } else {
 4732                    continue;
 4733                }
 4734            }
 4735            rebase.finish()
 4736        };
 4737        for message in messages_to_report {
 4738            cx.emit(message);
 4739        }
 4740        local.lsp_tree = new_tree;
 4741        for (id, _) in to_stop {
 4742            self.stop_local_language_server(id, cx).detach();
 4743        }
 4744    }
 4745
 4746    pub fn apply_code_action(
 4747        &self,
 4748        buffer_handle: Entity<Buffer>,
 4749        mut action: CodeAction,
 4750        push_to_history: bool,
 4751        cx: &mut Context<Self>,
 4752    ) -> Task<Result<ProjectTransaction>> {
 4753        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4754            let request = proto::ApplyCodeAction {
 4755                project_id,
 4756                buffer_id: buffer_handle.read(cx).remote_id().into(),
 4757                action: Some(Self::serialize_code_action(&action)),
 4758            };
 4759            let buffer_store = self.buffer_store();
 4760            cx.spawn(async move |_, cx| {
 4761                let response = upstream_client
 4762                    .request(request)
 4763                    .await?
 4764                    .transaction
 4765                    .context("missing transaction")?;
 4766
 4767                buffer_store
 4768                    .update(cx, |buffer_store, cx| {
 4769                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 4770                    })?
 4771                    .await
 4772            })
 4773        } else if self.mode.is_local() {
 4774            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 4775                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 4776                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 4777            }) else {
 4778                return Task::ready(Ok(ProjectTransaction::default()));
 4779            };
 4780            cx.spawn(async move |this,  cx| {
 4781                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 4782                    .await
 4783                    .context("resolving a code action")?;
 4784                if let Some(edit) = action.lsp_action.edit()
 4785                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 4786                        return LocalLspStore::deserialize_workspace_edit(
 4787                            this.upgrade().context("no app present")?,
 4788                            edit.clone(),
 4789                            push_to_history,
 4790
 4791                            lang_server.clone(),
 4792                            cx,
 4793                        )
 4794                        .await;
 4795                    }
 4796
 4797                if let Some(command) = action.lsp_action.command() {
 4798                    let server_capabilities = lang_server.capabilities();
 4799                    let available_commands = server_capabilities
 4800                        .execute_command_provider
 4801                        .as_ref()
 4802                        .map(|options| options.commands.as_slice())
 4803                        .unwrap_or_default();
 4804                    if available_commands.contains(&command.command) {
 4805                        this.update(cx, |this, _| {
 4806                            this.as_local_mut()
 4807                                .unwrap()
 4808                                .last_workspace_edits_by_language_server
 4809                                .remove(&lang_server.server_id());
 4810                        })?;
 4811
 4812                        let _result = lang_server
 4813                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 4814                                command: command.command.clone(),
 4815                                arguments: command.arguments.clone().unwrap_or_default(),
 4816                                ..lsp::ExecuteCommandParams::default()
 4817                            })
 4818                            .await.into_response()
 4819                            .context("execute command")?;
 4820
 4821                        return this.update(cx, |this, _| {
 4822                            this.as_local_mut()
 4823                                .unwrap()
 4824                                .last_workspace_edits_by_language_server
 4825                                .remove(&lang_server.server_id())
 4826                                .unwrap_or_default()
 4827                        });
 4828                    } else {
 4829                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 4830                    }
 4831                }
 4832
 4833                Ok(ProjectTransaction::default())
 4834            })
 4835        } else {
 4836            Task::ready(Err(anyhow!("no upstream client and not local")))
 4837        }
 4838    }
 4839
 4840    pub fn apply_code_action_kind(
 4841        &mut self,
 4842        buffers: HashSet<Entity<Buffer>>,
 4843        kind: CodeActionKind,
 4844        push_to_history: bool,
 4845        cx: &mut Context<Self>,
 4846    ) -> Task<anyhow::Result<ProjectTransaction>> {
 4847        if self.as_local().is_some() {
 4848            cx.spawn(async move |lsp_store, cx| {
 4849                let buffers = buffers.into_iter().collect::<Vec<_>>();
 4850                let result = LocalLspStore::execute_code_action_kind_locally(
 4851                    lsp_store.clone(),
 4852                    buffers,
 4853                    kind,
 4854                    push_to_history,
 4855                    cx,
 4856                )
 4857                .await;
 4858                lsp_store.update(cx, |lsp_store, _| {
 4859                    lsp_store.update_last_formatting_failure(&result);
 4860                })?;
 4861                result
 4862            })
 4863        } else if let Some((client, project_id)) = self.upstream_client() {
 4864            let buffer_store = self.buffer_store();
 4865            cx.spawn(async move |lsp_store, cx| {
 4866                let result = client
 4867                    .request(proto::ApplyCodeActionKind {
 4868                        project_id,
 4869                        kind: kind.as_str().to_owned(),
 4870                        buffer_ids: buffers
 4871                            .iter()
 4872                            .map(|buffer| {
 4873                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 4874                            })
 4875                            .collect::<Result<_>>()?,
 4876                    })
 4877                    .await
 4878                    .and_then(|result| result.transaction.context("missing transaction"));
 4879                lsp_store.update(cx, |lsp_store, _| {
 4880                    lsp_store.update_last_formatting_failure(&result);
 4881                })?;
 4882
 4883                let transaction_response = result?;
 4884                buffer_store
 4885                    .update(cx, |buffer_store, cx| {
 4886                        buffer_store.deserialize_project_transaction(
 4887                            transaction_response,
 4888                            push_to_history,
 4889                            cx,
 4890                        )
 4891                    })?
 4892                    .await
 4893            })
 4894        } else {
 4895            Task::ready(Ok(ProjectTransaction::default()))
 4896        }
 4897    }
 4898
 4899    pub fn resolve_inlay_hint(
 4900        &self,
 4901        mut hint: InlayHint,
 4902        buffer: Entity<Buffer>,
 4903        server_id: LanguageServerId,
 4904        cx: &mut Context<Self>,
 4905    ) -> Task<anyhow::Result<InlayHint>> {
 4906        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4907            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 4908            {
 4909                hint.resolve_state = ResolveState::Resolved;
 4910                return Task::ready(Ok(hint));
 4911            }
 4912            let request = proto::ResolveInlayHint {
 4913                project_id,
 4914                buffer_id: buffer.read(cx).remote_id().into(),
 4915                language_server_id: server_id.0 as u64,
 4916                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 4917            };
 4918            cx.background_spawn(async move {
 4919                let response = upstream_client
 4920                    .request(request)
 4921                    .await
 4922                    .context("inlay hints proto request")?;
 4923                match response.hint {
 4924                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 4925                        .context("inlay hints proto resolve response conversion"),
 4926                    None => Ok(hint),
 4927                }
 4928            })
 4929        } else {
 4930            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 4931                self.language_server_for_local_buffer(buffer, server_id, cx)
 4932                    .map(|(_, server)| server.clone())
 4933            }) else {
 4934                return Task::ready(Ok(hint));
 4935            };
 4936            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 4937                return Task::ready(Ok(hint));
 4938            }
 4939            let buffer_snapshot = buffer.read(cx).snapshot();
 4940            cx.spawn(async move |_, cx| {
 4941                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 4942                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 4943                );
 4944                let resolved_hint = resolve_task
 4945                    .await
 4946                    .into_response()
 4947                    .context("inlay hint resolve LSP request")?;
 4948                let resolved_hint = InlayHints::lsp_to_project_hint(
 4949                    resolved_hint,
 4950                    &buffer,
 4951                    server_id,
 4952                    ResolveState::Resolved,
 4953                    false,
 4954                    cx,
 4955                )
 4956                .await?;
 4957                Ok(resolved_hint)
 4958            })
 4959        }
 4960    }
 4961
 4962    pub fn resolve_color_presentation(
 4963        &mut self,
 4964        mut color: DocumentColor,
 4965        buffer: Entity<Buffer>,
 4966        server_id: LanguageServerId,
 4967        cx: &mut Context<Self>,
 4968    ) -> Task<Result<DocumentColor>> {
 4969        if color.resolved {
 4970            return Task::ready(Ok(color));
 4971        }
 4972
 4973        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4974            let start = color.lsp_range.start;
 4975            let end = color.lsp_range.end;
 4976            let request = proto::GetColorPresentation {
 4977                project_id,
 4978                server_id: server_id.to_proto(),
 4979                buffer_id: buffer.read(cx).remote_id().into(),
 4980                color: Some(proto::ColorInformation {
 4981                    red: color.color.red,
 4982                    green: color.color.green,
 4983                    blue: color.color.blue,
 4984                    alpha: color.color.alpha,
 4985                    lsp_range_start: Some(proto::PointUtf16 {
 4986                        row: start.line,
 4987                        column: start.character,
 4988                    }),
 4989                    lsp_range_end: Some(proto::PointUtf16 {
 4990                        row: end.line,
 4991                        column: end.character,
 4992                    }),
 4993                }),
 4994            };
 4995            cx.background_spawn(async move {
 4996                let response = upstream_client
 4997                    .request(request)
 4998                    .await
 4999                    .context("color presentation proto request")?;
 5000                color.resolved = true;
 5001                color.color_presentations = response
 5002                    .presentations
 5003                    .into_iter()
 5004                    .map(|presentation| ColorPresentation {
 5005                        label: SharedString::from(presentation.label),
 5006                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5007                        additional_text_edits: presentation
 5008                            .additional_text_edits
 5009                            .into_iter()
 5010                            .filter_map(deserialize_lsp_edit)
 5011                            .collect(),
 5012                    })
 5013                    .collect();
 5014                Ok(color)
 5015            })
 5016        } else {
 5017            let path = match buffer
 5018                .update(cx, |buffer, cx| {
 5019                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5020                })
 5021                .context("buffer with the missing path")
 5022            {
 5023                Ok(path) => path,
 5024                Err(e) => return Task::ready(Err(e)),
 5025            };
 5026            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5027                self.language_server_for_local_buffer(buffer, server_id, cx)
 5028                    .map(|(_, server)| server.clone())
 5029            }) else {
 5030                return Task::ready(Ok(color));
 5031            };
 5032            cx.background_spawn(async move {
 5033                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5034                    lsp::ColorPresentationParams {
 5035                        text_document: make_text_document_identifier(&path)?,
 5036                        color: color.color,
 5037                        range: color.lsp_range,
 5038                        work_done_progress_params: Default::default(),
 5039                        partial_result_params: Default::default(),
 5040                    },
 5041                );
 5042                color.color_presentations = resolve_task
 5043                    .await
 5044                    .into_response()
 5045                    .context("color presentation resolve LSP request")?
 5046                    .into_iter()
 5047                    .map(|presentation| ColorPresentation {
 5048                        label: SharedString::from(presentation.label),
 5049                        text_edit: presentation.text_edit,
 5050                        additional_text_edits: presentation
 5051                            .additional_text_edits
 5052                            .unwrap_or_default(),
 5053                    })
 5054                    .collect();
 5055                color.resolved = true;
 5056                Ok(color)
 5057            })
 5058        }
 5059    }
 5060
 5061    pub(crate) fn linked_edits(
 5062        &mut self,
 5063        buffer: &Entity<Buffer>,
 5064        position: Anchor,
 5065        cx: &mut Context<Self>,
 5066    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5067        let snapshot = buffer.read(cx).snapshot();
 5068        let scope = snapshot.language_scope_at(position);
 5069        let Some(server_id) = self
 5070            .as_local()
 5071            .and_then(|local| {
 5072                buffer.update(cx, |buffer, cx| {
 5073                    local
 5074                        .language_servers_for_buffer(buffer, cx)
 5075                        .filter(|(_, server)| {
 5076                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5077                        })
 5078                        .filter(|(adapter, _)| {
 5079                            scope
 5080                                .as_ref()
 5081                                .map(|scope| scope.language_allowed(&adapter.name))
 5082                                .unwrap_or(true)
 5083                        })
 5084                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5085                        .next()
 5086                })
 5087            })
 5088            .or_else(|| {
 5089                self.upstream_client()
 5090                    .is_some()
 5091                    .then_some(LanguageServerToQuery::FirstCapable)
 5092            })
 5093            .filter(|_| {
 5094                maybe!({
 5095                    let language = buffer.read(cx).language_at(position)?;
 5096                    Some(
 5097                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5098                            .linked_edits,
 5099                    )
 5100                }) == Some(true)
 5101            })
 5102        else {
 5103            return Task::ready(Ok(Vec::new()));
 5104        };
 5105
 5106        self.request_lsp(
 5107            buffer.clone(),
 5108            server_id,
 5109            LinkedEditingRange { position },
 5110            cx,
 5111        )
 5112    }
 5113
 5114    fn apply_on_type_formatting(
 5115        &mut self,
 5116        buffer: Entity<Buffer>,
 5117        position: Anchor,
 5118        trigger: String,
 5119        cx: &mut Context<Self>,
 5120    ) -> Task<Result<Option<Transaction>>> {
 5121        if let Some((client, project_id)) = self.upstream_client() {
 5122            if !self.check_if_capable_for_proto_request(
 5123                &buffer,
 5124                |capabilities| {
 5125                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5126                },
 5127                cx,
 5128            ) {
 5129                return Task::ready(Ok(None));
 5130            }
 5131            let request = proto::OnTypeFormatting {
 5132                project_id,
 5133                buffer_id: buffer.read(cx).remote_id().into(),
 5134                position: Some(serialize_anchor(&position)),
 5135                trigger,
 5136                version: serialize_version(&buffer.read(cx).version()),
 5137            };
 5138            cx.background_spawn(async move {
 5139                client
 5140                    .request(request)
 5141                    .await?
 5142                    .transaction
 5143                    .map(language::proto::deserialize_transaction)
 5144                    .transpose()
 5145            })
 5146        } else if let Some(local) = self.as_local_mut() {
 5147            let buffer_id = buffer.read(cx).remote_id();
 5148            local.buffers_being_formatted.insert(buffer_id);
 5149            cx.spawn(async move |this, cx| {
 5150                let _cleanup = defer({
 5151                    let this = this.clone();
 5152                    let mut cx = cx.clone();
 5153                    move || {
 5154                        this.update(&mut cx, |this, _| {
 5155                            if let Some(local) = this.as_local_mut() {
 5156                                local.buffers_being_formatted.remove(&buffer_id);
 5157                            }
 5158                        })
 5159                        .ok();
 5160                    }
 5161                });
 5162
 5163                buffer
 5164                    .update(cx, |buffer, _| {
 5165                        buffer.wait_for_edits(Some(position.timestamp))
 5166                    })?
 5167                    .await?;
 5168                this.update(cx, |this, cx| {
 5169                    let position = position.to_point_utf16(buffer.read(cx));
 5170                    this.on_type_format(buffer, position, trigger, false, cx)
 5171                })?
 5172                .await
 5173            })
 5174        } else {
 5175            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5176        }
 5177    }
 5178
 5179    pub fn on_type_format<T: ToPointUtf16>(
 5180        &mut self,
 5181        buffer: Entity<Buffer>,
 5182        position: T,
 5183        trigger: String,
 5184        push_to_history: bool,
 5185        cx: &mut Context<Self>,
 5186    ) -> Task<Result<Option<Transaction>>> {
 5187        let position = position.to_point_utf16(buffer.read(cx));
 5188        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5189    }
 5190
 5191    fn on_type_format_impl(
 5192        &mut self,
 5193        buffer: Entity<Buffer>,
 5194        position: PointUtf16,
 5195        trigger: String,
 5196        push_to_history: bool,
 5197        cx: &mut Context<Self>,
 5198    ) -> Task<Result<Option<Transaction>>> {
 5199        let options = buffer.update(cx, |buffer, cx| {
 5200            lsp_command::lsp_formatting_options(
 5201                language_settings(
 5202                    buffer.language_at(position).map(|l| l.name()),
 5203                    buffer.file(),
 5204                    cx,
 5205                )
 5206                .as_ref(),
 5207            )
 5208        });
 5209
 5210        cx.spawn(async move |this, cx| {
 5211            if let Some(waiter) =
 5212                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5213            {
 5214                waiter.await?;
 5215            }
 5216            cx.update(|cx| {
 5217                this.update(cx, |this, cx| {
 5218                    this.request_lsp(
 5219                        buffer.clone(),
 5220                        LanguageServerToQuery::FirstCapable,
 5221                        OnTypeFormatting {
 5222                            position,
 5223                            trigger,
 5224                            options,
 5225                            push_to_history,
 5226                        },
 5227                        cx,
 5228                    )
 5229                })
 5230            })??
 5231            .await
 5232        })
 5233    }
 5234
 5235    pub fn definitions(
 5236        &mut self,
 5237        buffer: &Entity<Buffer>,
 5238        position: PointUtf16,
 5239        cx: &mut Context<Self>,
 5240    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5241        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5242            let request = GetDefinitions { position };
 5243            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5244                return Task::ready(Ok(None));
 5245            }
 5246            let request_task = upstream_client.request_lsp(
 5247                project_id,
 5248                LSP_REQUEST_TIMEOUT,
 5249                cx.background_executor().clone(),
 5250                request.to_proto(project_id, buffer.read(cx)),
 5251            );
 5252            let buffer = buffer.clone();
 5253            cx.spawn(async move |weak_project, cx| {
 5254                let Some(project) = weak_project.upgrade() else {
 5255                    return Ok(None);
 5256                };
 5257                let Some(responses) = request_task.await? else {
 5258                    return Ok(None);
 5259                };
 5260                let actions = join_all(responses.payload.into_iter().map(|response| {
 5261                    GetDefinitions { position }.response_from_proto(
 5262                        response.response,
 5263                        project.clone(),
 5264                        buffer.clone(),
 5265                        cx.clone(),
 5266                    )
 5267                }))
 5268                .await;
 5269
 5270                Ok(Some(
 5271                    actions
 5272                        .into_iter()
 5273                        .collect::<Result<Vec<Vec<_>>>>()?
 5274                        .into_iter()
 5275                        .flatten()
 5276                        .dedup()
 5277                        .collect(),
 5278                ))
 5279            })
 5280        } else {
 5281            let definitions_task = self.request_multiple_lsp_locally(
 5282                buffer,
 5283                Some(position),
 5284                GetDefinitions { position },
 5285                cx,
 5286            );
 5287            cx.background_spawn(async move {
 5288                Ok(Some(
 5289                    definitions_task
 5290                        .await
 5291                        .into_iter()
 5292                        .flat_map(|(_, definitions)| definitions)
 5293                        .dedup()
 5294                        .collect(),
 5295                ))
 5296            })
 5297        }
 5298    }
 5299
 5300    pub fn declarations(
 5301        &mut self,
 5302        buffer: &Entity<Buffer>,
 5303        position: PointUtf16,
 5304        cx: &mut Context<Self>,
 5305    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5306        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5307            let request = GetDeclarations { position };
 5308            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5309                return Task::ready(Ok(None));
 5310            }
 5311            let request_task = upstream_client.request_lsp(
 5312                project_id,
 5313                LSP_REQUEST_TIMEOUT,
 5314                cx.background_executor().clone(),
 5315                request.to_proto(project_id, buffer.read(cx)),
 5316            );
 5317            let buffer = buffer.clone();
 5318            cx.spawn(async move |weak_project, cx| {
 5319                let Some(project) = weak_project.upgrade() else {
 5320                    return Ok(None);
 5321                };
 5322                let Some(responses) = request_task.await? else {
 5323                    return Ok(None);
 5324                };
 5325                let actions = join_all(responses.payload.into_iter().map(|response| {
 5326                    GetDeclarations { position }.response_from_proto(
 5327                        response.response,
 5328                        project.clone(),
 5329                        buffer.clone(),
 5330                        cx.clone(),
 5331                    )
 5332                }))
 5333                .await;
 5334
 5335                Ok(Some(
 5336                    actions
 5337                        .into_iter()
 5338                        .collect::<Result<Vec<Vec<_>>>>()?
 5339                        .into_iter()
 5340                        .flatten()
 5341                        .dedup()
 5342                        .collect(),
 5343                ))
 5344            })
 5345        } else {
 5346            let declarations_task = self.request_multiple_lsp_locally(
 5347                buffer,
 5348                Some(position),
 5349                GetDeclarations { position },
 5350                cx,
 5351            );
 5352            cx.background_spawn(async move {
 5353                Ok(Some(
 5354                    declarations_task
 5355                        .await
 5356                        .into_iter()
 5357                        .flat_map(|(_, declarations)| declarations)
 5358                        .dedup()
 5359                        .collect(),
 5360                ))
 5361            })
 5362        }
 5363    }
 5364
 5365    pub fn type_definitions(
 5366        &mut self,
 5367        buffer: &Entity<Buffer>,
 5368        position: PointUtf16,
 5369        cx: &mut Context<Self>,
 5370    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5371        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5372            let request = GetTypeDefinitions { position };
 5373            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5374                return Task::ready(Ok(None));
 5375            }
 5376            let request_task = upstream_client.request_lsp(
 5377                project_id,
 5378                LSP_REQUEST_TIMEOUT,
 5379                cx.background_executor().clone(),
 5380                request.to_proto(project_id, buffer.read(cx)),
 5381            );
 5382            let buffer = buffer.clone();
 5383            cx.spawn(async move |weak_project, cx| {
 5384                let Some(project) = weak_project.upgrade() else {
 5385                    return Ok(None);
 5386                };
 5387                let Some(responses) = request_task.await? else {
 5388                    return Ok(None);
 5389                };
 5390                let actions = join_all(responses.payload.into_iter().map(|response| {
 5391                    GetTypeDefinitions { position }.response_from_proto(
 5392                        response.response,
 5393                        project.clone(),
 5394                        buffer.clone(),
 5395                        cx.clone(),
 5396                    )
 5397                }))
 5398                .await;
 5399
 5400                Ok(Some(
 5401                    actions
 5402                        .into_iter()
 5403                        .collect::<Result<Vec<Vec<_>>>>()?
 5404                        .into_iter()
 5405                        .flatten()
 5406                        .dedup()
 5407                        .collect(),
 5408                ))
 5409            })
 5410        } else {
 5411            let type_definitions_task = self.request_multiple_lsp_locally(
 5412                buffer,
 5413                Some(position),
 5414                GetTypeDefinitions { position },
 5415                cx,
 5416            );
 5417            cx.background_spawn(async move {
 5418                Ok(Some(
 5419                    type_definitions_task
 5420                        .await
 5421                        .into_iter()
 5422                        .flat_map(|(_, type_definitions)| type_definitions)
 5423                        .dedup()
 5424                        .collect(),
 5425                ))
 5426            })
 5427        }
 5428    }
 5429
 5430    pub fn implementations(
 5431        &mut self,
 5432        buffer: &Entity<Buffer>,
 5433        position: PointUtf16,
 5434        cx: &mut Context<Self>,
 5435    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5436        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5437            let request = GetImplementations { position };
 5438            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5439                return Task::ready(Ok(None));
 5440            }
 5441            let request_task = upstream_client.request_lsp(
 5442                project_id,
 5443                LSP_REQUEST_TIMEOUT,
 5444                cx.background_executor().clone(),
 5445                request.to_proto(project_id, buffer.read(cx)),
 5446            );
 5447            let buffer = buffer.clone();
 5448            cx.spawn(async move |weak_project, cx| {
 5449                let Some(project) = weak_project.upgrade() else {
 5450                    return Ok(None);
 5451                };
 5452                let Some(responses) = request_task.await? else {
 5453                    return Ok(None);
 5454                };
 5455                let actions = join_all(responses.payload.into_iter().map(|response| {
 5456                    GetImplementations { position }.response_from_proto(
 5457                        response.response,
 5458                        project.clone(),
 5459                        buffer.clone(),
 5460                        cx.clone(),
 5461                    )
 5462                }))
 5463                .await;
 5464
 5465                Ok(Some(
 5466                    actions
 5467                        .into_iter()
 5468                        .collect::<Result<Vec<Vec<_>>>>()?
 5469                        .into_iter()
 5470                        .flatten()
 5471                        .dedup()
 5472                        .collect(),
 5473                ))
 5474            })
 5475        } else {
 5476            let implementations_task = self.request_multiple_lsp_locally(
 5477                buffer,
 5478                Some(position),
 5479                GetImplementations { position },
 5480                cx,
 5481            );
 5482            cx.background_spawn(async move {
 5483                Ok(Some(
 5484                    implementations_task
 5485                        .await
 5486                        .into_iter()
 5487                        .flat_map(|(_, implementations)| implementations)
 5488                        .dedup()
 5489                        .collect(),
 5490                ))
 5491            })
 5492        }
 5493    }
 5494
 5495    pub fn references(
 5496        &mut self,
 5497        buffer: &Entity<Buffer>,
 5498        position: PointUtf16,
 5499        cx: &mut Context<Self>,
 5500    ) -> Task<Result<Option<Vec<Location>>>> {
 5501        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5502            let request = GetReferences { position };
 5503            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5504                return Task::ready(Ok(None));
 5505            }
 5506
 5507            let request_task = upstream_client.request_lsp(
 5508                project_id,
 5509                LSP_REQUEST_TIMEOUT,
 5510                cx.background_executor().clone(),
 5511                request.to_proto(project_id, buffer.read(cx)),
 5512            );
 5513            let buffer = buffer.clone();
 5514            cx.spawn(async move |weak_project, cx| {
 5515                let Some(project) = weak_project.upgrade() else {
 5516                    return Ok(None);
 5517                };
 5518                let Some(responses) = request_task.await? else {
 5519                    return Ok(None);
 5520                };
 5521
 5522                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5523                    GetReferences { position }.response_from_proto(
 5524                        lsp_response.response,
 5525                        project.clone(),
 5526                        buffer.clone(),
 5527                        cx.clone(),
 5528                    )
 5529                }))
 5530                .await
 5531                .into_iter()
 5532                .collect::<Result<Vec<Vec<_>>>>()?
 5533                .into_iter()
 5534                .flatten()
 5535                .dedup()
 5536                .collect();
 5537                Ok(Some(locations))
 5538            })
 5539        } else {
 5540            let references_task = self.request_multiple_lsp_locally(
 5541                buffer,
 5542                Some(position),
 5543                GetReferences { position },
 5544                cx,
 5545            );
 5546            cx.background_spawn(async move {
 5547                Ok(Some(
 5548                    references_task
 5549                        .await
 5550                        .into_iter()
 5551                        .flat_map(|(_, references)| references)
 5552                        .dedup()
 5553                        .collect(),
 5554                ))
 5555            })
 5556        }
 5557    }
 5558
 5559    pub fn code_actions(
 5560        &mut self,
 5561        buffer: &Entity<Buffer>,
 5562        range: Range<Anchor>,
 5563        kinds: Option<Vec<CodeActionKind>>,
 5564        cx: &mut Context<Self>,
 5565    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5566        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5567            let request = GetCodeActions {
 5568                range: range.clone(),
 5569                kinds: kinds.clone(),
 5570            };
 5571            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5572                return Task::ready(Ok(None));
 5573            }
 5574            let request_task = upstream_client.request_lsp(
 5575                project_id,
 5576                LSP_REQUEST_TIMEOUT,
 5577                cx.background_executor().clone(),
 5578                request.to_proto(project_id, buffer.read(cx)),
 5579            );
 5580            let buffer = buffer.clone();
 5581            cx.spawn(async move |weak_project, cx| {
 5582                let Some(project) = weak_project.upgrade() else {
 5583                    return Ok(None);
 5584                };
 5585                let Some(responses) = request_task.await? else {
 5586                    return Ok(None);
 5587                };
 5588                let actions = join_all(responses.payload.into_iter().map(|response| {
 5589                    GetCodeActions {
 5590                        range: range.clone(),
 5591                        kinds: kinds.clone(),
 5592                    }
 5593                    .response_from_proto(
 5594                        response.response,
 5595                        project.clone(),
 5596                        buffer.clone(),
 5597                        cx.clone(),
 5598                    )
 5599                }))
 5600                .await;
 5601
 5602                Ok(Some(
 5603                    actions
 5604                        .into_iter()
 5605                        .collect::<Result<Vec<Vec<_>>>>()?
 5606                        .into_iter()
 5607                        .flatten()
 5608                        .collect(),
 5609                ))
 5610            })
 5611        } else {
 5612            let all_actions_task = self.request_multiple_lsp_locally(
 5613                buffer,
 5614                Some(range.start),
 5615                GetCodeActions { range, kinds },
 5616                cx,
 5617            );
 5618            cx.background_spawn(async move {
 5619                Ok(Some(
 5620                    all_actions_task
 5621                        .await
 5622                        .into_iter()
 5623                        .flat_map(|(_, actions)| actions)
 5624                        .collect(),
 5625                ))
 5626            })
 5627        }
 5628    }
 5629
 5630    pub fn code_lens_actions(
 5631        &mut self,
 5632        buffer: &Entity<Buffer>,
 5633        cx: &mut Context<Self>,
 5634    ) -> CodeLensTask {
 5635        let version_queried_for = buffer.read(cx).version();
 5636        let buffer_id = buffer.read(cx).remote_id();
 5637
 5638        if let Some(cached_data) = self.lsp_code_lens.get(&buffer_id)
 5639            && !version_queried_for.changed_since(&cached_data.lens_for_version)
 5640        {
 5641            let has_different_servers = self.as_local().is_some_and(|local| {
 5642                local
 5643                    .buffers_opened_in_servers
 5644                    .get(&buffer_id)
 5645                    .cloned()
 5646                    .unwrap_or_default()
 5647                    != cached_data.lens.keys().copied().collect()
 5648            });
 5649            if !has_different_servers {
 5650                return Task::ready(Ok(Some(
 5651                    cached_data.lens.values().flatten().cloned().collect(),
 5652                )))
 5653                .shared();
 5654            }
 5655        }
 5656
 5657        let lsp_data = self.lsp_code_lens.entry(buffer_id).or_default();
 5658        if let Some((updating_for, running_update)) = &lsp_data.update
 5659            && !version_queried_for.changed_since(updating_for)
 5660        {
 5661            return running_update.clone();
 5662        }
 5663        let buffer = buffer.clone();
 5664        let query_version_queried_for = version_queried_for.clone();
 5665        let new_task = cx
 5666            .spawn(async move |lsp_store, cx| {
 5667                cx.background_executor()
 5668                    .timer(Duration::from_millis(30))
 5669                    .await;
 5670                let fetched_lens = lsp_store
 5671                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 5672                    .map_err(Arc::new)?
 5673                    .await
 5674                    .context("fetching code lens")
 5675                    .map_err(Arc::new);
 5676                let fetched_lens = match fetched_lens {
 5677                    Ok(fetched_lens) => fetched_lens,
 5678                    Err(e) => {
 5679                        lsp_store
 5680                            .update(cx, |lsp_store, _| {
 5681                                lsp_store.lsp_code_lens.entry(buffer_id).or_default().update = None;
 5682                            })
 5683                            .ok();
 5684                        return Err(e);
 5685                    }
 5686                };
 5687
 5688                lsp_store
 5689                    .update(cx, |lsp_store, _| {
 5690                        let lsp_data = lsp_store.lsp_code_lens.entry(buffer_id).or_default();
 5691                        if let Some(fetched_lens) = fetched_lens {
 5692                            if lsp_data.lens_for_version == query_version_queried_for {
 5693                                lsp_data.lens.extend(fetched_lens);
 5694                            } else if !lsp_data
 5695                                .lens_for_version
 5696                                .changed_since(&query_version_queried_for)
 5697                            {
 5698                                lsp_data.lens_for_version = query_version_queried_for;
 5699                                lsp_data.lens = fetched_lens;
 5700                            }
 5701                        }
 5702                        lsp_data.update = None;
 5703                        Some(lsp_data.lens.values().flatten().cloned().collect())
 5704                    })
 5705                    .map_err(Arc::new)
 5706            })
 5707            .shared();
 5708        lsp_data.update = Some((version_queried_for, new_task.clone()));
 5709        new_task
 5710    }
 5711
 5712    fn fetch_code_lens(
 5713        &mut self,
 5714        buffer: &Entity<Buffer>,
 5715        cx: &mut Context<Self>,
 5716    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 5717        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5718            let request = GetCodeLens;
 5719            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5720                return Task::ready(Ok(None));
 5721            }
 5722            let request_task = upstream_client.request_lsp(
 5723                project_id,
 5724                LSP_REQUEST_TIMEOUT,
 5725                cx.background_executor().clone(),
 5726                request.to_proto(project_id, buffer.read(cx)),
 5727            );
 5728            let buffer = buffer.clone();
 5729            cx.spawn(async move |weak_lsp_store, cx| {
 5730                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5731                    return Ok(None);
 5732                };
 5733                let Some(responses) = request_task.await? else {
 5734                    return Ok(None);
 5735                };
 5736
 5737                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 5738                    let lsp_store = lsp_store.clone();
 5739                    let buffer = buffer.clone();
 5740                    let cx = cx.clone();
 5741                    async move {
 5742                        (
 5743                            LanguageServerId::from_proto(response.server_id),
 5744                            GetCodeLens
 5745                                .response_from_proto(response.response, lsp_store, buffer, cx)
 5746                                .await,
 5747                        )
 5748                    }
 5749                }))
 5750                .await;
 5751
 5752                let mut has_errors = false;
 5753                let code_lens_actions = code_lens_actions
 5754                    .into_iter()
 5755                    .filter_map(|(server_id, code_lens)| match code_lens {
 5756                        Ok(code_lens) => Some((server_id, code_lens)),
 5757                        Err(e) => {
 5758                            has_errors = true;
 5759                            log::error!("{e:#}");
 5760                            None
 5761                        }
 5762                    })
 5763                    .collect::<HashMap<_, _>>();
 5764                anyhow::ensure!(
 5765                    !has_errors || !code_lens_actions.is_empty(),
 5766                    "Failed to fetch code lens"
 5767                );
 5768                Ok(Some(code_lens_actions))
 5769            })
 5770        } else {
 5771            let code_lens_actions_task =
 5772                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 5773            cx.background_spawn(async move {
 5774                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 5775            })
 5776        }
 5777    }
 5778
 5779    #[inline(never)]
 5780    pub fn completions(
 5781        &self,
 5782        buffer: &Entity<Buffer>,
 5783        position: PointUtf16,
 5784        context: CompletionContext,
 5785        cx: &mut Context<Self>,
 5786    ) -> Task<Result<Vec<CompletionResponse>>> {
 5787        let language_registry = self.languages.clone();
 5788
 5789        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5790            let request = GetCompletions { position, context };
 5791            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5792                return Task::ready(Ok(Vec::new()));
 5793            }
 5794            let task = self.send_lsp_proto_request(
 5795                buffer.clone(),
 5796                upstream_client,
 5797                project_id,
 5798                request,
 5799                cx,
 5800            );
 5801            let language = buffer.read(cx).language().cloned();
 5802
 5803            // In the future, we should provide project guests with the names of LSP adapters,
 5804            // so that they can use the correct LSP adapter when computing labels. For now,
 5805            // guests just use the first LSP adapter associated with the buffer's language.
 5806            let lsp_adapter = language.as_ref().and_then(|language| {
 5807                language_registry
 5808                    .lsp_adapters(&language.name())
 5809                    .first()
 5810                    .cloned()
 5811            });
 5812
 5813            cx.foreground_executor().spawn(async move {
 5814                let completion_response = task.await?;
 5815                let completions = populate_labels_for_completions(
 5816                    completion_response.completions,
 5817                    language,
 5818                    lsp_adapter,
 5819                )
 5820                .await;
 5821                Ok(vec![CompletionResponse {
 5822                    completions,
 5823                    is_incomplete: completion_response.is_incomplete,
 5824                }])
 5825            })
 5826        } else if let Some(local) = self.as_local() {
 5827            let snapshot = buffer.read(cx).snapshot();
 5828            let offset = position.to_offset(&snapshot);
 5829            let scope = snapshot.language_scope_at(offset);
 5830            let language = snapshot.language().cloned();
 5831            let completion_settings = language_settings(
 5832                language.as_ref().map(|language| language.name()),
 5833                buffer.read(cx).file(),
 5834                cx,
 5835            )
 5836            .completions;
 5837            if !completion_settings.lsp {
 5838                return Task::ready(Ok(Vec::new()));
 5839            }
 5840
 5841            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 5842                local
 5843                    .language_servers_for_buffer(buffer, cx)
 5844                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 5845                    .filter(|(adapter, _)| {
 5846                        scope
 5847                            .as_ref()
 5848                            .map(|scope| scope.language_allowed(&adapter.name))
 5849                            .unwrap_or(true)
 5850                    })
 5851                    .map(|(_, server)| server.server_id())
 5852                    .collect()
 5853            });
 5854
 5855            let buffer = buffer.clone();
 5856            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 5857            let lsp_timeout = if lsp_timeout > 0 {
 5858                Some(Duration::from_millis(lsp_timeout))
 5859            } else {
 5860                None
 5861            };
 5862            cx.spawn(async move |this,  cx| {
 5863                let mut tasks = Vec::with_capacity(server_ids.len());
 5864                this.update(cx, |lsp_store, cx| {
 5865                    for server_id in server_ids {
 5866                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 5867                        let lsp_timeout = lsp_timeout
 5868                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 5869                        let mut timeout = cx.background_spawn(async move {
 5870                            match lsp_timeout {
 5871                                Some(lsp_timeout) => {
 5872                                    lsp_timeout.await;
 5873                                    true
 5874                                },
 5875                                None => false,
 5876                            }
 5877                        }).fuse();
 5878                        let mut lsp_request = lsp_store.request_lsp(
 5879                            buffer.clone(),
 5880                            LanguageServerToQuery::Other(server_id),
 5881                            GetCompletions {
 5882                                position,
 5883                                context: context.clone(),
 5884                            },
 5885                            cx,
 5886                        ).fuse();
 5887                        let new_task = cx.background_spawn(async move {
 5888                            select_biased! {
 5889                                response = lsp_request => anyhow::Ok(Some(response?)),
 5890                                timeout_happened = timeout => {
 5891                                    if timeout_happened {
 5892                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 5893                                        Ok(None)
 5894                                    } else {
 5895                                        let completions = lsp_request.await?;
 5896                                        Ok(Some(completions))
 5897                                    }
 5898                                },
 5899                            }
 5900                        });
 5901                        tasks.push((lsp_adapter, new_task));
 5902                    }
 5903                })?;
 5904
 5905                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 5906                    let completion_response = task.await.ok()??;
 5907                    let completions = populate_labels_for_completions(
 5908                            completion_response.completions,
 5909                            language.clone(),
 5910                            lsp_adapter,
 5911                        )
 5912                        .await;
 5913                    Some(CompletionResponse {
 5914                        completions,
 5915                        is_incomplete: completion_response.is_incomplete,
 5916                    })
 5917                });
 5918
 5919                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 5920
 5921                Ok(responses.into_iter().flatten().collect())
 5922            })
 5923        } else {
 5924            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5925        }
 5926    }
 5927
 5928    pub fn resolve_completions(
 5929        &self,
 5930        buffer: Entity<Buffer>,
 5931        completion_indices: Vec<usize>,
 5932        completions: Rc<RefCell<Box<[Completion]>>>,
 5933        cx: &mut Context<Self>,
 5934    ) -> Task<Result<bool>> {
 5935        let client = self.upstream_client();
 5936        let buffer_id = buffer.read(cx).remote_id();
 5937        let buffer_snapshot = buffer.read(cx).snapshot();
 5938
 5939        if !self.check_if_capable_for_proto_request(
 5940            &buffer,
 5941            GetCompletions::can_resolve_completions,
 5942            cx,
 5943        ) {
 5944            return Task::ready(Ok(false));
 5945        }
 5946        cx.spawn(async move |lsp_store, cx| {
 5947            let mut did_resolve = false;
 5948            if let Some((client, project_id)) = client {
 5949                for completion_index in completion_indices {
 5950                    let server_id = {
 5951                        let completion = &completions.borrow()[completion_index];
 5952                        completion.source.server_id()
 5953                    };
 5954                    if let Some(server_id) = server_id {
 5955                        if Self::resolve_completion_remote(
 5956                            project_id,
 5957                            server_id,
 5958                            buffer_id,
 5959                            completions.clone(),
 5960                            completion_index,
 5961                            client.clone(),
 5962                        )
 5963                        .await
 5964                        .log_err()
 5965                        .is_some()
 5966                        {
 5967                            did_resolve = true;
 5968                        }
 5969                    } else {
 5970                        resolve_word_completion(
 5971                            &buffer_snapshot,
 5972                            &mut completions.borrow_mut()[completion_index],
 5973                        );
 5974                    }
 5975                }
 5976            } else {
 5977                for completion_index in completion_indices {
 5978                    let server_id = {
 5979                        let completion = &completions.borrow()[completion_index];
 5980                        completion.source.server_id()
 5981                    };
 5982                    if let Some(server_id) = server_id {
 5983                        let server_and_adapter = lsp_store
 5984                            .read_with(cx, |lsp_store, _| {
 5985                                let server = lsp_store.language_server_for_id(server_id)?;
 5986                                let adapter =
 5987                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 5988                                Some((server, adapter))
 5989                            })
 5990                            .ok()
 5991                            .flatten();
 5992                        let Some((server, adapter)) = server_and_adapter else {
 5993                            continue;
 5994                        };
 5995
 5996                        let resolved = Self::resolve_completion_local(
 5997                            server,
 5998                            completions.clone(),
 5999                            completion_index,
 6000                        )
 6001                        .await
 6002                        .log_err()
 6003                        .is_some();
 6004                        if resolved {
 6005                            Self::regenerate_completion_labels(
 6006                                adapter,
 6007                                &buffer_snapshot,
 6008                                completions.clone(),
 6009                                completion_index,
 6010                            )
 6011                            .await
 6012                            .log_err();
 6013                            did_resolve = true;
 6014                        }
 6015                    } else {
 6016                        resolve_word_completion(
 6017                            &buffer_snapshot,
 6018                            &mut completions.borrow_mut()[completion_index],
 6019                        );
 6020                    }
 6021                }
 6022            }
 6023
 6024            Ok(did_resolve)
 6025        })
 6026    }
 6027
 6028    async fn resolve_completion_local(
 6029        server: Arc<lsp::LanguageServer>,
 6030        completions: Rc<RefCell<Box<[Completion]>>>,
 6031        completion_index: usize,
 6032    ) -> Result<()> {
 6033        let server_id = server.server_id();
 6034        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6035            return Ok(());
 6036        }
 6037
 6038        let request = {
 6039            let completion = &completions.borrow()[completion_index];
 6040            match &completion.source {
 6041                CompletionSource::Lsp {
 6042                    lsp_completion,
 6043                    resolved,
 6044                    server_id: completion_server_id,
 6045                    ..
 6046                } => {
 6047                    if *resolved {
 6048                        return Ok(());
 6049                    }
 6050                    anyhow::ensure!(
 6051                        server_id == *completion_server_id,
 6052                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6053                    );
 6054                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6055                }
 6056                CompletionSource::BufferWord { .. }
 6057                | CompletionSource::Dap { .. }
 6058                | CompletionSource::Custom => {
 6059                    return Ok(());
 6060                }
 6061            }
 6062        };
 6063        let resolved_completion = request
 6064            .await
 6065            .into_response()
 6066            .context("resolve completion")?;
 6067
 6068        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6069        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6070
 6071        let mut completions = completions.borrow_mut();
 6072        let completion = &mut completions[completion_index];
 6073        if let CompletionSource::Lsp {
 6074            lsp_completion,
 6075            resolved,
 6076            server_id: completion_server_id,
 6077            ..
 6078        } = &mut completion.source
 6079        {
 6080            if *resolved {
 6081                return Ok(());
 6082            }
 6083            anyhow::ensure!(
 6084                server_id == *completion_server_id,
 6085                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6086            );
 6087            *lsp_completion = Box::new(resolved_completion);
 6088            *resolved = true;
 6089        }
 6090        Ok(())
 6091    }
 6092
 6093    async fn regenerate_completion_labels(
 6094        adapter: Arc<CachedLspAdapter>,
 6095        snapshot: &BufferSnapshot,
 6096        completions: Rc<RefCell<Box<[Completion]>>>,
 6097        completion_index: usize,
 6098    ) -> Result<()> {
 6099        let completion_item = completions.borrow()[completion_index]
 6100            .source
 6101            .lsp_completion(true)
 6102            .map(Cow::into_owned);
 6103        if let Some(lsp_documentation) = completion_item
 6104            .as_ref()
 6105            .and_then(|completion_item| completion_item.documentation.clone())
 6106        {
 6107            let mut completions = completions.borrow_mut();
 6108            let completion = &mut completions[completion_index];
 6109            completion.documentation = Some(lsp_documentation.into());
 6110        } else {
 6111            let mut completions = completions.borrow_mut();
 6112            let completion = &mut completions[completion_index];
 6113            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6114        }
 6115
 6116        let mut new_label = match completion_item {
 6117            Some(completion_item) => {
 6118                // 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
 6119                // So we have to update the label here anyway...
 6120                let language = snapshot.language();
 6121                match language {
 6122                    Some(language) => {
 6123                        adapter
 6124                            .labels_for_completions(
 6125                                std::slice::from_ref(&completion_item),
 6126                                language,
 6127                            )
 6128                            .await?
 6129                    }
 6130                    None => Vec::new(),
 6131                }
 6132                .pop()
 6133                .flatten()
 6134                .unwrap_or_else(|| {
 6135                    CodeLabel::fallback_for_completion(
 6136                        &completion_item,
 6137                        language.map(|language| language.as_ref()),
 6138                    )
 6139                })
 6140            }
 6141            None => CodeLabel::plain(
 6142                completions.borrow()[completion_index].new_text.clone(),
 6143                None,
 6144            ),
 6145        };
 6146        ensure_uniform_list_compatible_label(&mut new_label);
 6147
 6148        let mut completions = completions.borrow_mut();
 6149        let completion = &mut completions[completion_index];
 6150        if completion.label.filter_text() == new_label.filter_text() {
 6151            completion.label = new_label;
 6152        } else {
 6153            log::error!(
 6154                "Resolved completion changed display label from {} to {}. \
 6155                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6156                completion.label.text(),
 6157                new_label.text(),
 6158                completion.label.filter_text(),
 6159                new_label.filter_text()
 6160            );
 6161        }
 6162
 6163        Ok(())
 6164    }
 6165
 6166    async fn resolve_completion_remote(
 6167        project_id: u64,
 6168        server_id: LanguageServerId,
 6169        buffer_id: BufferId,
 6170        completions: Rc<RefCell<Box<[Completion]>>>,
 6171        completion_index: usize,
 6172        client: AnyProtoClient,
 6173    ) -> Result<()> {
 6174        let lsp_completion = {
 6175            let completion = &completions.borrow()[completion_index];
 6176            match &completion.source {
 6177                CompletionSource::Lsp {
 6178                    lsp_completion,
 6179                    resolved,
 6180                    server_id: completion_server_id,
 6181                    ..
 6182                } => {
 6183                    anyhow::ensure!(
 6184                        server_id == *completion_server_id,
 6185                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6186                    );
 6187                    if *resolved {
 6188                        return Ok(());
 6189                    }
 6190                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6191                }
 6192                CompletionSource::Custom
 6193                | CompletionSource::Dap { .. }
 6194                | CompletionSource::BufferWord { .. } => {
 6195                    return Ok(());
 6196                }
 6197            }
 6198        };
 6199        let request = proto::ResolveCompletionDocumentation {
 6200            project_id,
 6201            language_server_id: server_id.0 as u64,
 6202            lsp_completion,
 6203            buffer_id: buffer_id.into(),
 6204        };
 6205
 6206        let response = client
 6207            .request(request)
 6208            .await
 6209            .context("completion documentation resolve proto request")?;
 6210        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6211
 6212        let documentation = if response.documentation.is_empty() {
 6213            CompletionDocumentation::Undocumented
 6214        } else if response.documentation_is_markdown {
 6215            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6216        } else if response.documentation.lines().count() <= 1 {
 6217            CompletionDocumentation::SingleLine(response.documentation.into())
 6218        } else {
 6219            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6220        };
 6221
 6222        let mut completions = completions.borrow_mut();
 6223        let completion = &mut completions[completion_index];
 6224        completion.documentation = Some(documentation);
 6225        if let CompletionSource::Lsp {
 6226            insert_range,
 6227            lsp_completion,
 6228            resolved,
 6229            server_id: completion_server_id,
 6230            lsp_defaults: _,
 6231        } = &mut completion.source
 6232        {
 6233            let completion_insert_range = response
 6234                .old_insert_start
 6235                .and_then(deserialize_anchor)
 6236                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6237            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6238
 6239            if *resolved {
 6240                return Ok(());
 6241            }
 6242            anyhow::ensure!(
 6243                server_id == *completion_server_id,
 6244                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6245            );
 6246            *lsp_completion = Box::new(resolved_lsp_completion);
 6247            *resolved = true;
 6248        }
 6249
 6250        let replace_range = response
 6251            .old_replace_start
 6252            .and_then(deserialize_anchor)
 6253            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6254        if let Some((old_replace_start, old_replace_end)) = replace_range
 6255            && !response.new_text.is_empty()
 6256        {
 6257            completion.new_text = response.new_text;
 6258            completion.replace_range = old_replace_start..old_replace_end;
 6259        }
 6260
 6261        Ok(())
 6262    }
 6263
 6264    pub fn apply_additional_edits_for_completion(
 6265        &self,
 6266        buffer_handle: Entity<Buffer>,
 6267        completions: Rc<RefCell<Box<[Completion]>>>,
 6268        completion_index: usize,
 6269        push_to_history: bool,
 6270        cx: &mut Context<Self>,
 6271    ) -> Task<Result<Option<Transaction>>> {
 6272        if let Some((client, project_id)) = self.upstream_client() {
 6273            let buffer = buffer_handle.read(cx);
 6274            let buffer_id = buffer.remote_id();
 6275            cx.spawn(async move |_, cx| {
 6276                let request = {
 6277                    let completion = completions.borrow()[completion_index].clone();
 6278                    proto::ApplyCompletionAdditionalEdits {
 6279                        project_id,
 6280                        buffer_id: buffer_id.into(),
 6281                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6282                            replace_range: completion.replace_range,
 6283                            new_text: completion.new_text,
 6284                            source: completion.source,
 6285                        })),
 6286                    }
 6287                };
 6288
 6289                if let Some(transaction) = client.request(request).await?.transaction {
 6290                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6291                    buffer_handle
 6292                        .update(cx, |buffer, _| {
 6293                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6294                        })?
 6295                        .await?;
 6296                    if push_to_history {
 6297                        buffer_handle.update(cx, |buffer, _| {
 6298                            buffer.push_transaction(transaction.clone(), Instant::now());
 6299                            buffer.finalize_last_transaction();
 6300                        })?;
 6301                    }
 6302                    Ok(Some(transaction))
 6303                } else {
 6304                    Ok(None)
 6305                }
 6306            })
 6307        } else {
 6308            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6309                let completion = &completions.borrow()[completion_index];
 6310                let server_id = completion.source.server_id()?;
 6311                Some(
 6312                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6313                        .1
 6314                        .clone(),
 6315                )
 6316            }) else {
 6317                return Task::ready(Ok(None));
 6318            };
 6319
 6320            cx.spawn(async move |this, cx| {
 6321                Self::resolve_completion_local(
 6322                    server.clone(),
 6323                    completions.clone(),
 6324                    completion_index,
 6325                )
 6326                .await
 6327                .context("resolving completion")?;
 6328                let completion = completions.borrow()[completion_index].clone();
 6329                let additional_text_edits = completion
 6330                    .source
 6331                    .lsp_completion(true)
 6332                    .as_ref()
 6333                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6334                if let Some(edits) = additional_text_edits {
 6335                    let edits = this
 6336                        .update(cx, |this, cx| {
 6337                            this.as_local_mut().unwrap().edits_from_lsp(
 6338                                &buffer_handle,
 6339                                edits,
 6340                                server.server_id(),
 6341                                None,
 6342                                cx,
 6343                            )
 6344                        })?
 6345                        .await?;
 6346
 6347                    buffer_handle.update(cx, |buffer, cx| {
 6348                        buffer.finalize_last_transaction();
 6349                        buffer.start_transaction();
 6350
 6351                        for (range, text) in edits {
 6352                            let primary = &completion.replace_range;
 6353                            let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6354                                && primary.end.cmp(&range.start, buffer).is_ge();
 6355                            let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6356                                && range.end.cmp(&primary.end, buffer).is_ge();
 6357
 6358                            //Skip additional edits which overlap with the primary completion edit
 6359                            //https://github.com/zed-industries/zed/pull/1871
 6360                            if !start_within && !end_within {
 6361                                buffer.edit([(range, text)], None, cx);
 6362                            }
 6363                        }
 6364
 6365                        let transaction = if buffer.end_transaction(cx).is_some() {
 6366                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6367                            if !push_to_history {
 6368                                buffer.forget_transaction(transaction.id);
 6369                            }
 6370                            Some(transaction)
 6371                        } else {
 6372                            None
 6373                        };
 6374                        Ok(transaction)
 6375                    })?
 6376                } else {
 6377                    Ok(None)
 6378                }
 6379            })
 6380        }
 6381    }
 6382
 6383    pub fn pull_diagnostics(
 6384        &mut self,
 6385        buffer: Entity<Buffer>,
 6386        cx: &mut Context<Self>,
 6387    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6388        let buffer_id = buffer.read(cx).remote_id();
 6389
 6390        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6391            let request = GetDocumentDiagnostics {
 6392                previous_result_id: None,
 6393            };
 6394            if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 6395                return Task::ready(Ok(None));
 6396            }
 6397            let request_task = client.request_lsp(
 6398                upstream_project_id,
 6399                LSP_REQUEST_TIMEOUT,
 6400                cx.background_executor().clone(),
 6401                request.to_proto(upstream_project_id, buffer.read(cx)),
 6402            );
 6403            cx.background_spawn(async move {
 6404                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6405                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6406                // Do not attempt to further process the dummy responses here.
 6407                let _response = request_task.await?;
 6408                Ok(None)
 6409            })
 6410        } else {
 6411            let server_ids = buffer.update(cx, |buffer, cx| {
 6412                self.language_servers_for_local_buffer(buffer, cx)
 6413                    .map(|(_, server)| server.server_id())
 6414                    .collect::<Vec<_>>()
 6415            });
 6416            let pull_diagnostics = server_ids
 6417                .into_iter()
 6418                .map(|server_id| {
 6419                    let result_id = self.result_id(server_id, buffer_id, cx);
 6420                    self.request_lsp(
 6421                        buffer.clone(),
 6422                        LanguageServerToQuery::Other(server_id),
 6423                        GetDocumentDiagnostics {
 6424                            previous_result_id: result_id,
 6425                        },
 6426                        cx,
 6427                    )
 6428                })
 6429                .collect::<Vec<_>>();
 6430
 6431            cx.background_spawn(async move {
 6432                let mut responses = Vec::new();
 6433                for diagnostics in join_all(pull_diagnostics).await {
 6434                    responses.extend(diagnostics?);
 6435                }
 6436                Ok(Some(responses))
 6437            })
 6438        }
 6439    }
 6440
 6441    pub fn inlay_hints(
 6442        &mut self,
 6443        buffer: Entity<Buffer>,
 6444        range: Range<Anchor>,
 6445        cx: &mut Context<Self>,
 6446    ) -> Task<anyhow::Result<Vec<InlayHint>>> {
 6447        let range_start = range.start;
 6448        let range_end = range.end;
 6449        let buffer_id = buffer.read(cx).remote_id().into();
 6450        let request = InlayHints { range };
 6451
 6452        if let Some((client, project_id)) = self.upstream_client() {
 6453            if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 6454                return Task::ready(Ok(Vec::new()));
 6455            }
 6456            let proto_request = proto::InlayHints {
 6457                project_id,
 6458                buffer_id,
 6459                start: Some(serialize_anchor(&range_start)),
 6460                end: Some(serialize_anchor(&range_end)),
 6461                version: serialize_version(&buffer.read(cx).version()),
 6462            };
 6463            cx.spawn(async move |project, cx| {
 6464                let response = client
 6465                    .request(proto_request)
 6466                    .await
 6467                    .context("inlay hints proto request")?;
 6468                LspCommand::response_from_proto(
 6469                    request,
 6470                    response,
 6471                    project.upgrade().context("No project")?,
 6472                    buffer.clone(),
 6473                    cx.clone(),
 6474                )
 6475                .await
 6476                .context("inlay hints proto response conversion")
 6477            })
 6478        } else {
 6479            let lsp_request_task = self.request_lsp(
 6480                buffer.clone(),
 6481                LanguageServerToQuery::FirstCapable,
 6482                request,
 6483                cx,
 6484            );
 6485            cx.spawn(async move |_, cx| {
 6486                buffer
 6487                    .update(cx, |buffer, _| {
 6488                        buffer.wait_for_edits(vec![range_start.timestamp, range_end.timestamp])
 6489                    })?
 6490                    .await
 6491                    .context("waiting for inlay hint request range edits")?;
 6492                lsp_request_task.await.context("inlay hints LSP request")
 6493            })
 6494        }
 6495    }
 6496
 6497    pub fn pull_diagnostics_for_buffer(
 6498        &mut self,
 6499        buffer: Entity<Buffer>,
 6500        cx: &mut Context<Self>,
 6501    ) -> Task<anyhow::Result<()>> {
 6502        let diagnostics = self.pull_diagnostics(buffer, cx);
 6503        cx.spawn(async move |lsp_store, cx| {
 6504            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 6505                return Ok(());
 6506            };
 6507            lsp_store.update(cx, |lsp_store, cx| {
 6508                if lsp_store.as_local().is_none() {
 6509                    return;
 6510                }
 6511
 6512                let mut unchanged_buffers = HashSet::default();
 6513                let mut changed_buffers = HashSet::default();
 6514                let server_diagnostics_updates = diagnostics
 6515                    .into_iter()
 6516                    .filter_map(|diagnostics_set| match diagnostics_set {
 6517                        LspPullDiagnostics::Response {
 6518                            server_id,
 6519                            uri,
 6520                            diagnostics,
 6521                        } => Some((server_id, uri, diagnostics)),
 6522                        LspPullDiagnostics::Default => None,
 6523                    })
 6524                    .fold(
 6525                        HashMap::default(),
 6526                        |mut acc, (server_id, uri, diagnostics)| {
 6527                            let (result_id, diagnostics) = match diagnostics {
 6528                                PulledDiagnostics::Unchanged { result_id } => {
 6529                                    unchanged_buffers.insert(uri.clone());
 6530                                    (Some(result_id), Vec::new())
 6531                                }
 6532                                PulledDiagnostics::Changed {
 6533                                    result_id,
 6534                                    diagnostics,
 6535                                } => {
 6536                                    changed_buffers.insert(uri.clone());
 6537                                    (result_id, diagnostics)
 6538                                }
 6539                            };
 6540                            let disk_based_sources = Cow::Owned(
 6541                                lsp_store
 6542                                    .language_server_adapter_for_id(server_id)
 6543                                    .as_ref()
 6544                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 6545                                    .unwrap_or(&[])
 6546                                    .to_vec(),
 6547                            );
 6548                            acc.entry(server_id).or_insert_with(Vec::new).push(
 6549                                DocumentDiagnosticsUpdate {
 6550                                    server_id,
 6551                                    diagnostics: lsp::PublishDiagnosticsParams {
 6552                                        uri,
 6553                                        diagnostics,
 6554                                        version: None,
 6555                                    },
 6556                                    result_id,
 6557                                    disk_based_sources,
 6558                                },
 6559                            );
 6560                            acc
 6561                        },
 6562                    );
 6563
 6564                for diagnostic_updates in server_diagnostics_updates.into_values() {
 6565                    lsp_store
 6566                        .merge_lsp_diagnostics(
 6567                            DiagnosticSourceKind::Pulled,
 6568                            diagnostic_updates,
 6569                            |buffer, old_diagnostic, cx| {
 6570                                File::from_dyn(buffer.file())
 6571                                    .and_then(|file| {
 6572                                        let abs_path = file.as_local()?.abs_path(cx);
 6573                                        lsp::Url::from_file_path(abs_path).ok()
 6574                                    })
 6575                                    .is_none_or(|buffer_uri| {
 6576                                        unchanged_buffers.contains(&buffer_uri)
 6577                                            || match old_diagnostic.source_kind {
 6578                                                DiagnosticSourceKind::Pulled => {
 6579                                                    !changed_buffers.contains(&buffer_uri)
 6580                                                }
 6581                                                DiagnosticSourceKind::Other
 6582                                                | DiagnosticSourceKind::Pushed => true,
 6583                                            }
 6584                                    })
 6585                            },
 6586                            cx,
 6587                        )
 6588                        .log_err();
 6589                }
 6590            })
 6591        })
 6592    }
 6593
 6594    pub fn document_colors(
 6595        &mut self,
 6596        fetch_strategy: LspFetchStrategy,
 6597        buffer: Entity<Buffer>,
 6598        cx: &mut Context<Self>,
 6599    ) -> Option<DocumentColorTask> {
 6600        let version_queried_for = buffer.read(cx).version();
 6601        let buffer_id = buffer.read(cx).remote_id();
 6602
 6603        match fetch_strategy {
 6604            LspFetchStrategy::IgnoreCache => {}
 6605            LspFetchStrategy::UseCache {
 6606                known_cache_version,
 6607            } => {
 6608                if let Some(cached_data) = self.lsp_document_colors.get(&buffer_id)
 6609                    && !version_queried_for.changed_since(&cached_data.colors_for_version)
 6610                {
 6611                    let has_different_servers = self.as_local().is_some_and(|local| {
 6612                        local
 6613                            .buffers_opened_in_servers
 6614                            .get(&buffer_id)
 6615                            .cloned()
 6616                            .unwrap_or_default()
 6617                            != cached_data.colors.keys().copied().collect()
 6618                    });
 6619                    if !has_different_servers {
 6620                        if Some(cached_data.cache_version) == known_cache_version {
 6621                            return None;
 6622                        } else {
 6623                            return Some(
 6624                                Task::ready(Ok(DocumentColors {
 6625                                    colors: cached_data
 6626                                        .colors
 6627                                        .values()
 6628                                        .flatten()
 6629                                        .cloned()
 6630                                        .collect(),
 6631                                    cache_version: Some(cached_data.cache_version),
 6632                                }))
 6633                                .shared(),
 6634                            );
 6635                        }
 6636                    }
 6637                }
 6638            }
 6639        }
 6640
 6641        let lsp_data = self.lsp_document_colors.entry(buffer_id).or_default();
 6642        if let Some((updating_for, running_update)) = &lsp_data.colors_update
 6643            && !version_queried_for.changed_since(updating_for)
 6644        {
 6645            return Some(running_update.clone());
 6646        }
 6647        let query_version_queried_for = version_queried_for.clone();
 6648        let new_task = cx
 6649            .spawn(async move |lsp_store, cx| {
 6650                cx.background_executor()
 6651                    .timer(Duration::from_millis(30))
 6652                    .await;
 6653                let fetched_colors = lsp_store
 6654                    .update(cx, |lsp_store, cx| {
 6655                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 6656                    })?
 6657                    .await
 6658                    .context("fetching document colors")
 6659                    .map_err(Arc::new);
 6660                let fetched_colors = match fetched_colors {
 6661                    Ok(fetched_colors) => {
 6662                        if fetch_strategy != LspFetchStrategy::IgnoreCache
 6663                            && Some(true)
 6664                                == buffer
 6665                                    .update(cx, |buffer, _| {
 6666                                        buffer.version() != query_version_queried_for
 6667                                    })
 6668                                    .ok()
 6669                        {
 6670                            return Ok(DocumentColors::default());
 6671                        }
 6672                        fetched_colors
 6673                    }
 6674                    Err(e) => {
 6675                        lsp_store
 6676                            .update(cx, |lsp_store, _| {
 6677                                lsp_store
 6678                                    .lsp_document_colors
 6679                                    .entry(buffer_id)
 6680                                    .or_default()
 6681                                    .colors_update = None;
 6682                            })
 6683                            .ok();
 6684                        return Err(e);
 6685                    }
 6686                };
 6687
 6688                lsp_store
 6689                    .update(cx, |lsp_store, _| {
 6690                        let lsp_data = lsp_store.lsp_document_colors.entry(buffer_id).or_default();
 6691
 6692                        if let Some(fetched_colors) = fetched_colors {
 6693                            if lsp_data.colors_for_version == query_version_queried_for {
 6694                                lsp_data.colors.extend(fetched_colors);
 6695                                lsp_data.cache_version += 1;
 6696                            } else if !lsp_data
 6697                                .colors_for_version
 6698                                .changed_since(&query_version_queried_for)
 6699                            {
 6700                                lsp_data.colors_for_version = query_version_queried_for;
 6701                                lsp_data.colors = fetched_colors;
 6702                                lsp_data.cache_version += 1;
 6703                            }
 6704                        }
 6705                        lsp_data.colors_update = None;
 6706                        let colors = lsp_data
 6707                            .colors
 6708                            .values()
 6709                            .flatten()
 6710                            .cloned()
 6711                            .collect::<HashSet<_>>();
 6712                        DocumentColors {
 6713                            colors,
 6714                            cache_version: Some(lsp_data.cache_version),
 6715                        }
 6716                    })
 6717                    .map_err(Arc::new)
 6718            })
 6719            .shared();
 6720        lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 6721        Some(new_task)
 6722    }
 6723
 6724    fn fetch_document_colors_for_buffer(
 6725        &mut self,
 6726        buffer: &Entity<Buffer>,
 6727        cx: &mut Context<Self>,
 6728    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 6729        if let Some((client, project_id)) = self.upstream_client() {
 6730            let request = GetDocumentColor {};
 6731            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6732                return Task::ready(Ok(None));
 6733            }
 6734
 6735            let request_task = client.request_lsp(
 6736                project_id,
 6737                LSP_REQUEST_TIMEOUT,
 6738                cx.background_executor().clone(),
 6739                request.to_proto(project_id, buffer.read(cx)),
 6740            );
 6741            let buffer = buffer.clone();
 6742            cx.spawn(async move |lsp_store, cx| {
 6743                let Some(project) = lsp_store.upgrade() else {
 6744                    return Ok(None);
 6745                };
 6746                let colors = join_all(
 6747                    request_task
 6748                        .await
 6749                        .log_err()
 6750                        .flatten()
 6751                        .map(|response| response.payload)
 6752                        .unwrap_or_default()
 6753                        .into_iter()
 6754                        .map(|color_response| {
 6755                            let response = request.response_from_proto(
 6756                                color_response.response,
 6757                                project.clone(),
 6758                                buffer.clone(),
 6759                                cx.clone(),
 6760                            );
 6761                            async move {
 6762                                (
 6763                                    LanguageServerId::from_proto(color_response.server_id),
 6764                                    response.await.log_err().unwrap_or_default(),
 6765                                )
 6766                            }
 6767                        }),
 6768                )
 6769                .await
 6770                .into_iter()
 6771                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 6772                    acc.entry(server_id)
 6773                        .or_insert_with(HashSet::default)
 6774                        .extend(colors);
 6775                    acc
 6776                });
 6777                Ok(Some(colors))
 6778            })
 6779        } else {
 6780            let document_colors_task =
 6781                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 6782            cx.background_spawn(async move {
 6783                Ok(Some(
 6784                    document_colors_task
 6785                        .await
 6786                        .into_iter()
 6787                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 6788                            acc.entry(server_id)
 6789                                .or_insert_with(HashSet::default)
 6790                                .extend(colors);
 6791                            acc
 6792                        })
 6793                        .into_iter()
 6794                        .collect(),
 6795                ))
 6796            })
 6797        }
 6798    }
 6799
 6800    pub fn signature_help<T: ToPointUtf16>(
 6801        &mut self,
 6802        buffer: &Entity<Buffer>,
 6803        position: T,
 6804        cx: &mut Context<Self>,
 6805    ) -> Task<Option<Vec<SignatureHelp>>> {
 6806        let position = position.to_point_utf16(buffer.read(cx));
 6807
 6808        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6809            let request = GetSignatureHelp { position };
 6810            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6811                return Task::ready(None);
 6812            }
 6813            let request_task = client.request_lsp(
 6814                upstream_project_id,
 6815                LSP_REQUEST_TIMEOUT,
 6816                cx.background_executor().clone(),
 6817                request.to_proto(upstream_project_id, buffer.read(cx)),
 6818            );
 6819            let buffer = buffer.clone();
 6820            cx.spawn(async move |weak_project, cx| {
 6821                let project = weak_project.upgrade()?;
 6822                let signatures = join_all(
 6823                    request_task
 6824                        .await
 6825                        .log_err()
 6826                        .flatten()
 6827                        .map(|response| response.payload)
 6828                        .unwrap_or_default()
 6829                        .into_iter()
 6830                        .map(|response| {
 6831                            let response = GetSignatureHelp { position }.response_from_proto(
 6832                                response.response,
 6833                                project.clone(),
 6834                                buffer.clone(),
 6835                                cx.clone(),
 6836                            );
 6837                            async move { response.await.log_err().flatten() }
 6838                        }),
 6839                )
 6840                .await
 6841                .into_iter()
 6842                .flatten()
 6843                .collect();
 6844                Some(signatures)
 6845            })
 6846        } else {
 6847            let all_actions_task = self.request_multiple_lsp_locally(
 6848                buffer,
 6849                Some(position),
 6850                GetSignatureHelp { position },
 6851                cx,
 6852            );
 6853            cx.background_spawn(async move {
 6854                Some(
 6855                    all_actions_task
 6856                        .await
 6857                        .into_iter()
 6858                        .flat_map(|(_, actions)| actions)
 6859                        .collect::<Vec<_>>(),
 6860                )
 6861            })
 6862        }
 6863    }
 6864
 6865    pub fn hover(
 6866        &mut self,
 6867        buffer: &Entity<Buffer>,
 6868        position: PointUtf16,
 6869        cx: &mut Context<Self>,
 6870    ) -> Task<Option<Vec<Hover>>> {
 6871        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6872            let request = GetHover { position };
 6873            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6874                return Task::ready(None);
 6875            }
 6876            let request_task = client.request_lsp(
 6877                upstream_project_id,
 6878                LSP_REQUEST_TIMEOUT,
 6879                cx.background_executor().clone(),
 6880                request.to_proto(upstream_project_id, buffer.read(cx)),
 6881            );
 6882            let buffer = buffer.clone();
 6883            cx.spawn(async move |weak_project, cx| {
 6884                let project = weak_project.upgrade()?;
 6885                let hovers = join_all(
 6886                    request_task
 6887                        .await
 6888                        .log_err()
 6889                        .flatten()
 6890                        .map(|response| response.payload)
 6891                        .unwrap_or_default()
 6892                        .into_iter()
 6893                        .map(|response| {
 6894                            let response = GetHover { position }.response_from_proto(
 6895                                response.response,
 6896                                project.clone(),
 6897                                buffer.clone(),
 6898                                cx.clone(),
 6899                            );
 6900                            async move {
 6901                                response
 6902                                    .await
 6903                                    .log_err()
 6904                                    .flatten()
 6905                                    .and_then(remove_empty_hover_blocks)
 6906                            }
 6907                        }),
 6908                )
 6909                .await
 6910                .into_iter()
 6911                .flatten()
 6912                .collect();
 6913                Some(hovers)
 6914            })
 6915        } else {
 6916            let all_actions_task = self.request_multiple_lsp_locally(
 6917                buffer,
 6918                Some(position),
 6919                GetHover { position },
 6920                cx,
 6921            );
 6922            cx.background_spawn(async move {
 6923                Some(
 6924                    all_actions_task
 6925                        .await
 6926                        .into_iter()
 6927                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 6928                        .collect::<Vec<Hover>>(),
 6929                )
 6930            })
 6931        }
 6932    }
 6933
 6934    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 6935        let language_registry = self.languages.clone();
 6936
 6937        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 6938            let request = upstream_client.request(proto::GetProjectSymbols {
 6939                project_id: *project_id,
 6940                query: query.to_string(),
 6941            });
 6942            cx.foreground_executor().spawn(async move {
 6943                let response = request.await?;
 6944                let mut symbols = Vec::new();
 6945                let core_symbols = response
 6946                    .symbols
 6947                    .into_iter()
 6948                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 6949                    .collect::<Vec<_>>();
 6950                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 6951                    .await;
 6952                Ok(symbols)
 6953            })
 6954        } else if let Some(local) = self.as_local() {
 6955            struct WorkspaceSymbolsResult {
 6956                server_id: LanguageServerId,
 6957                lsp_adapter: Arc<CachedLspAdapter>,
 6958                worktree: WeakEntity<Worktree>,
 6959                worktree_abs_path: Arc<Path>,
 6960                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 6961            }
 6962
 6963            let mut requests = Vec::new();
 6964            let mut requested_servers = BTreeSet::new();
 6965            for (seed, state) in local.language_server_ids.iter() {
 6966                let Some(worktree_handle) = self
 6967                    .worktree_store
 6968                    .read(cx)
 6969                    .worktree_for_id(seed.worktree_id, cx)
 6970                else {
 6971                    continue;
 6972                };
 6973                let worktree = worktree_handle.read(cx);
 6974                if !worktree.is_visible() {
 6975                    continue;
 6976                }
 6977
 6978                if !requested_servers.insert(state.id) {
 6979                    continue;
 6980                }
 6981
 6982                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 6983                    Some(LanguageServerState::Running {
 6984                        adapter, server, ..
 6985                    }) => (adapter.clone(), server),
 6986
 6987                    _ => continue,
 6988                };
 6989                let supports_workspace_symbol_request =
 6990                    match server.capabilities().workspace_symbol_provider {
 6991                        Some(OneOf::Left(supported)) => supported,
 6992                        Some(OneOf::Right(_)) => true,
 6993                        None => false,
 6994                    };
 6995                if !supports_workspace_symbol_request {
 6996                    continue;
 6997                }
 6998                let worktree_abs_path = worktree.abs_path().clone();
 6999                let worktree_handle = worktree_handle.clone();
 7000                let server_id = server.server_id();
 7001                requests.push(
 7002                        server
 7003                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7004                                lsp::WorkspaceSymbolParams {
 7005                                    query: query.to_string(),
 7006                                    ..Default::default()
 7007                                },
 7008                            )
 7009                            .map(move |response| {
 7010                                let lsp_symbols = response.into_response()
 7011                                    .context("workspace symbols request")
 7012                                    .log_err()
 7013                                    .flatten()
 7014                                    .map(|symbol_response| match symbol_response {
 7015                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7016                                            flat_responses.into_iter().map(|lsp_symbol| {
 7017                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7018                                            }).collect::<Vec<_>>()
 7019                                        }
 7020                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7021                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7022                                                let location = match lsp_symbol.location {
 7023                                                    OneOf::Left(location) => location,
 7024                                                    OneOf::Right(_) => {
 7025                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7026                                                        return None
 7027                                                    }
 7028                                                };
 7029                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7030                                            }).collect::<Vec<_>>()
 7031                                        }
 7032                                    }).unwrap_or_default();
 7033
 7034                                WorkspaceSymbolsResult {
 7035                                    server_id,
 7036                                    lsp_adapter,
 7037                                    worktree: worktree_handle.downgrade(),
 7038                                    worktree_abs_path,
 7039                                    lsp_symbols,
 7040                                }
 7041                            }),
 7042                    );
 7043            }
 7044
 7045            cx.spawn(async move |this, cx| {
 7046                let responses = futures::future::join_all(requests).await;
 7047                let this = match this.upgrade() {
 7048                    Some(this) => this,
 7049                    None => return Ok(Vec::new()),
 7050                };
 7051
 7052                let mut symbols = Vec::new();
 7053                for result in responses {
 7054                    let core_symbols = this.update(cx, |this, cx| {
 7055                        result
 7056                            .lsp_symbols
 7057                            .into_iter()
 7058                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7059                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7060                                let source_worktree = result.worktree.upgrade()?;
 7061                                let source_worktree_id = source_worktree.read(cx).id();
 7062
 7063                                let path;
 7064                                let worktree;
 7065                                if let Some((tree, rel_path)) =
 7066                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7067                                {
 7068                                    worktree = tree;
 7069                                    path = rel_path;
 7070                                } else {
 7071                                    worktree = source_worktree;
 7072                                    path = relativize_path(&result.worktree_abs_path, &abs_path);
 7073                                }
 7074
 7075                                let worktree_id = worktree.read(cx).id();
 7076                                let project_path = ProjectPath {
 7077                                    worktree_id,
 7078                                    path: path.into(),
 7079                                };
 7080                                let signature = this.symbol_signature(&project_path);
 7081                                Some(CoreSymbol {
 7082                                    source_language_server_id: result.server_id,
 7083                                    language_server_name: result.lsp_adapter.name.clone(),
 7084                                    source_worktree_id,
 7085                                    path: project_path,
 7086                                    kind: symbol_kind,
 7087                                    name: symbol_name,
 7088                                    range: range_from_lsp(symbol_location.range),
 7089                                    signature,
 7090                                })
 7091                            })
 7092                            .collect()
 7093                    })?;
 7094
 7095                    populate_labels_for_symbols(
 7096                        core_symbols,
 7097                        &language_registry,
 7098                        Some(result.lsp_adapter),
 7099                        &mut symbols,
 7100                    )
 7101                    .await;
 7102                }
 7103
 7104                Ok(symbols)
 7105            })
 7106        } else {
 7107            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7108        }
 7109    }
 7110
 7111    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7112        let mut summary = DiagnosticSummary::default();
 7113        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7114            summary.error_count += path_summary.error_count;
 7115            summary.warning_count += path_summary.warning_count;
 7116        }
 7117        summary
 7118    }
 7119
 7120    pub fn diagnostic_summaries<'a>(
 7121        &'a self,
 7122        include_ignored: bool,
 7123        cx: &'a App,
 7124    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7125        self.worktree_store
 7126            .read(cx)
 7127            .visible_worktrees(cx)
 7128            .filter_map(|worktree| {
 7129                let worktree = worktree.read(cx);
 7130                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7131            })
 7132            .flat_map(move |(worktree, summaries)| {
 7133                let worktree_id = worktree.id();
 7134                summaries
 7135                    .iter()
 7136                    .filter(move |(path, _)| {
 7137                        include_ignored
 7138                            || worktree
 7139                                .entry_for_path(path.as_ref())
 7140                                .is_some_and(|entry| !entry.is_ignored)
 7141                    })
 7142                    .flat_map(move |(path, summaries)| {
 7143                        summaries.iter().map(move |(server_id, summary)| {
 7144                            (
 7145                                ProjectPath {
 7146                                    worktree_id,
 7147                                    path: path.clone(),
 7148                                },
 7149                                *server_id,
 7150                                *summary,
 7151                            )
 7152                        })
 7153                    })
 7154            })
 7155    }
 7156
 7157    pub fn on_buffer_edited(
 7158        &mut self,
 7159        buffer: Entity<Buffer>,
 7160        cx: &mut Context<Self>,
 7161    ) -> Option<()> {
 7162        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7163            Some(
 7164                self.as_local()?
 7165                    .language_servers_for_buffer(buffer, cx)
 7166                    .map(|i| i.1.clone())
 7167                    .collect(),
 7168            )
 7169        })?;
 7170
 7171        let buffer = buffer.read(cx);
 7172        let file = File::from_dyn(buffer.file())?;
 7173        let abs_path = file.as_local()?.abs_path(cx);
 7174        let uri = lsp::Url::from_file_path(abs_path).unwrap();
 7175        let next_snapshot = buffer.text_snapshot();
 7176        for language_server in language_servers {
 7177            let language_server = language_server.clone();
 7178
 7179            let buffer_snapshots = self
 7180                .as_local_mut()
 7181                .unwrap()
 7182                .buffer_snapshots
 7183                .get_mut(&buffer.remote_id())
 7184                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7185            let previous_snapshot = buffer_snapshots.last()?;
 7186
 7187            let build_incremental_change = || {
 7188                buffer
 7189                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7190                        previous_snapshot.snapshot.version(),
 7191                    )
 7192                    .map(|edit| {
 7193                        let edit_start = edit.new.start.0;
 7194                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7195                        let new_text = next_snapshot
 7196                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7197                            .collect();
 7198                        lsp::TextDocumentContentChangeEvent {
 7199                            range: Some(lsp::Range::new(
 7200                                point_to_lsp(edit_start),
 7201                                point_to_lsp(edit_end),
 7202                            )),
 7203                            range_length: None,
 7204                            text: new_text,
 7205                        }
 7206                    })
 7207                    .collect()
 7208            };
 7209
 7210            let document_sync_kind =
 7211                language_server.effective_capability::<lsp::cap::DidChangeTextDocument>();
 7212
 7213            let content_changes: Vec<_> = match document_sync_kind {
 7214                Some(lsp::TextDocumentSyncKind::FULL) => {
 7215                    vec![lsp::TextDocumentContentChangeEvent {
 7216                        range: None,
 7217                        range_length: None,
 7218                        text: next_snapshot.text(),
 7219                    }]
 7220                }
 7221                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7222                _ => {
 7223                    #[cfg(any(test, feature = "test-support"))]
 7224                    {
 7225                        build_incremental_change()
 7226                    }
 7227
 7228                    #[cfg(not(any(test, feature = "test-support")))]
 7229                    {
 7230                        continue;
 7231                    }
 7232                }
 7233            };
 7234
 7235            let next_version = previous_snapshot.version + 1;
 7236            buffer_snapshots.push(LspBufferSnapshot {
 7237                version: next_version,
 7238                snapshot: next_snapshot.clone(),
 7239            });
 7240
 7241            language_server
 7242                .notify::<lsp::notification::DidChangeTextDocument>(
 7243                    &lsp::DidChangeTextDocumentParams {
 7244                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7245                            uri.clone(),
 7246                            next_version,
 7247                        ),
 7248                        content_changes,
 7249                    },
 7250                )
 7251                .ok();
 7252            self.pull_workspace_diagnostics(language_server.server_id());
 7253        }
 7254
 7255        None
 7256    }
 7257
 7258    pub fn on_buffer_saved(
 7259        &mut self,
 7260        buffer: Entity<Buffer>,
 7261        cx: &mut Context<Self>,
 7262    ) -> Option<()> {
 7263        let file = File::from_dyn(buffer.read(cx).file())?;
 7264        let worktree_id = file.worktree_id(cx);
 7265        let abs_path = file.as_local()?.abs_path(cx);
 7266        let text_document = lsp::TextDocumentIdentifier {
 7267            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7268        };
 7269        let local = self.as_local()?;
 7270
 7271        for server in local.language_servers_for_worktree(worktree_id) {
 7272            if let Some(include_text) =
 7273                server.effective_capability::<lsp::cap::DidSaveTextDocument>()
 7274            {
 7275                let text = if include_text {
 7276                    Some(buffer.read(cx).text())
 7277                } else {
 7278                    None
 7279                };
 7280                server
 7281                    .notify::<lsp::notification::DidSaveTextDocument>(
 7282                        &lsp::DidSaveTextDocumentParams {
 7283                            text_document: text_document.clone(),
 7284                            text,
 7285                        },
 7286                    )
 7287                    .ok();
 7288            }
 7289        }
 7290
 7291        let language_servers = buffer.update(cx, |buffer, cx| {
 7292            local.language_server_ids_for_buffer(buffer, cx)
 7293        });
 7294        for language_server_id in language_servers {
 7295            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7296        }
 7297
 7298        None
 7299    }
 7300
 7301    async fn refresh_workspace_configurations(
 7302        lsp_store: &WeakEntity<Self>,
 7303        fs: Arc<dyn Fs>,
 7304        cx: &mut AsyncApp,
 7305    ) {
 7306        maybe!(async move {
 7307            let mut refreshed_servers = HashSet::default();
 7308            let servers = lsp_store
 7309                .update(cx, |lsp_store, cx| {
 7310                    let local = lsp_store.as_local()?;
 7311
 7312                    let servers = local
 7313                        .language_server_ids
 7314                        .iter()
 7315                        .filter_map(|(seed, state)| {
 7316                            let worktree = lsp_store
 7317                                .worktree_store
 7318                                .read(cx)
 7319                                .worktree_for_id(seed.worktree_id, cx);
 7320                            let delegate: Arc<dyn LspAdapterDelegate> =
 7321                                worktree.map(|worktree| {
 7322                                    LocalLspAdapterDelegate::new(
 7323                                        local.languages.clone(),
 7324                                        &local.environment,
 7325                                        cx.weak_entity(),
 7326                                        &worktree,
 7327                                        local.http_client.clone(),
 7328                                        local.fs.clone(),
 7329                                        cx,
 7330                                    )
 7331                                })?;
 7332                            let server_id = state.id;
 7333
 7334                            let states = local.language_servers.get(&server_id)?;
 7335
 7336                            match states {
 7337                                LanguageServerState::Starting { .. } => None,
 7338                                LanguageServerState::Running {
 7339                                    adapter, server, ..
 7340                                } => {
 7341                                    let fs = fs.clone();
 7342
 7343                                    let adapter = adapter.clone();
 7344                                    let server = server.clone();
 7345                                    refreshed_servers.insert(server.name());
 7346                                    let toolchain = seed.toolchain.clone();
 7347                                    Some(cx.spawn(async move |_, cx| {
 7348                                        let settings =
 7349                                            LocalLspStore::workspace_configuration_for_adapter(
 7350                                                adapter.adapter.clone(),
 7351                                                fs.as_ref(),
 7352                                                &delegate,
 7353                                                toolchain,
 7354                                                cx,
 7355                                            )
 7356                                            .await
 7357                                            .ok()?;
 7358                                        server
 7359                                            .notify::<lsp::notification::DidChangeConfiguration>(
 7360                                                &lsp::DidChangeConfigurationParams { settings },
 7361                                            )
 7362                                            .ok()?;
 7363                                        Some(())
 7364                                    }))
 7365                                }
 7366                            }
 7367                        })
 7368                        .collect::<Vec<_>>();
 7369
 7370                    Some(servers)
 7371                })
 7372                .ok()
 7373                .flatten()?;
 7374
 7375            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 7376            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 7377            // to stop and unregister its language server wrapper.
 7378            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 7379            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 7380            let _: Vec<Option<()>> = join_all(servers).await;
 7381
 7382            Some(())
 7383        })
 7384        .await;
 7385    }
 7386
 7387    fn maintain_workspace_config(
 7388        fs: Arc<dyn Fs>,
 7389        external_refresh_requests: watch::Receiver<()>,
 7390        cx: &mut Context<Self>,
 7391    ) -> Task<Result<()>> {
 7392        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 7393        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 7394
 7395        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 7396            *settings_changed_tx.borrow_mut() = ();
 7397        });
 7398
 7399        let mut joint_future =
 7400            futures::stream::select(settings_changed_rx, external_refresh_requests);
 7401        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 7402        // - We might shut down a language server if it's no longer enabled for a given language (and there are no buffers using it otherwise).
 7403        // - We might also shut it down when the workspace configuration of all of the users of a given language server converges onto that of the other.
 7404        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 7405        // - In the easiest case (where we're not wrangling the lifetime of a language server anyhow), if none of the roots of a single language server diverge in their configuration,
 7406        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 7407        cx.spawn(async move |this, cx| {
 7408            while let Some(()) = joint_future.next().await {
 7409                this.update(cx, |this, cx| {
 7410                    this.refresh_server_tree(cx);
 7411                })
 7412                .ok();
 7413
 7414                Self::refresh_workspace_configurations(&this, fs.clone(), cx).await;
 7415            }
 7416
 7417            drop(settings_observation);
 7418            anyhow::Ok(())
 7419        })
 7420    }
 7421
 7422    pub fn language_servers_for_local_buffer<'a>(
 7423        &'a self,
 7424        buffer: &Buffer,
 7425        cx: &mut App,
 7426    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7427        let local = self.as_local();
 7428        let language_server_ids = local
 7429            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 7430            .unwrap_or_default();
 7431
 7432        language_server_ids
 7433            .into_iter()
 7434            .filter_map(
 7435                move |server_id| match local?.language_servers.get(&server_id)? {
 7436                    LanguageServerState::Running {
 7437                        adapter, server, ..
 7438                    } => Some((adapter, server)),
 7439                    _ => None,
 7440                },
 7441            )
 7442    }
 7443
 7444    pub fn language_server_for_local_buffer<'a>(
 7445        &'a self,
 7446        buffer: &'a Buffer,
 7447        server_id: LanguageServerId,
 7448        cx: &'a mut App,
 7449    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7450        self.as_local()?
 7451            .language_servers_for_buffer(buffer, cx)
 7452            .find(|(_, s)| s.server_id() == server_id)
 7453    }
 7454
 7455    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 7456        self.diagnostic_summaries.remove(&id_to_remove);
 7457        if let Some(local) = self.as_local_mut() {
 7458            let to_remove = local.remove_worktree(id_to_remove, cx);
 7459            for server in to_remove {
 7460                self.language_server_statuses.remove(&server);
 7461            }
 7462        }
 7463    }
 7464
 7465    pub fn shared(
 7466        &mut self,
 7467        project_id: u64,
 7468        downstream_client: AnyProtoClient,
 7469        _: &mut Context<Self>,
 7470    ) {
 7471        self.downstream_client = Some((downstream_client.clone(), project_id));
 7472
 7473        for (server_id, status) in &self.language_server_statuses {
 7474            if let Some(server) = self.language_server_for_id(*server_id) {
 7475                downstream_client
 7476                    .send(proto::StartLanguageServer {
 7477                        project_id,
 7478                        server: Some(proto::LanguageServer {
 7479                            id: server_id.to_proto(),
 7480                            name: status.name.to_string(),
 7481                            worktree_id: None,
 7482                        }),
 7483                        capabilities: serde_json::to_string(&server.capabilities())
 7484                            .expect("serializing server LSP capabilities"),
 7485                    })
 7486                    .log_err();
 7487            }
 7488        }
 7489    }
 7490
 7491    pub fn disconnected_from_host(&mut self) {
 7492        self.downstream_client.take();
 7493    }
 7494
 7495    pub fn disconnected_from_ssh_remote(&mut self) {
 7496        if let LspStoreMode::Remote(RemoteLspStore {
 7497            upstream_client, ..
 7498        }) = &mut self.mode
 7499        {
 7500            upstream_client.take();
 7501        }
 7502    }
 7503
 7504    pub(crate) fn set_language_server_statuses_from_proto(
 7505        &mut self,
 7506        language_servers: Vec<proto::LanguageServer>,
 7507        server_capabilities: Vec<String>,
 7508    ) {
 7509        self.language_server_statuses = language_servers
 7510            .into_iter()
 7511            .zip(server_capabilities)
 7512            .map(|(server, server_capabilities)| {
 7513                let server_id = LanguageServerId(server.id as usize);
 7514                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 7515                    self.lsp_server_capabilities
 7516                        .insert(server_id, server_capabilities);
 7517                }
 7518                (
 7519                    server_id,
 7520                    LanguageServerStatus {
 7521                        name: LanguageServerName::from_proto(server.name),
 7522                        pending_work: Default::default(),
 7523                        has_pending_diagnostic_updates: false,
 7524                        progress_tokens: Default::default(),
 7525                    },
 7526                )
 7527            })
 7528            .collect();
 7529    }
 7530
 7531    #[cfg(test)]
 7532    pub fn update_diagnostic_entries(
 7533        &mut self,
 7534        server_id: LanguageServerId,
 7535        abs_path: PathBuf,
 7536        result_id: Option<String>,
 7537        version: Option<i32>,
 7538        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 7539        cx: &mut Context<Self>,
 7540    ) -> anyhow::Result<()> {
 7541        self.merge_diagnostic_entries(
 7542            vec![DocumentDiagnosticsUpdate {
 7543                diagnostics: DocumentDiagnostics {
 7544                    diagnostics,
 7545                    document_abs_path: abs_path,
 7546                    version,
 7547                },
 7548                result_id,
 7549                server_id,
 7550                disk_based_sources: Cow::Borrowed(&[]),
 7551            }],
 7552            |_, _, _| false,
 7553            cx,
 7554        )?;
 7555        Ok(())
 7556    }
 7557
 7558    pub fn merge_diagnostic_entries<'a>(
 7559        &mut self,
 7560        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 7561        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
 7562        cx: &mut Context<Self>,
 7563    ) -> anyhow::Result<()> {
 7564        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 7565        let mut updated_diagnostics_paths = HashMap::default();
 7566        for mut update in diagnostic_updates {
 7567            let abs_path = &update.diagnostics.document_abs_path;
 7568            let server_id = update.server_id;
 7569            let Some((worktree, relative_path)) =
 7570                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 7571            else {
 7572                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 7573                return Ok(());
 7574            };
 7575
 7576            let worktree_id = worktree.read(cx).id();
 7577            let project_path = ProjectPath {
 7578                worktree_id,
 7579                path: relative_path.into(),
 7580            };
 7581
 7582            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 7583                let snapshot = buffer_handle.read(cx).snapshot();
 7584                let buffer = buffer_handle.read(cx);
 7585                let reused_diagnostics = buffer
 7586                    .get_diagnostics(server_id)
 7587                    .into_iter()
 7588                    .flat_map(|diag| {
 7589                        diag.iter()
 7590                            .filter(|v| merge(buffer, &v.diagnostic, cx))
 7591                            .map(|v| {
 7592                                let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 7593                                let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 7594                                DiagnosticEntry {
 7595                                    range: start..end,
 7596                                    diagnostic: v.diagnostic.clone(),
 7597                                }
 7598                            })
 7599                    })
 7600                    .collect::<Vec<_>>();
 7601
 7602                self.as_local_mut()
 7603                    .context("cannot merge diagnostics on a remote LspStore")?
 7604                    .update_buffer_diagnostics(
 7605                        &buffer_handle,
 7606                        server_id,
 7607                        update.result_id,
 7608                        update.diagnostics.version,
 7609                        update.diagnostics.diagnostics.clone(),
 7610                        reused_diagnostics.clone(),
 7611                        cx,
 7612                    )?;
 7613
 7614                update.diagnostics.diagnostics.extend(reused_diagnostics);
 7615            }
 7616
 7617            let updated = worktree.update(cx, |worktree, cx| {
 7618                self.update_worktree_diagnostics(
 7619                    worktree.id(),
 7620                    server_id,
 7621                    project_path.path.clone(),
 7622                    update.diagnostics.diagnostics,
 7623                    cx,
 7624                )
 7625            })?;
 7626            match updated {
 7627                ControlFlow::Continue(new_summary) => {
 7628                    if let Some((project_id, new_summary)) = new_summary {
 7629                        match &mut diagnostics_summary {
 7630                            Some(diagnostics_summary) => {
 7631                                diagnostics_summary
 7632                                    .more_summaries
 7633                                    .push(proto::DiagnosticSummary {
 7634                                        path: project_path.path.as_ref().to_proto(),
 7635                                        language_server_id: server_id.0 as u64,
 7636                                        error_count: new_summary.error_count,
 7637                                        warning_count: new_summary.warning_count,
 7638                                    })
 7639                            }
 7640                            None => {
 7641                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 7642                                    project_id,
 7643                                    worktree_id: worktree_id.to_proto(),
 7644                                    summary: Some(proto::DiagnosticSummary {
 7645                                        path: project_path.path.as_ref().to_proto(),
 7646                                        language_server_id: server_id.0 as u64,
 7647                                        error_count: new_summary.error_count,
 7648                                        warning_count: new_summary.warning_count,
 7649                                    }),
 7650                                    more_summaries: Vec::new(),
 7651                                })
 7652                            }
 7653                        }
 7654                    }
 7655                    updated_diagnostics_paths
 7656                        .entry(server_id)
 7657                        .or_insert_with(Vec::new)
 7658                        .push(project_path);
 7659                }
 7660                ControlFlow::Break(()) => {}
 7661            }
 7662        }
 7663
 7664        if let Some((diagnostics_summary, (downstream_client, _))) =
 7665            diagnostics_summary.zip(self.downstream_client.as_ref())
 7666        {
 7667            downstream_client.send(diagnostics_summary).log_err();
 7668        }
 7669        for (server_id, paths) in updated_diagnostics_paths {
 7670            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 7671        }
 7672        Ok(())
 7673    }
 7674
 7675    fn update_worktree_diagnostics(
 7676        &mut self,
 7677        worktree_id: WorktreeId,
 7678        server_id: LanguageServerId,
 7679        path_in_worktree: Arc<Path>,
 7680        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 7681        _: &mut Context<Worktree>,
 7682    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 7683        let local = match &mut self.mode {
 7684            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 7685            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 7686        };
 7687
 7688        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 7689        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 7690        let summaries_by_server_id = summaries_for_tree
 7691            .entry(path_in_worktree.clone())
 7692            .or_default();
 7693
 7694        let old_summary = summaries_by_server_id
 7695            .remove(&server_id)
 7696            .unwrap_or_default();
 7697
 7698        let new_summary = DiagnosticSummary::new(&diagnostics);
 7699        if new_summary.is_empty() {
 7700            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 7701            {
 7702                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 7703                    diagnostics_by_server_id.remove(ix);
 7704                }
 7705                if diagnostics_by_server_id.is_empty() {
 7706                    diagnostics_for_tree.remove(&path_in_worktree);
 7707                }
 7708            }
 7709        } else {
 7710            summaries_by_server_id.insert(server_id, new_summary);
 7711            let diagnostics_by_server_id = diagnostics_for_tree
 7712                .entry(path_in_worktree.clone())
 7713                .or_default();
 7714            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 7715                Ok(ix) => {
 7716                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 7717                }
 7718                Err(ix) => {
 7719                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 7720                }
 7721            }
 7722        }
 7723
 7724        if !old_summary.is_empty() || !new_summary.is_empty() {
 7725            if let Some((_, project_id)) = &self.downstream_client {
 7726                Ok(ControlFlow::Continue(Some((
 7727                    *project_id,
 7728                    proto::DiagnosticSummary {
 7729                        path: path_in_worktree.to_proto(),
 7730                        language_server_id: server_id.0 as u64,
 7731                        error_count: new_summary.error_count as u32,
 7732                        warning_count: new_summary.warning_count as u32,
 7733                    },
 7734                ))))
 7735            } else {
 7736                Ok(ControlFlow::Continue(None))
 7737            }
 7738        } else {
 7739            Ok(ControlFlow::Break(()))
 7740        }
 7741    }
 7742
 7743    pub fn open_buffer_for_symbol(
 7744        &mut self,
 7745        symbol: &Symbol,
 7746        cx: &mut Context<Self>,
 7747    ) -> Task<Result<Entity<Buffer>>> {
 7748        if let Some((client, project_id)) = self.upstream_client() {
 7749            let request = client.request(proto::OpenBufferForSymbol {
 7750                project_id,
 7751                symbol: Some(Self::serialize_symbol(symbol)),
 7752            });
 7753            cx.spawn(async move |this, cx| {
 7754                let response = request.await?;
 7755                let buffer_id = BufferId::new(response.buffer_id)?;
 7756                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 7757                    .await
 7758            })
 7759        } else if let Some(local) = self.as_local() {
 7760            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 7761                seed.worktree_id == symbol.source_worktree_id
 7762                    && state.id == symbol.source_language_server_id
 7763                    && symbol.language_server_name == seed.name
 7764            });
 7765            if !is_valid {
 7766                return Task::ready(Err(anyhow!(
 7767                    "language server for worktree and language not found"
 7768                )));
 7769            };
 7770
 7771            let worktree_abs_path = if let Some(worktree_abs_path) = self
 7772                .worktree_store
 7773                .read(cx)
 7774                .worktree_for_id(symbol.path.worktree_id, cx)
 7775                .map(|worktree| worktree.read(cx).abs_path())
 7776            {
 7777                worktree_abs_path
 7778            } else {
 7779                return Task::ready(Err(anyhow!("worktree not found for symbol")));
 7780            };
 7781
 7782            let symbol_abs_path = resolve_path(&worktree_abs_path, &symbol.path.path);
 7783            let symbol_uri = if let Ok(uri) = lsp::Url::from_file_path(symbol_abs_path) {
 7784                uri
 7785            } else {
 7786                return Task::ready(Err(anyhow!("invalid symbol path")));
 7787            };
 7788
 7789            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 7790        } else {
 7791            Task::ready(Err(anyhow!("no upstream client or local store")))
 7792        }
 7793    }
 7794
 7795    pub(crate) fn open_local_buffer_via_lsp(
 7796        &mut self,
 7797        mut abs_path: lsp::Url,
 7798        language_server_id: LanguageServerId,
 7799        cx: &mut Context<Self>,
 7800    ) -> Task<Result<Entity<Buffer>>> {
 7801        cx.spawn(async move |lsp_store, cx| {
 7802            // Escape percent-encoded string.
 7803            let current_scheme = abs_path.scheme().to_owned();
 7804            let _ = abs_path.set_scheme("file");
 7805
 7806            let abs_path = abs_path
 7807                .to_file_path()
 7808                .map_err(|()| anyhow!("can't convert URI to path"))?;
 7809            let p = abs_path.clone();
 7810            let yarn_worktree = lsp_store
 7811                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 7812                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 7813                        cx.spawn(async move |this, cx| {
 7814                            let t = this
 7815                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 7816                                .ok()?;
 7817                            t.await
 7818                        })
 7819                    }),
 7820                    None => Task::ready(None),
 7821                })?
 7822                .await;
 7823            let (worktree_root_target, known_relative_path) =
 7824                if let Some((zip_root, relative_path)) = yarn_worktree {
 7825                    (zip_root, Some(relative_path))
 7826                } else {
 7827                    (Arc::<Path>::from(abs_path.as_path()), None)
 7828                };
 7829            let (worktree, relative_path) = if let Some(result) =
 7830                lsp_store.update(cx, |lsp_store, cx| {
 7831                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 7832                        worktree_store.find_worktree(&worktree_root_target, cx)
 7833                    })
 7834                })? {
 7835                let relative_path =
 7836                    known_relative_path.unwrap_or_else(|| Arc::<Path>::from(result.1));
 7837                (result.0, relative_path)
 7838            } else {
 7839                let worktree = lsp_store
 7840                    .update(cx, |lsp_store, cx| {
 7841                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 7842                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 7843                        })
 7844                    })?
 7845                    .await?;
 7846                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 7847                    lsp_store
 7848                        .update(cx, |lsp_store, cx| {
 7849                            if let Some(local) = lsp_store.as_local_mut() {
 7850                                local.register_language_server_for_invisible_worktree(
 7851                                    &worktree,
 7852                                    language_server_id,
 7853                                    cx,
 7854                                )
 7855                            }
 7856                        })
 7857                        .ok();
 7858                }
 7859                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 7860                let relative_path = if let Some(known_path) = known_relative_path {
 7861                    known_path
 7862                } else {
 7863                    abs_path.strip_prefix(worktree_root)?.into()
 7864                };
 7865                (worktree, relative_path)
 7866            };
 7867            let project_path = ProjectPath {
 7868                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 7869                path: relative_path,
 7870            };
 7871            lsp_store
 7872                .update(cx, |lsp_store, cx| {
 7873                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 7874                        buffer_store.open_buffer(project_path, cx)
 7875                    })
 7876                })?
 7877                .await
 7878        })
 7879    }
 7880
 7881    fn request_multiple_lsp_locally<P, R>(
 7882        &mut self,
 7883        buffer: &Entity<Buffer>,
 7884        position: Option<P>,
 7885        request: R,
 7886        cx: &mut Context<Self>,
 7887    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 7888    where
 7889        P: ToOffset,
 7890        R: LspCommand + Clone,
 7891        <R::LspRequest as lsp::request::Request>::Result: Send,
 7892        <R::LspRequest as lsp::request::Request>::Params: Send,
 7893    {
 7894        let Some(local) = self.as_local() else {
 7895            return Task::ready(Vec::new());
 7896        };
 7897
 7898        let snapshot = buffer.read(cx).snapshot();
 7899        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 7900
 7901        let server_ids = buffer.update(cx, |buffer, cx| {
 7902            local
 7903                .language_servers_for_buffer(buffer, cx)
 7904                .filter(|(adapter, _)| {
 7905                    scope
 7906                        .as_ref()
 7907                        .map(|scope| scope.language_allowed(&adapter.name))
 7908                        .unwrap_or(true)
 7909                })
 7910                .map(|(_, server)| server.server_id())
 7911                .filter(|server_id| {
 7912                    self.as_local().is_none_or(|local| {
 7913                        local
 7914                            .buffers_opened_in_servers
 7915                            .get(&snapshot.remote_id())
 7916                            .is_some_and(|servers| servers.contains(server_id))
 7917                    })
 7918                })
 7919                .collect::<Vec<_>>()
 7920        });
 7921
 7922        let mut response_results = server_ids
 7923            .into_iter()
 7924            .map(|server_id| {
 7925                let task = self.request_lsp(
 7926                    buffer.clone(),
 7927                    LanguageServerToQuery::Other(server_id),
 7928                    request.clone(),
 7929                    cx,
 7930                );
 7931                async move { (server_id, task.await) }
 7932            })
 7933            .collect::<FuturesUnordered<_>>();
 7934
 7935        cx.background_spawn(async move {
 7936            let mut responses = Vec::with_capacity(response_results.len());
 7937            while let Some((server_id, response_result)) = response_results.next().await {
 7938                if let Some(response) = response_result.log_err() {
 7939                    responses.push((server_id, response));
 7940                }
 7941            }
 7942            responses
 7943        })
 7944    }
 7945
 7946    async fn handle_lsp_command<T: LspCommand>(
 7947        this: Entity<Self>,
 7948        envelope: TypedEnvelope<T::ProtoRequest>,
 7949        mut cx: AsyncApp,
 7950    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 7951    where
 7952        <T::LspRequest as lsp::request::Request>::Params: Send,
 7953        <T::LspRequest as lsp::request::Request>::Result: Send,
 7954    {
 7955        let sender_id = envelope.original_sender_id().unwrap_or_default();
 7956        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 7957        let buffer_handle = this.update(&mut cx, |this, cx| {
 7958            this.buffer_store.read(cx).get_existing(buffer_id)
 7959        })??;
 7960        let request = T::from_proto(
 7961            envelope.payload,
 7962            this.clone(),
 7963            buffer_handle.clone(),
 7964            cx.clone(),
 7965        )
 7966        .await?;
 7967        let response = this
 7968            .update(&mut cx, |this, cx| {
 7969                this.request_lsp(
 7970                    buffer_handle.clone(),
 7971                    LanguageServerToQuery::FirstCapable,
 7972                    request,
 7973                    cx,
 7974                )
 7975            })?
 7976            .await?;
 7977        this.update(&mut cx, |this, cx| {
 7978            Ok(T::response_to_proto(
 7979                response,
 7980                this,
 7981                sender_id,
 7982                &buffer_handle.read(cx).version(),
 7983                cx,
 7984            ))
 7985        })?
 7986    }
 7987
 7988    async fn handle_lsp_query(
 7989        lsp_store: Entity<Self>,
 7990        envelope: TypedEnvelope<proto::LspQuery>,
 7991        mut cx: AsyncApp,
 7992    ) -> Result<proto::Ack> {
 7993        use proto::lsp_query::Request;
 7994        let sender_id = envelope.original_sender_id().unwrap_or_default();
 7995        let lsp_query = envelope.payload;
 7996        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 7997        match lsp_query.request.context("invalid LSP query request")? {
 7998            Request::GetReferences(get_references) => {
 7999                let position = get_references.position.clone().and_then(deserialize_anchor);
 8000                Self::query_lsp_locally::<GetReferences>(
 8001                    lsp_store,
 8002                    sender_id,
 8003                    lsp_request_id,
 8004                    get_references,
 8005                    position,
 8006                    cx.clone(),
 8007                )
 8008                .await?;
 8009            }
 8010            Request::GetDocumentColor(get_document_color) => {
 8011                Self::query_lsp_locally::<GetDocumentColor>(
 8012                    lsp_store,
 8013                    sender_id,
 8014                    lsp_request_id,
 8015                    get_document_color,
 8016                    None,
 8017                    cx.clone(),
 8018                )
 8019                .await?;
 8020            }
 8021            Request::GetHover(get_hover) => {
 8022                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8023                Self::query_lsp_locally::<GetHover>(
 8024                    lsp_store,
 8025                    sender_id,
 8026                    lsp_request_id,
 8027                    get_hover,
 8028                    position,
 8029                    cx.clone(),
 8030                )
 8031                .await?;
 8032            }
 8033            Request::GetCodeActions(get_code_actions) => {
 8034                Self::query_lsp_locally::<GetCodeActions>(
 8035                    lsp_store,
 8036                    sender_id,
 8037                    lsp_request_id,
 8038                    get_code_actions,
 8039                    None,
 8040                    cx.clone(),
 8041                )
 8042                .await?;
 8043            }
 8044            Request::GetSignatureHelp(get_signature_help) => {
 8045                let position = get_signature_help
 8046                    .position
 8047                    .clone()
 8048                    .and_then(deserialize_anchor);
 8049                Self::query_lsp_locally::<GetSignatureHelp>(
 8050                    lsp_store,
 8051                    sender_id,
 8052                    lsp_request_id,
 8053                    get_signature_help,
 8054                    position,
 8055                    cx.clone(),
 8056                )
 8057                .await?;
 8058            }
 8059            Request::GetCodeLens(get_code_lens) => {
 8060                Self::query_lsp_locally::<GetCodeLens>(
 8061                    lsp_store,
 8062                    sender_id,
 8063                    lsp_request_id,
 8064                    get_code_lens,
 8065                    None,
 8066                    cx.clone(),
 8067                )
 8068                .await?;
 8069            }
 8070            Request::GetDefinition(get_definition) => {
 8071                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8072                Self::query_lsp_locally::<GetDefinitions>(
 8073                    lsp_store,
 8074                    sender_id,
 8075                    lsp_request_id,
 8076                    get_definition,
 8077                    position,
 8078                    cx.clone(),
 8079                )
 8080                .await?;
 8081            }
 8082            Request::GetDeclaration(get_declaration) => {
 8083                let position = get_declaration
 8084                    .position
 8085                    .clone()
 8086                    .and_then(deserialize_anchor);
 8087                Self::query_lsp_locally::<GetDeclarations>(
 8088                    lsp_store,
 8089                    sender_id,
 8090                    lsp_request_id,
 8091                    get_declaration,
 8092                    position,
 8093                    cx.clone(),
 8094                )
 8095                .await?;
 8096            }
 8097            Request::GetTypeDefinition(get_type_definition) => {
 8098                let position = get_type_definition
 8099                    .position
 8100                    .clone()
 8101                    .and_then(deserialize_anchor);
 8102                Self::query_lsp_locally::<GetTypeDefinitions>(
 8103                    lsp_store,
 8104                    sender_id,
 8105                    lsp_request_id,
 8106                    get_type_definition,
 8107                    position,
 8108                    cx.clone(),
 8109                )
 8110                .await?;
 8111            }
 8112            Request::GetImplementation(get_implementation) => {
 8113                let position = get_implementation
 8114                    .position
 8115                    .clone()
 8116                    .and_then(deserialize_anchor);
 8117                Self::query_lsp_locally::<GetImplementations>(
 8118                    lsp_store,
 8119                    sender_id,
 8120                    lsp_request_id,
 8121                    get_implementation,
 8122                    position,
 8123                    cx.clone(),
 8124                )
 8125                .await?;
 8126            }
 8127            // Diagnostics pull synchronizes internally via the buffer state, and cannot be handled generically as the other requests.
 8128            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 8129                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 8130                let version = deserialize_version(get_document_diagnostics.buffer_version());
 8131                let buffer = lsp_store.update(&mut cx, |this, cx| {
 8132                    this.buffer_store.read(cx).get_existing(buffer_id)
 8133                })??;
 8134                buffer
 8135                    .update(&mut cx, |buffer, _| {
 8136                        buffer.wait_for_version(version.clone())
 8137                    })?
 8138                    .await?;
 8139                lsp_store.update(&mut cx, |lsp_store, cx| {
 8140                    let existing_queries = lsp_store
 8141                        .running_lsp_requests
 8142                        .entry(TypeId::of::<GetDocumentDiagnostics>())
 8143                        .or_default();
 8144                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 8145                    ) || buffer.read(cx).version.changed_since(&existing_queries.0)
 8146                    {
 8147                        existing_queries.1.clear();
 8148                    }
 8149                    existing_queries.1.insert(
 8150                        lsp_request_id,
 8151                        cx.spawn(async move |lsp_store, cx| {
 8152                            let diagnostics_pull = lsp_store
 8153                                .update(cx, |lsp_store, cx| {
 8154                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8155                                })
 8156                                .ok();
 8157                            if let Some(diagnostics_pull) = diagnostics_pull {
 8158                                match diagnostics_pull.await {
 8159                                    Ok(()) => {}
 8160                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 8161                                };
 8162                            }
 8163                        }),
 8164                    );
 8165                })?;
 8166            }
 8167        }
 8168        Ok(proto::Ack {})
 8169    }
 8170
 8171    async fn handle_lsp_query_response(
 8172        lsp_store: Entity<Self>,
 8173        envelope: TypedEnvelope<proto::LspQueryResponse>,
 8174        cx: AsyncApp,
 8175    ) -> Result<()> {
 8176        lsp_store.read_with(&cx, |lsp_store, _| {
 8177            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 8178                upstream_client.handle_lsp_response(envelope.clone());
 8179            }
 8180        })?;
 8181        Ok(())
 8182    }
 8183
 8184    // todo(lsp) remove after Zed Stable hits v0.204.x
 8185    async fn handle_multi_lsp_query(
 8186        lsp_store: Entity<Self>,
 8187        envelope: TypedEnvelope<proto::MultiLspQuery>,
 8188        mut cx: AsyncApp,
 8189    ) -> Result<proto::MultiLspQueryResponse> {
 8190        let response_from_ssh = lsp_store.read_with(&cx, |this, _| {
 8191            let (upstream_client, project_id) = this.upstream_client()?;
 8192            let mut payload = envelope.payload.clone();
 8193            payload.project_id = project_id;
 8194
 8195            Some(upstream_client.request(payload))
 8196        })?;
 8197        if let Some(response_from_ssh) = response_from_ssh {
 8198            return response_from_ssh.await;
 8199        }
 8200
 8201        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8202        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8203        let version = deserialize_version(&envelope.payload.version);
 8204        let buffer = lsp_store.update(&mut cx, |this, cx| {
 8205            this.buffer_store.read(cx).get_existing(buffer_id)
 8206        })??;
 8207        buffer
 8208            .update(&mut cx, |buffer, _| {
 8209                buffer.wait_for_version(version.clone())
 8210            })?
 8211            .await?;
 8212        let buffer_version = buffer.read_with(&cx, |buffer, _| buffer.version())?;
 8213        match envelope
 8214            .payload
 8215            .strategy
 8216            .context("invalid request without the strategy")?
 8217        {
 8218            proto::multi_lsp_query::Strategy::All(_) => {
 8219                // currently, there's only one multiple language servers query strategy,
 8220                // so just ensure it's specified correctly
 8221            }
 8222        }
 8223        match envelope.payload.request {
 8224            Some(proto::multi_lsp_query::Request::GetHover(message)) => {
 8225                buffer
 8226                    .update(&mut cx, |buffer, _| {
 8227                        buffer.wait_for_version(deserialize_version(&message.version))
 8228                    })?
 8229                    .await?;
 8230                let get_hover =
 8231                    GetHover::from_proto(message, lsp_store.clone(), buffer.clone(), cx.clone())
 8232                        .await?;
 8233                let all_hovers = lsp_store
 8234                    .update(&mut cx, |this, cx| {
 8235                        this.request_multiple_lsp_locally(
 8236                            &buffer,
 8237                            Some(get_hover.position),
 8238                            get_hover,
 8239                            cx,
 8240                        )
 8241                    })?
 8242                    .await
 8243                    .into_iter()
 8244                    .filter_map(|(server_id, hover)| {
 8245                        Some((server_id, remove_empty_hover_blocks(hover?)?))
 8246                    });
 8247                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8248                    responses: all_hovers
 8249                        .map(|(server_id, hover)| proto::LspResponse {
 8250                            server_id: server_id.to_proto(),
 8251                            response: Some(proto::lsp_response::Response::GetHoverResponse(
 8252                                GetHover::response_to_proto(
 8253                                    Some(hover),
 8254                                    project,
 8255                                    sender_id,
 8256                                    &buffer_version,
 8257                                    cx,
 8258                                ),
 8259                            )),
 8260                        })
 8261                        .collect(),
 8262                })
 8263            }
 8264            Some(proto::multi_lsp_query::Request::GetCodeActions(message)) => {
 8265                buffer
 8266                    .update(&mut cx, |buffer, _| {
 8267                        buffer.wait_for_version(deserialize_version(&message.version))
 8268                    })?
 8269                    .await?;
 8270                let get_code_actions = GetCodeActions::from_proto(
 8271                    message,
 8272                    lsp_store.clone(),
 8273                    buffer.clone(),
 8274                    cx.clone(),
 8275                )
 8276                .await?;
 8277
 8278                let all_actions = lsp_store
 8279                    .update(&mut cx, |project, cx| {
 8280                        project.request_multiple_lsp_locally(
 8281                            &buffer,
 8282                            Some(get_code_actions.range.start),
 8283                            get_code_actions,
 8284                            cx,
 8285                        )
 8286                    })?
 8287                    .await
 8288                    .into_iter();
 8289
 8290                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8291                    responses: all_actions
 8292                        .map(|(server_id, code_actions)| proto::LspResponse {
 8293                            server_id: server_id.to_proto(),
 8294                            response: Some(proto::lsp_response::Response::GetCodeActionsResponse(
 8295                                GetCodeActions::response_to_proto(
 8296                                    code_actions,
 8297                                    project,
 8298                                    sender_id,
 8299                                    &buffer_version,
 8300                                    cx,
 8301                                ),
 8302                            )),
 8303                        })
 8304                        .collect(),
 8305                })
 8306            }
 8307            Some(proto::multi_lsp_query::Request::GetSignatureHelp(message)) => {
 8308                buffer
 8309                    .update(&mut cx, |buffer, _| {
 8310                        buffer.wait_for_version(deserialize_version(&message.version))
 8311                    })?
 8312                    .await?;
 8313                let get_signature_help = GetSignatureHelp::from_proto(
 8314                    message,
 8315                    lsp_store.clone(),
 8316                    buffer.clone(),
 8317                    cx.clone(),
 8318                )
 8319                .await?;
 8320
 8321                let all_signatures = lsp_store
 8322                    .update(&mut cx, |project, cx| {
 8323                        project.request_multiple_lsp_locally(
 8324                            &buffer,
 8325                            Some(get_signature_help.position),
 8326                            get_signature_help,
 8327                            cx,
 8328                        )
 8329                    })?
 8330                    .await
 8331                    .into_iter();
 8332
 8333                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8334                    responses: all_signatures
 8335                        .map(|(server_id, signature_help)| proto::LspResponse {
 8336                            server_id: server_id.to_proto(),
 8337                            response: Some(
 8338                                proto::lsp_response::Response::GetSignatureHelpResponse(
 8339                                    GetSignatureHelp::response_to_proto(
 8340                                        signature_help,
 8341                                        project,
 8342                                        sender_id,
 8343                                        &buffer_version,
 8344                                        cx,
 8345                                    ),
 8346                                ),
 8347                            ),
 8348                        })
 8349                        .collect(),
 8350                })
 8351            }
 8352            Some(proto::multi_lsp_query::Request::GetCodeLens(message)) => {
 8353                buffer
 8354                    .update(&mut cx, |buffer, _| {
 8355                        buffer.wait_for_version(deserialize_version(&message.version))
 8356                    })?
 8357                    .await?;
 8358                let get_code_lens =
 8359                    GetCodeLens::from_proto(message, lsp_store.clone(), buffer.clone(), cx.clone())
 8360                        .await?;
 8361
 8362                let code_lens_actions = lsp_store
 8363                    .update(&mut cx, |project, cx| {
 8364                        project.request_multiple_lsp_locally(
 8365                            &buffer,
 8366                            None::<usize>,
 8367                            get_code_lens,
 8368                            cx,
 8369                        )
 8370                    })?
 8371                    .await
 8372                    .into_iter();
 8373
 8374                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8375                    responses: code_lens_actions
 8376                        .map(|(server_id, actions)| proto::LspResponse {
 8377                            server_id: server_id.to_proto(),
 8378                            response: Some(proto::lsp_response::Response::GetCodeLensResponse(
 8379                                GetCodeLens::response_to_proto(
 8380                                    actions,
 8381                                    project,
 8382                                    sender_id,
 8383                                    &buffer_version,
 8384                                    cx,
 8385                                ),
 8386                            )),
 8387                        })
 8388                        .collect(),
 8389                })
 8390            }
 8391            Some(proto::multi_lsp_query::Request::GetDocumentDiagnostics(message)) => {
 8392                buffer
 8393                    .update(&mut cx, |buffer, _| {
 8394                        buffer.wait_for_version(deserialize_version(&message.version))
 8395                    })?
 8396                    .await?;
 8397                lsp_store
 8398                    .update(&mut cx, |lsp_store, cx| {
 8399                        lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8400                    })?
 8401                    .await?;
 8402                // `pull_diagnostics_for_buffer` will merge in the new diagnostics and send them to the client.
 8403                // The client cannot merge anything into its non-local LspStore, so we do not need to return anything.
 8404                Ok(proto::MultiLspQueryResponse {
 8405                    responses: Vec::new(),
 8406                })
 8407            }
 8408            Some(proto::multi_lsp_query::Request::GetDocumentColor(message)) => {
 8409                buffer
 8410                    .update(&mut cx, |buffer, _| {
 8411                        buffer.wait_for_version(deserialize_version(&message.version))
 8412                    })?
 8413                    .await?;
 8414                let get_document_color = GetDocumentColor::from_proto(
 8415                    message,
 8416                    lsp_store.clone(),
 8417                    buffer.clone(),
 8418                    cx.clone(),
 8419                )
 8420                .await?;
 8421
 8422                let all_colors = lsp_store
 8423                    .update(&mut cx, |project, cx| {
 8424                        project.request_multiple_lsp_locally(
 8425                            &buffer,
 8426                            None::<usize>,
 8427                            get_document_color,
 8428                            cx,
 8429                        )
 8430                    })?
 8431                    .await
 8432                    .into_iter();
 8433
 8434                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8435                    responses: all_colors
 8436                        .map(|(server_id, colors)| proto::LspResponse {
 8437                            server_id: server_id.to_proto(),
 8438                            response: Some(
 8439                                proto::lsp_response::Response::GetDocumentColorResponse(
 8440                                    GetDocumentColor::response_to_proto(
 8441                                        colors,
 8442                                        project,
 8443                                        sender_id,
 8444                                        &buffer_version,
 8445                                        cx,
 8446                                    ),
 8447                                ),
 8448                            ),
 8449                        })
 8450                        .collect(),
 8451                })
 8452            }
 8453            Some(proto::multi_lsp_query::Request::GetDefinition(message)) => {
 8454                let get_definitions = GetDefinitions::from_proto(
 8455                    message,
 8456                    lsp_store.clone(),
 8457                    buffer.clone(),
 8458                    cx.clone(),
 8459                )
 8460                .await?;
 8461
 8462                let definitions = lsp_store
 8463                    .update(&mut cx, |project, cx| {
 8464                        project.request_multiple_lsp_locally(
 8465                            &buffer,
 8466                            Some(get_definitions.position),
 8467                            get_definitions,
 8468                            cx,
 8469                        )
 8470                    })?
 8471                    .await
 8472                    .into_iter();
 8473
 8474                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8475                    responses: definitions
 8476                        .map(|(server_id, definitions)| proto::LspResponse {
 8477                            server_id: server_id.to_proto(),
 8478                            response: Some(proto::lsp_response::Response::GetDefinitionResponse(
 8479                                GetDefinitions::response_to_proto(
 8480                                    definitions,
 8481                                    project,
 8482                                    sender_id,
 8483                                    &buffer_version,
 8484                                    cx,
 8485                                ),
 8486                            )),
 8487                        })
 8488                        .collect(),
 8489                })
 8490            }
 8491            Some(proto::multi_lsp_query::Request::GetDeclaration(message)) => {
 8492                let get_declarations = GetDeclarations::from_proto(
 8493                    message,
 8494                    lsp_store.clone(),
 8495                    buffer.clone(),
 8496                    cx.clone(),
 8497                )
 8498                .await?;
 8499
 8500                let declarations = lsp_store
 8501                    .update(&mut cx, |project, cx| {
 8502                        project.request_multiple_lsp_locally(
 8503                            &buffer,
 8504                            Some(get_declarations.position),
 8505                            get_declarations,
 8506                            cx,
 8507                        )
 8508                    })?
 8509                    .await
 8510                    .into_iter();
 8511
 8512                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8513                    responses: declarations
 8514                        .map(|(server_id, declarations)| proto::LspResponse {
 8515                            server_id: server_id.to_proto(),
 8516                            response: Some(proto::lsp_response::Response::GetDeclarationResponse(
 8517                                GetDeclarations::response_to_proto(
 8518                                    declarations,
 8519                                    project,
 8520                                    sender_id,
 8521                                    &buffer_version,
 8522                                    cx,
 8523                                ),
 8524                            )),
 8525                        })
 8526                        .collect(),
 8527                })
 8528            }
 8529            Some(proto::multi_lsp_query::Request::GetTypeDefinition(message)) => {
 8530                let get_type_definitions = GetTypeDefinitions::from_proto(
 8531                    message,
 8532                    lsp_store.clone(),
 8533                    buffer.clone(),
 8534                    cx.clone(),
 8535                )
 8536                .await?;
 8537
 8538                let type_definitions = lsp_store
 8539                    .update(&mut cx, |project, cx| {
 8540                        project.request_multiple_lsp_locally(
 8541                            &buffer,
 8542                            Some(get_type_definitions.position),
 8543                            get_type_definitions,
 8544                            cx,
 8545                        )
 8546                    })?
 8547                    .await
 8548                    .into_iter();
 8549
 8550                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8551                    responses: type_definitions
 8552                        .map(|(server_id, type_definitions)| proto::LspResponse {
 8553                            server_id: server_id.to_proto(),
 8554                            response: Some(
 8555                                proto::lsp_response::Response::GetTypeDefinitionResponse(
 8556                                    GetTypeDefinitions::response_to_proto(
 8557                                        type_definitions,
 8558                                        project,
 8559                                        sender_id,
 8560                                        &buffer_version,
 8561                                        cx,
 8562                                    ),
 8563                                ),
 8564                            ),
 8565                        })
 8566                        .collect(),
 8567                })
 8568            }
 8569            Some(proto::multi_lsp_query::Request::GetImplementation(message)) => {
 8570                let get_implementations = GetImplementations::from_proto(
 8571                    message,
 8572                    lsp_store.clone(),
 8573                    buffer.clone(),
 8574                    cx.clone(),
 8575                )
 8576                .await?;
 8577
 8578                let implementations = lsp_store
 8579                    .update(&mut cx, |project, cx| {
 8580                        project.request_multiple_lsp_locally(
 8581                            &buffer,
 8582                            Some(get_implementations.position),
 8583                            get_implementations,
 8584                            cx,
 8585                        )
 8586                    })?
 8587                    .await
 8588                    .into_iter();
 8589
 8590                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8591                    responses: implementations
 8592                        .map(|(server_id, implementations)| proto::LspResponse {
 8593                            server_id: server_id.to_proto(),
 8594                            response: Some(
 8595                                proto::lsp_response::Response::GetImplementationResponse(
 8596                                    GetImplementations::response_to_proto(
 8597                                        implementations,
 8598                                        project,
 8599                                        sender_id,
 8600                                        &buffer_version,
 8601                                        cx,
 8602                                    ),
 8603                                ),
 8604                            ),
 8605                        })
 8606                        .collect(),
 8607                })
 8608            }
 8609            Some(proto::multi_lsp_query::Request::GetReferences(message)) => {
 8610                let get_references = GetReferences::from_proto(
 8611                    message,
 8612                    lsp_store.clone(),
 8613                    buffer.clone(),
 8614                    cx.clone(),
 8615                )
 8616                .await?;
 8617
 8618                let references = lsp_store
 8619                    .update(&mut cx, |project, cx| {
 8620                        project.request_multiple_lsp_locally(
 8621                            &buffer,
 8622                            Some(get_references.position),
 8623                            get_references,
 8624                            cx,
 8625                        )
 8626                    })?
 8627                    .await
 8628                    .into_iter();
 8629
 8630                lsp_store.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
 8631                    responses: references
 8632                        .map(|(server_id, references)| proto::LspResponse {
 8633                            server_id: server_id.to_proto(),
 8634                            response: Some(proto::lsp_response::Response::GetReferencesResponse(
 8635                                GetReferences::response_to_proto(
 8636                                    references,
 8637                                    project,
 8638                                    sender_id,
 8639                                    &buffer_version,
 8640                                    cx,
 8641                                ),
 8642                            )),
 8643                        })
 8644                        .collect(),
 8645                })
 8646            }
 8647            None => anyhow::bail!("empty multi lsp query request"),
 8648        }
 8649    }
 8650
 8651    async fn handle_apply_code_action(
 8652        this: Entity<Self>,
 8653        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 8654        mut cx: AsyncApp,
 8655    ) -> Result<proto::ApplyCodeActionResponse> {
 8656        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8657        let action =
 8658            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 8659        let apply_code_action = this.update(&mut cx, |this, cx| {
 8660            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8661            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 8662            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 8663        })??;
 8664
 8665        let project_transaction = apply_code_action.await?;
 8666        let project_transaction = this.update(&mut cx, |this, cx| {
 8667            this.buffer_store.update(cx, |buffer_store, cx| {
 8668                buffer_store.serialize_project_transaction_for_peer(
 8669                    project_transaction,
 8670                    sender_id,
 8671                    cx,
 8672                )
 8673            })
 8674        })?;
 8675        Ok(proto::ApplyCodeActionResponse {
 8676            transaction: Some(project_transaction),
 8677        })
 8678    }
 8679
 8680    async fn handle_register_buffer_with_language_servers(
 8681        this: Entity<Self>,
 8682        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 8683        mut cx: AsyncApp,
 8684    ) -> Result<proto::Ack> {
 8685        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8686        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 8687        this.update(&mut cx, |this, cx| {
 8688            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 8689                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 8690                    project_id: upstream_project_id,
 8691                    buffer_id: buffer_id.to_proto(),
 8692                    only_servers: envelope.payload.only_servers,
 8693                });
 8694            }
 8695
 8696            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 8697                anyhow::bail!("buffer is not open");
 8698            };
 8699
 8700            let handle = this.register_buffer_with_language_servers(
 8701                &buffer,
 8702                envelope
 8703                    .payload
 8704                    .only_servers
 8705                    .into_iter()
 8706                    .filter_map(|selector| {
 8707                        Some(match selector.selector? {
 8708                            proto::language_server_selector::Selector::ServerId(server_id) => {
 8709                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 8710                            }
 8711                            proto::language_server_selector::Selector::Name(name) => {
 8712                                LanguageServerSelector::Name(LanguageServerName(
 8713                                    SharedString::from(name),
 8714                                ))
 8715                            }
 8716                        })
 8717                    })
 8718                    .collect(),
 8719                false,
 8720                cx,
 8721            );
 8722            this.buffer_store().update(cx, |buffer_store, _| {
 8723                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 8724            });
 8725
 8726            Ok(())
 8727        })??;
 8728        Ok(proto::Ack {})
 8729    }
 8730
 8731    async fn handle_rename_project_entry(
 8732        this: Entity<Self>,
 8733        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 8734        mut cx: AsyncApp,
 8735    ) -> Result<proto::ProjectEntryResponse> {
 8736        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 8737        let (worktree_id, worktree, old_path, is_dir) = this
 8738            .update(&mut cx, |this, cx| {
 8739                this.worktree_store
 8740                    .read(cx)
 8741                    .worktree_and_entry_for_id(entry_id, cx)
 8742                    .map(|(worktree, entry)| {
 8743                        (
 8744                            worktree.read(cx).id(),
 8745                            worktree,
 8746                            entry.path.clone(),
 8747                            entry.is_dir(),
 8748                        )
 8749                    })
 8750            })?
 8751            .context("worktree not found")?;
 8752        let (old_abs_path, new_abs_path) = {
 8753            let root_path = worktree.read_with(&cx, |this, _| this.abs_path())?;
 8754            let new_path = PathBuf::from_proto(envelope.payload.new_path.clone());
 8755            (root_path.join(&old_path), root_path.join(&new_path))
 8756        };
 8757
 8758        let _transaction = Self::will_rename_entry(
 8759            this.downgrade(),
 8760            worktree_id,
 8761            &old_abs_path,
 8762            &new_abs_path,
 8763            is_dir,
 8764            cx.clone(),
 8765        )
 8766        .await;
 8767        let response = Worktree::handle_rename_entry(worktree, envelope.payload, cx.clone()).await;
 8768        this.read_with(&cx, |this, _| {
 8769            this.did_rename_entry(worktree_id, &old_abs_path, &new_abs_path, is_dir);
 8770        })
 8771        .ok();
 8772        response
 8773    }
 8774
 8775    async fn handle_update_diagnostic_summary(
 8776        this: Entity<Self>,
 8777        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 8778        mut cx: AsyncApp,
 8779    ) -> Result<()> {
 8780        this.update(&mut cx, |lsp_store, cx| {
 8781            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 8782            let mut updated_diagnostics_paths = HashMap::default();
 8783            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8784            for message_summary in envelope
 8785                .payload
 8786                .summary
 8787                .into_iter()
 8788                .chain(envelope.payload.more_summaries)
 8789            {
 8790                let project_path = ProjectPath {
 8791                    worktree_id,
 8792                    path: Arc::<Path>::from_proto(message_summary.path),
 8793                };
 8794                let path = project_path.path.clone();
 8795                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 8796                let summary = DiagnosticSummary {
 8797                    error_count: message_summary.error_count as usize,
 8798                    warning_count: message_summary.warning_count as usize,
 8799                };
 8800
 8801                if summary.is_empty() {
 8802                    if let Some(worktree_summaries) =
 8803                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 8804                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 8805                    {
 8806                        summaries.remove(&server_id);
 8807                        if summaries.is_empty() {
 8808                            worktree_summaries.remove(&path);
 8809                        }
 8810                    }
 8811                } else {
 8812                    lsp_store
 8813                        .diagnostic_summaries
 8814                        .entry(worktree_id)
 8815                        .or_default()
 8816                        .entry(path)
 8817                        .or_default()
 8818                        .insert(server_id, summary);
 8819                }
 8820
 8821                if let Some((_, project_id)) = &lsp_store.downstream_client {
 8822                    match &mut diagnostics_summary {
 8823                        Some(diagnostics_summary) => {
 8824                            diagnostics_summary
 8825                                .more_summaries
 8826                                .push(proto::DiagnosticSummary {
 8827                                    path: project_path.path.as_ref().to_proto(),
 8828                                    language_server_id: server_id.0 as u64,
 8829                                    error_count: summary.error_count as u32,
 8830                                    warning_count: summary.warning_count as u32,
 8831                                })
 8832                        }
 8833                        None => {
 8834                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8835                                project_id: *project_id,
 8836                                worktree_id: worktree_id.to_proto(),
 8837                                summary: Some(proto::DiagnosticSummary {
 8838                                    path: project_path.path.as_ref().to_proto(),
 8839                                    language_server_id: server_id.0 as u64,
 8840                                    error_count: summary.error_count as u32,
 8841                                    warning_count: summary.warning_count as u32,
 8842                                }),
 8843                                more_summaries: Vec::new(),
 8844                            })
 8845                        }
 8846                    }
 8847                }
 8848                updated_diagnostics_paths
 8849                    .entry(server_id)
 8850                    .or_insert_with(Vec::new)
 8851                    .push(project_path);
 8852            }
 8853
 8854            if let Some((diagnostics_summary, (downstream_client, _))) =
 8855                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 8856            {
 8857                downstream_client.send(diagnostics_summary).log_err();
 8858            }
 8859            for (server_id, paths) in updated_diagnostics_paths {
 8860                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8861            }
 8862            Ok(())
 8863        })?
 8864    }
 8865
 8866    async fn handle_start_language_server(
 8867        lsp_store: Entity<Self>,
 8868        envelope: TypedEnvelope<proto::StartLanguageServer>,
 8869        mut cx: AsyncApp,
 8870    ) -> Result<()> {
 8871        let server = envelope.payload.server.context("invalid server")?;
 8872        let server_capabilities =
 8873            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 8874                .with_context(|| {
 8875                    format!(
 8876                        "incorrect server capabilities {}",
 8877                        envelope.payload.capabilities
 8878                    )
 8879                })?;
 8880        lsp_store.update(&mut cx, |lsp_store, cx| {
 8881            let server_id = LanguageServerId(server.id as usize);
 8882            let server_name = LanguageServerName::from_proto(server.name.clone());
 8883            lsp_store
 8884                .lsp_server_capabilities
 8885                .insert(server_id, server_capabilities);
 8886            lsp_store.language_server_statuses.insert(
 8887                server_id,
 8888                LanguageServerStatus {
 8889                    name: server_name.clone(),
 8890                    pending_work: Default::default(),
 8891                    has_pending_diagnostic_updates: false,
 8892                    progress_tokens: Default::default(),
 8893                },
 8894            );
 8895            cx.emit(LspStoreEvent::LanguageServerAdded(
 8896                server_id,
 8897                server_name,
 8898                server.worktree_id.map(WorktreeId::from_proto),
 8899            ));
 8900            cx.notify();
 8901        })?;
 8902        Ok(())
 8903    }
 8904
 8905    async fn handle_update_language_server(
 8906        lsp_store: Entity<Self>,
 8907        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 8908        mut cx: AsyncApp,
 8909    ) -> Result<()> {
 8910        lsp_store.update(&mut cx, |lsp_store, cx| {
 8911            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8912
 8913            match envelope.payload.variant.context("invalid variant")? {
 8914                proto::update_language_server::Variant::WorkStart(payload) => {
 8915                    lsp_store.on_lsp_work_start(
 8916                        language_server_id,
 8917                        payload.token,
 8918                        LanguageServerProgress {
 8919                            title: payload.title,
 8920                            is_disk_based_diagnostics_progress: false,
 8921                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 8922                            message: payload.message,
 8923                            percentage: payload.percentage.map(|p| p as usize),
 8924                            last_update_at: cx.background_executor().now(),
 8925                        },
 8926                        cx,
 8927                    );
 8928                }
 8929                proto::update_language_server::Variant::WorkProgress(payload) => {
 8930                    lsp_store.on_lsp_work_progress(
 8931                        language_server_id,
 8932                        payload.token,
 8933                        LanguageServerProgress {
 8934                            title: None,
 8935                            is_disk_based_diagnostics_progress: false,
 8936                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 8937                            message: payload.message,
 8938                            percentage: payload.percentage.map(|p| p as usize),
 8939                            last_update_at: cx.background_executor().now(),
 8940                        },
 8941                        cx,
 8942                    );
 8943                }
 8944
 8945                proto::update_language_server::Variant::WorkEnd(payload) => {
 8946                    lsp_store.on_lsp_work_end(language_server_id, payload.token, cx);
 8947                }
 8948
 8949                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 8950                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 8951                }
 8952
 8953                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 8954                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 8955                }
 8956
 8957                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 8958                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 8959                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 8960                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 8961                        language_server_id,
 8962                        name: envelope
 8963                            .payload
 8964                            .server_name
 8965                            .map(SharedString::new)
 8966                            .map(LanguageServerName),
 8967                        message: non_lsp,
 8968                    });
 8969                }
 8970            }
 8971
 8972            Ok(())
 8973        })?
 8974    }
 8975
 8976    async fn handle_language_server_log(
 8977        this: Entity<Self>,
 8978        envelope: TypedEnvelope<proto::LanguageServerLog>,
 8979        mut cx: AsyncApp,
 8980    ) -> Result<()> {
 8981        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8982        let log_type = envelope
 8983            .payload
 8984            .log_type
 8985            .map(LanguageServerLogType::from_proto)
 8986            .context("invalid language server log type")?;
 8987
 8988        let message = envelope.payload.message;
 8989
 8990        this.update(&mut cx, |_, cx| {
 8991            cx.emit(LspStoreEvent::LanguageServerLog(
 8992                language_server_id,
 8993                log_type,
 8994                message,
 8995            ));
 8996        })
 8997    }
 8998
 8999    async fn handle_lsp_ext_cancel_flycheck(
 9000        lsp_store: Entity<Self>,
 9001        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9002        cx: AsyncApp,
 9003    ) -> Result<proto::Ack> {
 9004        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9005        lsp_store.read_with(&cx, |lsp_store, _| {
 9006            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9007                server
 9008                    .notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(&())
 9009                    .context("handling lsp ext cancel flycheck")
 9010            } else {
 9011                anyhow::Ok(())
 9012            }
 9013        })??;
 9014
 9015        Ok(proto::Ack {})
 9016    }
 9017
 9018    async fn handle_lsp_ext_run_flycheck(
 9019        lsp_store: Entity<Self>,
 9020        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9021        mut cx: AsyncApp,
 9022    ) -> Result<proto::Ack> {
 9023        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9024        lsp_store.update(&mut cx, |lsp_store, cx| {
 9025            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9026                let text_document = if envelope.payload.current_file_only {
 9027                    let buffer_id = envelope
 9028                        .payload
 9029                        .buffer_id
 9030                        .map(|id| BufferId::new(id))
 9031                        .transpose()?;
 9032                    buffer_id
 9033                        .and_then(|buffer_id| {
 9034                            lsp_store
 9035                                .buffer_store()
 9036                                .read(cx)
 9037                                .get(buffer_id)
 9038                                .and_then(|buffer| {
 9039                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9040                                })
 9041                                .map(|path| make_text_document_identifier(&path))
 9042                        })
 9043                        .transpose()?
 9044                } else {
 9045                    None
 9046                };
 9047                server
 9048                    .notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9049                        &lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9050                    )
 9051                    .context("handling lsp ext run flycheck")
 9052            } else {
 9053                anyhow::Ok(())
 9054            }
 9055        })??;
 9056
 9057        Ok(proto::Ack {})
 9058    }
 9059
 9060    async fn handle_lsp_ext_clear_flycheck(
 9061        lsp_store: Entity<Self>,
 9062        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9063        cx: AsyncApp,
 9064    ) -> Result<proto::Ack> {
 9065        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9066        lsp_store.read_with(&cx, |lsp_store, _| {
 9067            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9068                server
 9069                    .notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(&())
 9070                    .context("handling lsp ext clear flycheck")
 9071            } else {
 9072                anyhow::Ok(())
 9073            }
 9074        })??;
 9075
 9076        Ok(proto::Ack {})
 9077    }
 9078
 9079    pub fn disk_based_diagnostics_started(
 9080        &mut self,
 9081        language_server_id: LanguageServerId,
 9082        cx: &mut Context<Self>,
 9083    ) {
 9084        if let Some(language_server_status) =
 9085            self.language_server_statuses.get_mut(&language_server_id)
 9086        {
 9087            language_server_status.has_pending_diagnostic_updates = true;
 9088        }
 9089
 9090        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9091        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9092            language_server_id,
 9093            name: self
 9094                .language_server_adapter_for_id(language_server_id)
 9095                .map(|adapter| adapter.name()),
 9096            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9097                Default::default(),
 9098            ),
 9099        })
 9100    }
 9101
 9102    pub fn disk_based_diagnostics_finished(
 9103        &mut self,
 9104        language_server_id: LanguageServerId,
 9105        cx: &mut Context<Self>,
 9106    ) {
 9107        if let Some(language_server_status) =
 9108            self.language_server_statuses.get_mut(&language_server_id)
 9109        {
 9110            language_server_status.has_pending_diagnostic_updates = false;
 9111        }
 9112
 9113        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9114        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9115            language_server_id,
 9116            name: self
 9117                .language_server_adapter_for_id(language_server_id)
 9118                .map(|adapter| adapter.name()),
 9119            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9120                Default::default(),
 9121            ),
 9122        })
 9123    }
 9124
 9125    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9126    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9127    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9128    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9129    // the language server might take some time to publish diagnostics.
 9130    fn simulate_disk_based_diagnostics_events_if_needed(
 9131        &mut self,
 9132        language_server_id: LanguageServerId,
 9133        cx: &mut Context<Self>,
 9134    ) {
 9135        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9136
 9137        let Some(LanguageServerState::Running {
 9138            simulate_disk_based_diagnostics_completion,
 9139            adapter,
 9140            ..
 9141        }) = self
 9142            .as_local_mut()
 9143            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9144        else {
 9145            return;
 9146        };
 9147
 9148        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9149            return;
 9150        }
 9151
 9152        let prev_task =
 9153            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9154                cx.background_executor()
 9155                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9156                    .await;
 9157
 9158                this.update(cx, |this, cx| {
 9159                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9160
 9161                    if let Some(LanguageServerState::Running {
 9162                        simulate_disk_based_diagnostics_completion,
 9163                        ..
 9164                    }) = this.as_local_mut().and_then(|local_store| {
 9165                        local_store.language_servers.get_mut(&language_server_id)
 9166                    }) {
 9167                        *simulate_disk_based_diagnostics_completion = None;
 9168                    }
 9169                })
 9170                .ok();
 9171            }));
 9172
 9173        if prev_task.is_none() {
 9174            self.disk_based_diagnostics_started(language_server_id, cx);
 9175        }
 9176    }
 9177
 9178    pub fn language_server_statuses(
 9179        &self,
 9180    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9181        self.language_server_statuses
 9182            .iter()
 9183            .map(|(key, value)| (*key, value))
 9184    }
 9185
 9186    pub(super) fn did_rename_entry(
 9187        &self,
 9188        worktree_id: WorktreeId,
 9189        old_path: &Path,
 9190        new_path: &Path,
 9191        is_dir: bool,
 9192    ) {
 9193        maybe!({
 9194            let local_store = self.as_local()?;
 9195
 9196            let old_uri = lsp::Url::from_file_path(old_path).ok().map(String::from)?;
 9197            let new_uri = lsp::Url::from_file_path(new_path).ok().map(String::from)?;
 9198
 9199            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9200                let Some(filter) = local_store
 9201                    .language_server_paths_watched_for_rename
 9202                    .get(&language_server.server_id())
 9203                else {
 9204                    continue;
 9205                };
 9206
 9207                if filter.should_send_did_rename(&old_uri, is_dir) {
 9208                    language_server
 9209                        .notify::<DidRenameFiles>(&RenameFilesParams {
 9210                            files: vec![FileRename {
 9211                                old_uri: old_uri.clone(),
 9212                                new_uri: new_uri.clone(),
 9213                            }],
 9214                        })
 9215                        .ok();
 9216                }
 9217            }
 9218            Some(())
 9219        });
 9220    }
 9221
 9222    pub(super) fn will_rename_entry(
 9223        this: WeakEntity<Self>,
 9224        worktree_id: WorktreeId,
 9225        old_path: &Path,
 9226        new_path: &Path,
 9227        is_dir: bool,
 9228        cx: AsyncApp,
 9229    ) -> Task<ProjectTransaction> {
 9230        let old_uri = lsp::Url::from_file_path(old_path).ok().map(String::from);
 9231        let new_uri = lsp::Url::from_file_path(new_path).ok().map(String::from);
 9232        cx.spawn(async move |cx| {
 9233            let mut tasks = vec![];
 9234            this.update(cx, |this, cx| {
 9235                let local_store = this.as_local()?;
 9236                let old_uri = old_uri?;
 9237                let new_uri = new_uri?;
 9238                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9239                    let Some(filter) = local_store
 9240                        .language_server_paths_watched_for_rename
 9241                        .get(&language_server.server_id())
 9242                    else {
 9243                        continue;
 9244                    };
 9245
 9246                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9247                        let apply_edit = cx.spawn({
 9248                            let old_uri = old_uri.clone();
 9249                            let new_uri = new_uri.clone();
 9250                            let language_server = language_server.clone();
 9251                            async move |this, cx| {
 9252                                let edit = language_server
 9253                                    .request::<WillRenameFiles>(RenameFilesParams {
 9254                                        files: vec![FileRename { old_uri, new_uri }],
 9255                                    })
 9256                                    .await
 9257                                    .into_response()
 9258                                    .context("will rename files")
 9259                                    .log_err()
 9260                                    .flatten()?;
 9261
 9262                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9263                                    this.upgrade()?,
 9264                                    edit,
 9265                                    false,
 9266                                    language_server.clone(),
 9267                                    cx,
 9268                                )
 9269                                .await
 9270                                .ok()?;
 9271                                Some(transaction)
 9272                            }
 9273                        });
 9274                        tasks.push(apply_edit);
 9275                    }
 9276                }
 9277                Some(())
 9278            })
 9279            .ok()
 9280            .flatten();
 9281            let mut merged_transaction = ProjectTransaction::default();
 9282            for task in tasks {
 9283                // Await on tasks sequentially so that the order of application of edits is deterministic
 9284                // (at least with regards to the order of registration of language servers)
 9285                if let Some(transaction) = task.await {
 9286                    for (buffer, buffer_transaction) in transaction.0 {
 9287                        merged_transaction.0.insert(buffer, buffer_transaction);
 9288                    }
 9289                }
 9290            }
 9291            merged_transaction
 9292        })
 9293    }
 9294
 9295    fn lsp_notify_abs_paths_changed(
 9296        &mut self,
 9297        server_id: LanguageServerId,
 9298        changes: Vec<PathEvent>,
 9299    ) {
 9300        maybe!({
 9301            let server = self.language_server_for_id(server_id)?;
 9302            let changes = changes
 9303                .into_iter()
 9304                .filter_map(|event| {
 9305                    let typ = match event.kind? {
 9306                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9307                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9308                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9309                    };
 9310                    Some(lsp::FileEvent {
 9311                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9312                        typ,
 9313                    })
 9314                })
 9315                .collect::<Vec<_>>();
 9316            if !changes.is_empty() {
 9317                server
 9318                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9319                        &lsp::DidChangeWatchedFilesParams { changes },
 9320                    )
 9321                    .ok();
 9322            }
 9323            Some(())
 9324        });
 9325    }
 9326
 9327    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9328        self.as_local()?.language_server_for_id(id)
 9329    }
 9330
 9331    fn on_lsp_progress(
 9332        &mut self,
 9333        progress: lsp::ProgressParams,
 9334        language_server_id: LanguageServerId,
 9335        disk_based_diagnostics_progress_token: Option<String>,
 9336        cx: &mut Context<Self>,
 9337    ) {
 9338        let token = match progress.token {
 9339            lsp::NumberOrString::String(token) => token,
 9340            lsp::NumberOrString::Number(token) => {
 9341                log::info!("skipping numeric progress token {}", token);
 9342                return;
 9343            }
 9344        };
 9345
 9346        match progress.value {
 9347            lsp::ProgressParamsValue::WorkDone(progress) => {
 9348                self.handle_work_done_progress(
 9349                    progress,
 9350                    language_server_id,
 9351                    disk_based_diagnostics_progress_token,
 9352                    token,
 9353                    cx,
 9354                );
 9355            }
 9356            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9357                if let Some(LanguageServerState::Running {
 9358                    workspace_refresh_task: Some(workspace_refresh_task),
 9359                    ..
 9360                }) = self
 9361                    .as_local_mut()
 9362                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9363                {
 9364                    workspace_refresh_task.progress_tx.try_send(()).ok();
 9365                    self.apply_workspace_diagnostic_report(language_server_id, report, cx)
 9366                }
 9367            }
 9368        }
 9369    }
 9370
 9371    fn handle_work_done_progress(
 9372        &mut self,
 9373        progress: lsp::WorkDoneProgress,
 9374        language_server_id: LanguageServerId,
 9375        disk_based_diagnostics_progress_token: Option<String>,
 9376        token: String,
 9377        cx: &mut Context<Self>,
 9378    ) {
 9379        let language_server_status =
 9380            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9381                status
 9382            } else {
 9383                return;
 9384            };
 9385
 9386        if !language_server_status.progress_tokens.contains(&token) {
 9387            return;
 9388        }
 9389
 9390        let is_disk_based_diagnostics_progress = disk_based_diagnostics_progress_token
 9391            .as_ref()
 9392            .is_some_and(|disk_based_token| token.starts_with(disk_based_token));
 9393
 9394        match progress {
 9395            lsp::WorkDoneProgress::Begin(report) => {
 9396                if is_disk_based_diagnostics_progress {
 9397                    self.disk_based_diagnostics_started(language_server_id, cx);
 9398                }
 9399                self.on_lsp_work_start(
 9400                    language_server_id,
 9401                    token.clone(),
 9402                    LanguageServerProgress {
 9403                        title: Some(report.title),
 9404                        is_disk_based_diagnostics_progress,
 9405                        is_cancellable: report.cancellable.unwrap_or(false),
 9406                        message: report.message.clone(),
 9407                        percentage: report.percentage.map(|p| p as usize),
 9408                        last_update_at: cx.background_executor().now(),
 9409                    },
 9410                    cx,
 9411                );
 9412            }
 9413            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9414                language_server_id,
 9415                token,
 9416                LanguageServerProgress {
 9417                    title: None,
 9418                    is_disk_based_diagnostics_progress,
 9419                    is_cancellable: report.cancellable.unwrap_or(false),
 9420                    message: report.message,
 9421                    percentage: report.percentage.map(|p| p as usize),
 9422                    last_update_at: cx.background_executor().now(),
 9423                },
 9424                cx,
 9425            ),
 9426            lsp::WorkDoneProgress::End(_) => {
 9427                language_server_status.progress_tokens.remove(&token);
 9428                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9429                if is_disk_based_diagnostics_progress {
 9430                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9431                }
 9432            }
 9433        }
 9434    }
 9435
 9436    fn on_lsp_work_start(
 9437        &mut self,
 9438        language_server_id: LanguageServerId,
 9439        token: String,
 9440        progress: LanguageServerProgress,
 9441        cx: &mut Context<Self>,
 9442    ) {
 9443        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9444            status.pending_work.insert(token.clone(), progress.clone());
 9445            cx.notify();
 9446        }
 9447        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9448            language_server_id,
 9449            name: self
 9450                .language_server_adapter_for_id(language_server_id)
 9451                .map(|adapter| adapter.name()),
 9452            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9453                token,
 9454                title: progress.title,
 9455                message: progress.message,
 9456                percentage: progress.percentage.map(|p| p as u32),
 9457                is_cancellable: Some(progress.is_cancellable),
 9458            }),
 9459        })
 9460    }
 9461
 9462    fn on_lsp_work_progress(
 9463        &mut self,
 9464        language_server_id: LanguageServerId,
 9465        token: String,
 9466        progress: LanguageServerProgress,
 9467        cx: &mut Context<Self>,
 9468    ) {
 9469        let mut did_update = false;
 9470        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9471            match status.pending_work.entry(token.clone()) {
 9472                btree_map::Entry::Vacant(entry) => {
 9473                    entry.insert(progress.clone());
 9474                    did_update = true;
 9475                }
 9476                btree_map::Entry::Occupied(mut entry) => {
 9477                    let entry = entry.get_mut();
 9478                    if (progress.last_update_at - entry.last_update_at)
 9479                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9480                    {
 9481                        entry.last_update_at = progress.last_update_at;
 9482                        if progress.message.is_some() {
 9483                            entry.message = progress.message.clone();
 9484                        }
 9485                        if progress.percentage.is_some() {
 9486                            entry.percentage = progress.percentage;
 9487                        }
 9488                        if progress.is_cancellable != entry.is_cancellable {
 9489                            entry.is_cancellable = progress.is_cancellable;
 9490                        }
 9491                        did_update = true;
 9492                    }
 9493                }
 9494            }
 9495        }
 9496
 9497        if did_update {
 9498            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9499                language_server_id,
 9500                name: self
 9501                    .language_server_adapter_for_id(language_server_id)
 9502                    .map(|adapter| adapter.name()),
 9503                message: proto::update_language_server::Variant::WorkProgress(
 9504                    proto::LspWorkProgress {
 9505                        token,
 9506                        message: progress.message,
 9507                        percentage: progress.percentage.map(|p| p as u32),
 9508                        is_cancellable: Some(progress.is_cancellable),
 9509                    },
 9510                ),
 9511            })
 9512        }
 9513    }
 9514
 9515    fn on_lsp_work_end(
 9516        &mut self,
 9517        language_server_id: LanguageServerId,
 9518        token: String,
 9519        cx: &mut Context<Self>,
 9520    ) {
 9521        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9522            if let Some(work) = status.pending_work.remove(&token)
 9523                && !work.is_disk_based_diagnostics_progress
 9524            {
 9525                cx.emit(LspStoreEvent::RefreshInlayHints);
 9526            }
 9527            cx.notify();
 9528        }
 9529
 9530        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9531            language_server_id,
 9532            name: self
 9533                .language_server_adapter_for_id(language_server_id)
 9534                .map(|adapter| adapter.name()),
 9535            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd { token }),
 9536        })
 9537    }
 9538
 9539    pub async fn handle_resolve_completion_documentation(
 9540        this: Entity<Self>,
 9541        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
 9542        mut cx: AsyncApp,
 9543    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
 9544        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
 9545
 9546        let completion = this
 9547            .read_with(&cx, |this, cx| {
 9548                let id = LanguageServerId(envelope.payload.language_server_id as usize);
 9549                let server = this
 9550                    .language_server_for_id(id)
 9551                    .with_context(|| format!("No language server {id}"))?;
 9552
 9553                anyhow::Ok(cx.background_spawn(async move {
 9554                    let can_resolve = server
 9555                        .capabilities()
 9556                        .completion_provider
 9557                        .as_ref()
 9558                        .and_then(|options| options.resolve_provider)
 9559                        .unwrap_or(false);
 9560                    if can_resolve {
 9561                        server
 9562                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
 9563                            .await
 9564                            .into_response()
 9565                            .context("resolve completion item")
 9566                    } else {
 9567                        anyhow::Ok(lsp_completion)
 9568                    }
 9569                }))
 9570            })??
 9571            .await?;
 9572
 9573        let mut documentation_is_markdown = false;
 9574        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
 9575        let documentation = match completion.documentation {
 9576            Some(lsp::Documentation::String(text)) => text,
 9577
 9578            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
 9579                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
 9580                value
 9581            }
 9582
 9583            _ => String::new(),
 9584        };
 9585
 9586        // If we have a new buffer_id, that means we're talking to a new client
 9587        // and want to check for new text_edits in the completion too.
 9588        let mut old_replace_start = None;
 9589        let mut old_replace_end = None;
 9590        let mut old_insert_start = None;
 9591        let mut old_insert_end = None;
 9592        let mut new_text = String::default();
 9593        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
 9594            let buffer_snapshot = this.update(&mut cx, |this, cx| {
 9595                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9596                anyhow::Ok(buffer.read(cx).snapshot())
 9597            })??;
 9598
 9599            if let Some(text_edit) = completion.text_edit.as_ref() {
 9600                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
 9601
 9602                if let Some(mut edit) = edit {
 9603                    LineEnding::normalize(&mut edit.new_text);
 9604
 9605                    new_text = edit.new_text;
 9606                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
 9607                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
 9608                    if let Some(insert_range) = edit.insert_range {
 9609                        old_insert_start = Some(serialize_anchor(&insert_range.start));
 9610                        old_insert_end = Some(serialize_anchor(&insert_range.end));
 9611                    }
 9612                }
 9613            }
 9614        }
 9615
 9616        Ok(proto::ResolveCompletionDocumentationResponse {
 9617            documentation,
 9618            documentation_is_markdown,
 9619            old_replace_start,
 9620            old_replace_end,
 9621            new_text,
 9622            lsp_completion,
 9623            old_insert_start,
 9624            old_insert_end,
 9625        })
 9626    }
 9627
 9628    async fn handle_on_type_formatting(
 9629        this: Entity<Self>,
 9630        envelope: TypedEnvelope<proto::OnTypeFormatting>,
 9631        mut cx: AsyncApp,
 9632    ) -> Result<proto::OnTypeFormattingResponse> {
 9633        let on_type_formatting = this.update(&mut cx, |this, cx| {
 9634            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9635            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9636            let position = envelope
 9637                .payload
 9638                .position
 9639                .and_then(deserialize_anchor)
 9640                .context("invalid position")?;
 9641            anyhow::Ok(this.apply_on_type_formatting(
 9642                buffer,
 9643                position,
 9644                envelope.payload.trigger.clone(),
 9645                cx,
 9646            ))
 9647        })??;
 9648
 9649        let transaction = on_type_formatting
 9650            .await?
 9651            .as_ref()
 9652            .map(language::proto::serialize_transaction);
 9653        Ok(proto::OnTypeFormattingResponse { transaction })
 9654    }
 9655
 9656    async fn handle_refresh_inlay_hints(
 9657        this: Entity<Self>,
 9658        _: TypedEnvelope<proto::RefreshInlayHints>,
 9659        mut cx: AsyncApp,
 9660    ) -> Result<proto::Ack> {
 9661        this.update(&mut cx, |_, cx| {
 9662            cx.emit(LspStoreEvent::RefreshInlayHints);
 9663        })?;
 9664        Ok(proto::Ack {})
 9665    }
 9666
 9667    async fn handle_pull_workspace_diagnostics(
 9668        lsp_store: Entity<Self>,
 9669        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
 9670        mut cx: AsyncApp,
 9671    ) -> Result<proto::Ack> {
 9672        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
 9673        lsp_store.update(&mut cx, |lsp_store, _| {
 9674            lsp_store.pull_workspace_diagnostics(server_id);
 9675        })?;
 9676        Ok(proto::Ack {})
 9677    }
 9678
 9679    async fn handle_inlay_hints(
 9680        this: Entity<Self>,
 9681        envelope: TypedEnvelope<proto::InlayHints>,
 9682        mut cx: AsyncApp,
 9683    ) -> Result<proto::InlayHintsResponse> {
 9684        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9685        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9686        let buffer = this.update(&mut cx, |this, cx| {
 9687            this.buffer_store.read(cx).get_existing(buffer_id)
 9688        })??;
 9689        buffer
 9690            .update(&mut cx, |buffer, _| {
 9691                buffer.wait_for_version(deserialize_version(&envelope.payload.version))
 9692            })?
 9693            .await
 9694            .with_context(|| format!("waiting for version for buffer {}", buffer.entity_id()))?;
 9695
 9696        let start = envelope
 9697            .payload
 9698            .start
 9699            .and_then(deserialize_anchor)
 9700            .context("missing range start")?;
 9701        let end = envelope
 9702            .payload
 9703            .end
 9704            .and_then(deserialize_anchor)
 9705            .context("missing range end")?;
 9706        let buffer_hints = this
 9707            .update(&mut cx, |lsp_store, cx| {
 9708                lsp_store.inlay_hints(buffer.clone(), start..end, cx)
 9709            })?
 9710            .await
 9711            .context("inlay hints fetch")?;
 9712
 9713        this.update(&mut cx, |project, cx| {
 9714            InlayHints::response_to_proto(
 9715                buffer_hints,
 9716                project,
 9717                sender_id,
 9718                &buffer.read(cx).version(),
 9719                cx,
 9720            )
 9721        })
 9722    }
 9723
 9724    async fn handle_get_color_presentation(
 9725        lsp_store: Entity<Self>,
 9726        envelope: TypedEnvelope<proto::GetColorPresentation>,
 9727        mut cx: AsyncApp,
 9728    ) -> Result<proto::GetColorPresentationResponse> {
 9729        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9730        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9731            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9732        })??;
 9733
 9734        let color = envelope
 9735            .payload
 9736            .color
 9737            .context("invalid color resolve request")?;
 9738        let start = color
 9739            .lsp_range_start
 9740            .context("invalid color resolve request")?;
 9741        let end = color
 9742            .lsp_range_end
 9743            .context("invalid color resolve request")?;
 9744
 9745        let color = DocumentColor {
 9746            lsp_range: lsp::Range {
 9747                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
 9748                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
 9749            },
 9750            color: lsp::Color {
 9751                red: color.red,
 9752                green: color.green,
 9753                blue: color.blue,
 9754                alpha: color.alpha,
 9755            },
 9756            resolved: false,
 9757            color_presentations: Vec::new(),
 9758        };
 9759        let resolved_color = lsp_store
 9760            .update(&mut cx, |lsp_store, cx| {
 9761                lsp_store.resolve_color_presentation(
 9762                    color,
 9763                    buffer.clone(),
 9764                    LanguageServerId(envelope.payload.server_id as usize),
 9765                    cx,
 9766                )
 9767            })?
 9768            .await
 9769            .context("resolving color presentation")?;
 9770
 9771        Ok(proto::GetColorPresentationResponse {
 9772            presentations: resolved_color
 9773                .color_presentations
 9774                .into_iter()
 9775                .map(|presentation| proto::ColorPresentation {
 9776                    label: presentation.label.to_string(),
 9777                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
 9778                    additional_text_edits: presentation
 9779                        .additional_text_edits
 9780                        .into_iter()
 9781                        .map(serialize_lsp_edit)
 9782                        .collect(),
 9783                })
 9784                .collect(),
 9785        })
 9786    }
 9787
 9788    async fn handle_resolve_inlay_hint(
 9789        this: Entity<Self>,
 9790        envelope: TypedEnvelope<proto::ResolveInlayHint>,
 9791        mut cx: AsyncApp,
 9792    ) -> Result<proto::ResolveInlayHintResponse> {
 9793        let proto_hint = envelope
 9794            .payload
 9795            .hint
 9796            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
 9797        let hint = InlayHints::proto_to_project_hint(proto_hint)
 9798            .context("resolved proto inlay hint conversion")?;
 9799        let buffer = this.update(&mut cx, |this, cx| {
 9800            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9801            this.buffer_store.read(cx).get_existing(buffer_id)
 9802        })??;
 9803        let response_hint = this
 9804            .update(&mut cx, |this, cx| {
 9805                this.resolve_inlay_hint(
 9806                    hint,
 9807                    buffer,
 9808                    LanguageServerId(envelope.payload.language_server_id as usize),
 9809                    cx,
 9810                )
 9811            })?
 9812            .await
 9813            .context("inlay hints fetch")?;
 9814        Ok(proto::ResolveInlayHintResponse {
 9815            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
 9816        })
 9817    }
 9818
 9819    async fn handle_refresh_code_lens(
 9820        this: Entity<Self>,
 9821        _: TypedEnvelope<proto::RefreshCodeLens>,
 9822        mut cx: AsyncApp,
 9823    ) -> Result<proto::Ack> {
 9824        this.update(&mut cx, |_, cx| {
 9825            cx.emit(LspStoreEvent::RefreshCodeLens);
 9826        })?;
 9827        Ok(proto::Ack {})
 9828    }
 9829
 9830    async fn handle_open_buffer_for_symbol(
 9831        this: Entity<Self>,
 9832        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
 9833        mut cx: AsyncApp,
 9834    ) -> Result<proto::OpenBufferForSymbolResponse> {
 9835        let peer_id = envelope.original_sender_id().unwrap_or_default();
 9836        let symbol = envelope.payload.symbol.context("invalid symbol")?;
 9837        let symbol = Self::deserialize_symbol(symbol)?;
 9838        let symbol = this.read_with(&cx, |this, _| {
 9839            let signature = this.symbol_signature(&symbol.path);
 9840            anyhow::ensure!(signature == symbol.signature, "invalid symbol signature");
 9841            Ok(symbol)
 9842        })??;
 9843        let buffer = this
 9844            .update(&mut cx, |this, cx| {
 9845                this.open_buffer_for_symbol(
 9846                    &Symbol {
 9847                        language_server_name: symbol.language_server_name,
 9848                        source_worktree_id: symbol.source_worktree_id,
 9849                        source_language_server_id: symbol.source_language_server_id,
 9850                        path: symbol.path,
 9851                        name: symbol.name,
 9852                        kind: symbol.kind,
 9853                        range: symbol.range,
 9854                        signature: symbol.signature,
 9855                        label: CodeLabel {
 9856                            text: Default::default(),
 9857                            runs: Default::default(),
 9858                            filter_range: Default::default(),
 9859                        },
 9860                    },
 9861                    cx,
 9862                )
 9863            })?
 9864            .await?;
 9865
 9866        this.update(&mut cx, |this, cx| {
 9867            let is_private = buffer
 9868                .read(cx)
 9869                .file()
 9870                .map(|f| f.is_private())
 9871                .unwrap_or_default();
 9872            if is_private {
 9873                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
 9874            } else {
 9875                this.buffer_store
 9876                    .update(cx, |buffer_store, cx| {
 9877                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
 9878                    })
 9879                    .detach_and_log_err(cx);
 9880                let buffer_id = buffer.read(cx).remote_id().to_proto();
 9881                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
 9882            }
 9883        })?
 9884    }
 9885
 9886    fn symbol_signature(&self, project_path: &ProjectPath) -> [u8; 32] {
 9887        let mut hasher = Sha256::new();
 9888        hasher.update(project_path.worktree_id.to_proto().to_be_bytes());
 9889        hasher.update(project_path.path.to_string_lossy().as_bytes());
 9890        hasher.update(self.nonce.to_be_bytes());
 9891        hasher.finalize().as_slice().try_into().unwrap()
 9892    }
 9893
 9894    pub async fn handle_get_project_symbols(
 9895        this: Entity<Self>,
 9896        envelope: TypedEnvelope<proto::GetProjectSymbols>,
 9897        mut cx: AsyncApp,
 9898    ) -> Result<proto::GetProjectSymbolsResponse> {
 9899        let symbols = this
 9900            .update(&mut cx, |this, cx| {
 9901                this.symbols(&envelope.payload.query, cx)
 9902            })?
 9903            .await?;
 9904
 9905        Ok(proto::GetProjectSymbolsResponse {
 9906            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
 9907        })
 9908    }
 9909
 9910    pub async fn handle_restart_language_servers(
 9911        this: Entity<Self>,
 9912        envelope: TypedEnvelope<proto::RestartLanguageServers>,
 9913        mut cx: AsyncApp,
 9914    ) -> Result<proto::Ack> {
 9915        this.update(&mut cx, |lsp_store, cx| {
 9916            let buffers =
 9917                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9918            lsp_store.restart_language_servers_for_buffers(
 9919                buffers,
 9920                envelope
 9921                    .payload
 9922                    .only_servers
 9923                    .into_iter()
 9924                    .filter_map(|selector| {
 9925                        Some(match selector.selector? {
 9926                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9927                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9928                            }
 9929                            proto::language_server_selector::Selector::Name(name) => {
 9930                                LanguageServerSelector::Name(LanguageServerName(
 9931                                    SharedString::from(name),
 9932                                ))
 9933                            }
 9934                        })
 9935                    })
 9936                    .collect(),
 9937                cx,
 9938            );
 9939        })?;
 9940
 9941        Ok(proto::Ack {})
 9942    }
 9943
 9944    pub async fn handle_stop_language_servers(
 9945        lsp_store: Entity<Self>,
 9946        envelope: TypedEnvelope<proto::StopLanguageServers>,
 9947        mut cx: AsyncApp,
 9948    ) -> Result<proto::Ack> {
 9949        lsp_store.update(&mut cx, |lsp_store, cx| {
 9950            if envelope.payload.all
 9951                && envelope.payload.also_servers.is_empty()
 9952                && envelope.payload.buffer_ids.is_empty()
 9953            {
 9954                lsp_store.stop_all_language_servers(cx);
 9955            } else {
 9956                let buffers =
 9957                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9958                lsp_store
 9959                    .stop_language_servers_for_buffers(
 9960                        buffers,
 9961                        envelope
 9962                            .payload
 9963                            .also_servers
 9964                            .into_iter()
 9965                            .filter_map(|selector| {
 9966                                Some(match selector.selector? {
 9967                                    proto::language_server_selector::Selector::ServerId(
 9968                                        server_id,
 9969                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
 9970                                        server_id,
 9971                                    )),
 9972                                    proto::language_server_selector::Selector::Name(name) => {
 9973                                        LanguageServerSelector::Name(LanguageServerName(
 9974                                            SharedString::from(name),
 9975                                        ))
 9976                                    }
 9977                                })
 9978                            })
 9979                            .collect(),
 9980                        cx,
 9981                    )
 9982                    .detach_and_log_err(cx);
 9983            }
 9984        })?;
 9985
 9986        Ok(proto::Ack {})
 9987    }
 9988
 9989    pub async fn handle_cancel_language_server_work(
 9990        this: Entity<Self>,
 9991        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
 9992        mut cx: AsyncApp,
 9993    ) -> Result<proto::Ack> {
 9994        this.update(&mut cx, |this, cx| {
 9995            if let Some(work) = envelope.payload.work {
 9996                match work {
 9997                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
 9998                        let buffers =
 9999                            this.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10000                        this.cancel_language_server_work_for_buffers(buffers, cx);
10001                    }
10002                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10003                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10004                        this.cancel_language_server_work(server_id, work.token, cx);
10005                    }
10006                }
10007            }
10008        })?;
10009
10010        Ok(proto::Ack {})
10011    }
10012
10013    fn buffer_ids_to_buffers(
10014        &mut self,
10015        buffer_ids: impl Iterator<Item = u64>,
10016        cx: &mut Context<Self>,
10017    ) -> Vec<Entity<Buffer>> {
10018        buffer_ids
10019            .into_iter()
10020            .flat_map(|buffer_id| {
10021                self.buffer_store
10022                    .read(cx)
10023                    .get(BufferId::new(buffer_id).log_err()?)
10024            })
10025            .collect::<Vec<_>>()
10026    }
10027
10028    async fn handle_apply_additional_edits_for_completion(
10029        this: Entity<Self>,
10030        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10031        mut cx: AsyncApp,
10032    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10033        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10034            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10035            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10036            let completion = Self::deserialize_completion(
10037                envelope.payload.completion.context("invalid completion")?,
10038            )?;
10039            anyhow::Ok((buffer, completion))
10040        })??;
10041
10042        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10043            this.apply_additional_edits_for_completion(
10044                buffer,
10045                Rc::new(RefCell::new(Box::new([Completion {
10046                    replace_range: completion.replace_range,
10047                    new_text: completion.new_text,
10048                    source: completion.source,
10049                    documentation: None,
10050                    label: CodeLabel {
10051                        text: Default::default(),
10052                        runs: Default::default(),
10053                        filter_range: Default::default(),
10054                    },
10055                    insert_text_mode: None,
10056                    icon_path: None,
10057                    confirm: None,
10058                }]))),
10059                0,
10060                false,
10061                cx,
10062            )
10063        })?;
10064
10065        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10066            transaction: apply_additional_edits
10067                .await?
10068                .as_ref()
10069                .map(language::proto::serialize_transaction),
10070        })
10071    }
10072
10073    pub fn last_formatting_failure(&self) -> Option<&str> {
10074        self.last_formatting_failure.as_deref()
10075    }
10076
10077    pub fn reset_last_formatting_failure(&mut self) {
10078        self.last_formatting_failure = None;
10079    }
10080
10081    pub fn environment_for_buffer(
10082        &self,
10083        buffer: &Entity<Buffer>,
10084        cx: &mut Context<Self>,
10085    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10086        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10087            environment.update(cx, |env, cx| {
10088                env.get_buffer_environment(buffer, &self.worktree_store, cx)
10089            })
10090        } else {
10091            Task::ready(None).shared()
10092        }
10093    }
10094
10095    pub fn format(
10096        &mut self,
10097        buffers: HashSet<Entity<Buffer>>,
10098        target: LspFormatTarget,
10099        push_to_history: bool,
10100        trigger: FormatTrigger,
10101        cx: &mut Context<Self>,
10102    ) -> Task<anyhow::Result<ProjectTransaction>> {
10103        let logger = zlog::scoped!("format");
10104        if self.as_local().is_some() {
10105            zlog::trace!(logger => "Formatting locally");
10106            let logger = zlog::scoped!(logger => "local");
10107            let buffers = buffers
10108                .into_iter()
10109                .map(|buffer_handle| {
10110                    let buffer = buffer_handle.read(cx);
10111                    let buffer_abs_path = File::from_dyn(buffer.file())
10112                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10113
10114                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10115                })
10116                .collect::<Vec<_>>();
10117
10118            cx.spawn(async move |lsp_store, cx| {
10119                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10120
10121                for (handle, abs_path, id) in buffers {
10122                    let env = lsp_store
10123                        .update(cx, |lsp_store, cx| {
10124                            lsp_store.environment_for_buffer(&handle, cx)
10125                        })?
10126                        .await;
10127
10128                    let ranges = match &target {
10129                        LspFormatTarget::Buffers => None,
10130                        LspFormatTarget::Ranges(ranges) => {
10131                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10132                        }
10133                    };
10134
10135                    formattable_buffers.push(FormattableBuffer {
10136                        handle,
10137                        abs_path,
10138                        env,
10139                        ranges,
10140                    });
10141                }
10142                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10143
10144                let format_timer = zlog::time!(logger => "Formatting buffers");
10145                let result = LocalLspStore::format_locally(
10146                    lsp_store.clone(),
10147                    formattable_buffers,
10148                    push_to_history,
10149                    trigger,
10150                    logger,
10151                    cx,
10152                )
10153                .await;
10154                format_timer.end();
10155
10156                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10157
10158                lsp_store.update(cx, |lsp_store, _| {
10159                    lsp_store.update_last_formatting_failure(&result);
10160                })?;
10161
10162                result
10163            })
10164        } else if let Some((client, project_id)) = self.upstream_client() {
10165            zlog::trace!(logger => "Formatting remotely");
10166            let logger = zlog::scoped!(logger => "remote");
10167            // Don't support formatting ranges via remote
10168            match target {
10169                LspFormatTarget::Buffers => {}
10170                LspFormatTarget::Ranges(_) => {
10171                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10172                    return Task::ready(Ok(ProjectTransaction::default()));
10173                }
10174            }
10175
10176            let buffer_store = self.buffer_store();
10177            cx.spawn(async move |lsp_store, cx| {
10178                zlog::trace!(logger => "Sending remote format request");
10179                let request_timer = zlog::time!(logger => "remote format request");
10180                let result = client
10181                    .request(proto::FormatBuffers {
10182                        project_id,
10183                        trigger: trigger as i32,
10184                        buffer_ids: buffers
10185                            .iter()
10186                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10187                            .collect::<Result<_>>()?,
10188                    })
10189                    .await
10190                    .and_then(|result| result.transaction.context("missing transaction"));
10191                request_timer.end();
10192
10193                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10194
10195                lsp_store.update(cx, |lsp_store, _| {
10196                    lsp_store.update_last_formatting_failure(&result);
10197                })?;
10198
10199                let transaction_response = result?;
10200                let _timer = zlog::time!(logger => "deserializing project transaction");
10201                buffer_store
10202                    .update(cx, |buffer_store, cx| {
10203                        buffer_store.deserialize_project_transaction(
10204                            transaction_response,
10205                            push_to_history,
10206                            cx,
10207                        )
10208                    })?
10209                    .await
10210            })
10211        } else {
10212            zlog::trace!(logger => "Not formatting");
10213            Task::ready(Ok(ProjectTransaction::default()))
10214        }
10215    }
10216
10217    async fn handle_format_buffers(
10218        this: Entity<Self>,
10219        envelope: TypedEnvelope<proto::FormatBuffers>,
10220        mut cx: AsyncApp,
10221    ) -> Result<proto::FormatBuffersResponse> {
10222        let sender_id = envelope.original_sender_id().unwrap_or_default();
10223        let format = this.update(&mut cx, |this, cx| {
10224            let mut buffers = HashSet::default();
10225            for buffer_id in &envelope.payload.buffer_ids {
10226                let buffer_id = BufferId::new(*buffer_id)?;
10227                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10228            }
10229            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10230            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10231        })??;
10232
10233        let project_transaction = format.await?;
10234        let project_transaction = this.update(&mut cx, |this, cx| {
10235            this.buffer_store.update(cx, |buffer_store, cx| {
10236                buffer_store.serialize_project_transaction_for_peer(
10237                    project_transaction,
10238                    sender_id,
10239                    cx,
10240                )
10241            })
10242        })?;
10243        Ok(proto::FormatBuffersResponse {
10244            transaction: Some(project_transaction),
10245        })
10246    }
10247
10248    async fn handle_apply_code_action_kind(
10249        this: Entity<Self>,
10250        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10251        mut cx: AsyncApp,
10252    ) -> Result<proto::ApplyCodeActionKindResponse> {
10253        let sender_id = envelope.original_sender_id().unwrap_or_default();
10254        let format = this.update(&mut cx, |this, cx| {
10255            let mut buffers = HashSet::default();
10256            for buffer_id in &envelope.payload.buffer_ids {
10257                let buffer_id = BufferId::new(*buffer_id)?;
10258                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10259            }
10260            let kind = match envelope.payload.kind.as_str() {
10261                "" => CodeActionKind::EMPTY,
10262                "quickfix" => CodeActionKind::QUICKFIX,
10263                "refactor" => CodeActionKind::REFACTOR,
10264                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10265                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10266                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10267                "source" => CodeActionKind::SOURCE,
10268                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10269                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10270                _ => anyhow::bail!(
10271                    "Invalid code action kind {}",
10272                    envelope.payload.kind.as_str()
10273                ),
10274            };
10275            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10276        })??;
10277
10278        let project_transaction = format.await?;
10279        let project_transaction = this.update(&mut cx, |this, cx| {
10280            this.buffer_store.update(cx, |buffer_store, cx| {
10281                buffer_store.serialize_project_transaction_for_peer(
10282                    project_transaction,
10283                    sender_id,
10284                    cx,
10285                )
10286            })
10287        })?;
10288        Ok(proto::ApplyCodeActionKindResponse {
10289            transaction: Some(project_transaction),
10290        })
10291    }
10292
10293    async fn shutdown_language_server(
10294        server_state: Option<LanguageServerState>,
10295        name: LanguageServerName,
10296        cx: &mut AsyncApp,
10297    ) {
10298        let server = match server_state {
10299            Some(LanguageServerState::Starting { startup, .. }) => {
10300                let mut timer = cx
10301                    .background_executor()
10302                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10303                    .fuse();
10304
10305                select! {
10306                    server = startup.fuse() => server,
10307                    () = timer => {
10308                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10309                        None
10310                    },
10311                }
10312            }
10313
10314            Some(LanguageServerState::Running { server, .. }) => Some(server),
10315
10316            None => None,
10317        };
10318
10319        if let Some(server) = server
10320            && let Some(shutdown) = server.shutdown()
10321        {
10322            shutdown.await;
10323        }
10324    }
10325
10326    // Returns a list of all of the worktrees which no longer have a language server and the root path
10327    // for the stopped server
10328    fn stop_local_language_server(
10329        &mut self,
10330        server_id: LanguageServerId,
10331        cx: &mut Context<Self>,
10332    ) -> Task<()> {
10333        let local = match &mut self.mode {
10334            LspStoreMode::Local(local) => local,
10335            _ => {
10336                return Task::ready(());
10337            }
10338        };
10339
10340        // Remove this server ID from all entries in the given worktree.
10341        local
10342            .language_server_ids
10343            .retain(|_, state| state.id != server_id);
10344        self.buffer_store.update(cx, |buffer_store, cx| {
10345            for buffer in buffer_store.buffers() {
10346                buffer.update(cx, |buffer, cx| {
10347                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10348                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10349                });
10350            }
10351        });
10352
10353        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10354            summaries.retain(|path, summaries_by_server_id| {
10355                if summaries_by_server_id.remove(&server_id).is_some() {
10356                    if let Some((client, project_id)) = self.downstream_client.clone() {
10357                        client
10358                            .send(proto::UpdateDiagnosticSummary {
10359                                project_id,
10360                                worktree_id: worktree_id.to_proto(),
10361                                summary: Some(proto::DiagnosticSummary {
10362                                    path: path.as_ref().to_proto(),
10363                                    language_server_id: server_id.0 as u64,
10364                                    error_count: 0,
10365                                    warning_count: 0,
10366                                }),
10367                                more_summaries: Vec::new(),
10368                            })
10369                            .log_err();
10370                    }
10371                    !summaries_by_server_id.is_empty()
10372                } else {
10373                    true
10374                }
10375            });
10376        }
10377
10378        let local = self.as_local_mut().unwrap();
10379        for diagnostics in local.diagnostics.values_mut() {
10380            diagnostics.retain(|_, diagnostics_by_server_id| {
10381                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10382                    diagnostics_by_server_id.remove(ix);
10383                    !diagnostics_by_server_id.is_empty()
10384                } else {
10385                    true
10386                }
10387            });
10388        }
10389        local.language_server_watched_paths.remove(&server_id);
10390
10391        let server_state = local.language_servers.remove(&server_id);
10392        self.cleanup_lsp_data(server_id);
10393        let name = self
10394            .language_server_statuses
10395            .remove(&server_id)
10396            .map(|status| status.name)
10397            .or_else(|| {
10398                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10399                    Some(adapter.name())
10400                } else {
10401                    None
10402                }
10403            });
10404
10405        if let Some(name) = name {
10406            log::info!("stopping language server {name}");
10407            self.languages
10408                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10409            cx.notify();
10410
10411            return cx.spawn(async move |lsp_store, cx| {
10412                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10413                lsp_store
10414                    .update(cx, |lsp_store, cx| {
10415                        lsp_store
10416                            .languages
10417                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10418                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10419                        cx.notify();
10420                    })
10421                    .ok();
10422            });
10423        }
10424
10425        if server_state.is_some() {
10426            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10427        }
10428        Task::ready(())
10429    }
10430
10431    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10432        if let Some((client, project_id)) = self.upstream_client() {
10433            let request = client.request(proto::StopLanguageServers {
10434                project_id,
10435                buffer_ids: Vec::new(),
10436                also_servers: Vec::new(),
10437                all: true,
10438            });
10439            cx.background_spawn(request).detach_and_log_err(cx);
10440        } else {
10441            let Some(local) = self.as_local_mut() else {
10442                return;
10443            };
10444            let language_servers_to_stop = local
10445                .language_server_ids
10446                .values()
10447                .map(|state| state.id)
10448                .collect();
10449            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10450            let tasks = language_servers_to_stop
10451                .into_iter()
10452                .map(|server| self.stop_local_language_server(server, cx))
10453                .collect::<Vec<_>>();
10454            cx.background_spawn(async move {
10455                futures::future::join_all(tasks).await;
10456            })
10457            .detach();
10458        }
10459    }
10460
10461    pub fn restart_language_servers_for_buffers(
10462        &mut self,
10463        buffers: Vec<Entity<Buffer>>,
10464        only_restart_servers: HashSet<LanguageServerSelector>,
10465        cx: &mut Context<Self>,
10466    ) {
10467        if let Some((client, project_id)) = self.upstream_client() {
10468            let request = client.request(proto::RestartLanguageServers {
10469                project_id,
10470                buffer_ids: buffers
10471                    .into_iter()
10472                    .map(|b| b.read(cx).remote_id().to_proto())
10473                    .collect(),
10474                only_servers: only_restart_servers
10475                    .into_iter()
10476                    .map(|selector| {
10477                        let selector = match selector {
10478                            LanguageServerSelector::Id(language_server_id) => {
10479                                proto::language_server_selector::Selector::ServerId(
10480                                    language_server_id.to_proto(),
10481                                )
10482                            }
10483                            LanguageServerSelector::Name(language_server_name) => {
10484                                proto::language_server_selector::Selector::Name(
10485                                    language_server_name.to_string(),
10486                                )
10487                            }
10488                        };
10489                        proto::LanguageServerSelector {
10490                            selector: Some(selector),
10491                        }
10492                    })
10493                    .collect(),
10494                all: false,
10495            });
10496            cx.background_spawn(request).detach_and_log_err(cx);
10497        } else {
10498            let stop_task = if only_restart_servers.is_empty() {
10499                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10500            } else {
10501                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10502            };
10503            cx.spawn(async move |lsp_store, cx| {
10504                stop_task.await;
10505                lsp_store
10506                    .update(cx, |lsp_store, cx| {
10507                        for buffer in buffers {
10508                            lsp_store.register_buffer_with_language_servers(
10509                                &buffer,
10510                                only_restart_servers.clone(),
10511                                true,
10512                                cx,
10513                            );
10514                        }
10515                    })
10516                    .ok()
10517            })
10518            .detach();
10519        }
10520    }
10521
10522    pub fn stop_language_servers_for_buffers(
10523        &mut self,
10524        buffers: Vec<Entity<Buffer>>,
10525        also_stop_servers: HashSet<LanguageServerSelector>,
10526        cx: &mut Context<Self>,
10527    ) -> Task<Result<()>> {
10528        if let Some((client, project_id)) = self.upstream_client() {
10529            let request = client.request(proto::StopLanguageServers {
10530                project_id,
10531                buffer_ids: buffers
10532                    .into_iter()
10533                    .map(|b| b.read(cx).remote_id().to_proto())
10534                    .collect(),
10535                also_servers: also_stop_servers
10536                    .into_iter()
10537                    .map(|selector| {
10538                        let selector = match selector {
10539                            LanguageServerSelector::Id(language_server_id) => {
10540                                proto::language_server_selector::Selector::ServerId(
10541                                    language_server_id.to_proto(),
10542                                )
10543                            }
10544                            LanguageServerSelector::Name(language_server_name) => {
10545                                proto::language_server_selector::Selector::Name(
10546                                    language_server_name.to_string(),
10547                                )
10548                            }
10549                        };
10550                        proto::LanguageServerSelector {
10551                            selector: Some(selector),
10552                        }
10553                    })
10554                    .collect(),
10555                all: false,
10556            });
10557            cx.background_spawn(async move {
10558                let _ = request.await?;
10559                Ok(())
10560            })
10561        } else {
10562            let task =
10563                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10564            cx.background_spawn(async move {
10565                task.await;
10566                Ok(())
10567            })
10568        }
10569    }
10570
10571    fn stop_local_language_servers_for_buffers(
10572        &mut self,
10573        buffers: &[Entity<Buffer>],
10574        also_stop_servers: HashSet<LanguageServerSelector>,
10575        cx: &mut Context<Self>,
10576    ) -> Task<()> {
10577        let Some(local) = self.as_local_mut() else {
10578            return Task::ready(());
10579        };
10580        let mut language_server_names_to_stop = BTreeSet::default();
10581        let mut language_servers_to_stop = also_stop_servers
10582            .into_iter()
10583            .flat_map(|selector| match selector {
10584                LanguageServerSelector::Id(id) => Some(id),
10585                LanguageServerSelector::Name(name) => {
10586                    language_server_names_to_stop.insert(name);
10587                    None
10588                }
10589            })
10590            .collect::<BTreeSet<_>>();
10591
10592        let mut covered_worktrees = HashSet::default();
10593        for buffer in buffers {
10594            buffer.update(cx, |buffer, cx| {
10595                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
10596                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
10597                    && covered_worktrees.insert(worktree_id)
10598                {
10599                    language_server_names_to_stop.retain(|name| {
10600                        let old_ids_count = language_servers_to_stop.len();
10601                        let all_language_servers_with_this_name = local
10602                            .language_server_ids
10603                            .iter()
10604                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
10605                        language_servers_to_stop.extend(all_language_servers_with_this_name);
10606                        old_ids_count == language_servers_to_stop.len()
10607                    });
10608                }
10609            });
10610        }
10611        for name in language_server_names_to_stop {
10612            language_servers_to_stop.extend(
10613                local
10614                    .language_server_ids
10615                    .iter()
10616                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
10617            );
10618        }
10619
10620        local.lsp_tree.remove_nodes(&language_servers_to_stop);
10621        let tasks = language_servers_to_stop
10622            .into_iter()
10623            .map(|server| self.stop_local_language_server(server, cx))
10624            .collect::<Vec<_>>();
10625
10626        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
10627    }
10628
10629    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
10630        let (worktree, relative_path) =
10631            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
10632
10633        let project_path = ProjectPath {
10634            worktree_id: worktree.read(cx).id(),
10635            path: relative_path.into(),
10636        };
10637
10638        Some(
10639            self.buffer_store()
10640                .read(cx)
10641                .get_by_path(&project_path)?
10642                .read(cx),
10643        )
10644    }
10645
10646    #[cfg(any(test, feature = "test-support"))]
10647    pub fn update_diagnostics(
10648        &mut self,
10649        server_id: LanguageServerId,
10650        diagnostics: lsp::PublishDiagnosticsParams,
10651        result_id: Option<String>,
10652        source_kind: DiagnosticSourceKind,
10653        disk_based_sources: &[String],
10654        cx: &mut Context<Self>,
10655    ) -> Result<()> {
10656        self.merge_lsp_diagnostics(
10657            source_kind,
10658            vec![DocumentDiagnosticsUpdate {
10659                diagnostics,
10660                result_id,
10661                server_id,
10662                disk_based_sources: Cow::Borrowed(disk_based_sources),
10663            }],
10664            |_, _, _| false,
10665            cx,
10666        )
10667    }
10668
10669    pub fn merge_lsp_diagnostics(
10670        &mut self,
10671        source_kind: DiagnosticSourceKind,
10672        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
10673        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
10674        cx: &mut Context<Self>,
10675    ) -> Result<()> {
10676        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
10677        let updates = lsp_diagnostics
10678            .into_iter()
10679            .filter_map(|update| {
10680                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
10681                Some(DocumentDiagnosticsUpdate {
10682                    diagnostics: self.lsp_to_document_diagnostics(
10683                        abs_path,
10684                        source_kind,
10685                        update.server_id,
10686                        update.diagnostics,
10687                        &update.disk_based_sources,
10688                    ),
10689                    result_id: update.result_id,
10690                    server_id: update.server_id,
10691                    disk_based_sources: update.disk_based_sources,
10692                })
10693            })
10694            .collect();
10695        self.merge_diagnostic_entries(updates, merge, cx)?;
10696        Ok(())
10697    }
10698
10699    fn lsp_to_document_diagnostics(
10700        &mut self,
10701        document_abs_path: PathBuf,
10702        source_kind: DiagnosticSourceKind,
10703        server_id: LanguageServerId,
10704        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
10705        disk_based_sources: &[String],
10706    ) -> DocumentDiagnostics {
10707        let mut diagnostics = Vec::default();
10708        let mut primary_diagnostic_group_ids = HashMap::default();
10709        let mut sources_by_group_id = HashMap::default();
10710        let mut supporting_diagnostics = HashMap::default();
10711
10712        let adapter = self.language_server_adapter_for_id(server_id);
10713
10714        // Ensure that primary diagnostics are always the most severe
10715        lsp_diagnostics
10716            .diagnostics
10717            .sort_by_key(|item| item.severity);
10718
10719        for diagnostic in &lsp_diagnostics.diagnostics {
10720            let source = diagnostic.source.as_ref();
10721            let range = range_from_lsp(diagnostic.range);
10722            let is_supporting = diagnostic
10723                .related_information
10724                .as_ref()
10725                .is_some_and(|infos| {
10726                    infos.iter().any(|info| {
10727                        primary_diagnostic_group_ids.contains_key(&(
10728                            source,
10729                            diagnostic.code.clone(),
10730                            range_from_lsp(info.location.range),
10731                        ))
10732                    })
10733                });
10734
10735            let is_unnecessary = diagnostic
10736                .tags
10737                .as_ref()
10738                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
10739
10740            let underline = self
10741                .language_server_adapter_for_id(server_id)
10742                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
10743
10744            if is_supporting {
10745                supporting_diagnostics.insert(
10746                    (source, diagnostic.code.clone(), range),
10747                    (diagnostic.severity, is_unnecessary),
10748                );
10749            } else {
10750                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
10751                let is_disk_based =
10752                    source.is_some_and(|source| disk_based_sources.contains(source));
10753
10754                sources_by_group_id.insert(group_id, source);
10755                primary_diagnostic_group_ids
10756                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
10757
10758                diagnostics.push(DiagnosticEntry {
10759                    range,
10760                    diagnostic: Diagnostic {
10761                        source: diagnostic.source.clone(),
10762                        source_kind,
10763                        code: diagnostic.code.clone(),
10764                        code_description: diagnostic
10765                            .code_description
10766                            .as_ref()
10767                            .and_then(|d| d.href.clone()),
10768                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
10769                        markdown: adapter.as_ref().and_then(|adapter| {
10770                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
10771                        }),
10772                        message: diagnostic.message.trim().to_string(),
10773                        group_id,
10774                        is_primary: true,
10775                        is_disk_based,
10776                        is_unnecessary,
10777                        underline,
10778                        data: diagnostic.data.clone(),
10779                    },
10780                });
10781                if let Some(infos) = &diagnostic.related_information {
10782                    for info in infos {
10783                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
10784                            let range = range_from_lsp(info.location.range);
10785                            diagnostics.push(DiagnosticEntry {
10786                                range,
10787                                diagnostic: Diagnostic {
10788                                    source: diagnostic.source.clone(),
10789                                    source_kind,
10790                                    code: diagnostic.code.clone(),
10791                                    code_description: diagnostic
10792                                        .code_description
10793                                        .as_ref()
10794                                        .and_then(|d| d.href.clone()),
10795                                    severity: DiagnosticSeverity::INFORMATION,
10796                                    markdown: adapter.as_ref().and_then(|adapter| {
10797                                        adapter.diagnostic_message_to_markdown(&info.message)
10798                                    }),
10799                                    message: info.message.trim().to_string(),
10800                                    group_id,
10801                                    is_primary: false,
10802                                    is_disk_based,
10803                                    is_unnecessary: false,
10804                                    underline,
10805                                    data: diagnostic.data.clone(),
10806                                },
10807                            });
10808                        }
10809                    }
10810                }
10811            }
10812        }
10813
10814        for entry in &mut diagnostics {
10815            let diagnostic = &mut entry.diagnostic;
10816            if !diagnostic.is_primary {
10817                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
10818                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
10819                    source,
10820                    diagnostic.code.clone(),
10821                    entry.range.clone(),
10822                )) {
10823                    if let Some(severity) = severity {
10824                        diagnostic.severity = severity;
10825                    }
10826                    diagnostic.is_unnecessary = is_unnecessary;
10827                }
10828            }
10829        }
10830
10831        DocumentDiagnostics {
10832            diagnostics,
10833            document_abs_path,
10834            version: lsp_diagnostics.version,
10835        }
10836    }
10837
10838    fn insert_newly_running_language_server(
10839        &mut self,
10840        adapter: Arc<CachedLspAdapter>,
10841        language_server: Arc<LanguageServer>,
10842        server_id: LanguageServerId,
10843        key: LanguageServerSeed,
10844        workspace_folders: Arc<Mutex<BTreeSet<Url>>>,
10845        cx: &mut Context<Self>,
10846    ) {
10847        let Some(local) = self.as_local_mut() else {
10848            return;
10849        };
10850        // If the language server for this key doesn't match the server id, don't store the
10851        // server. Which will cause it to be dropped, killing the process
10852        if local
10853            .language_server_ids
10854            .get(&key)
10855            .map(|state| state.id != server_id)
10856            .unwrap_or(false)
10857        {
10858            return;
10859        }
10860
10861        // Update language_servers collection with Running variant of LanguageServerState
10862        // indicating that the server is up and running and ready
10863        let workspace_folders = workspace_folders.lock().clone();
10864        language_server.set_workspace_folders(workspace_folders);
10865
10866        local.language_servers.insert(
10867            server_id,
10868            LanguageServerState::Running {
10869                workspace_refresh_task: lsp_workspace_diagnostics_refresh(
10870                    language_server.clone(),
10871                    cx,
10872                ),
10873                adapter: adapter.clone(),
10874                server: language_server.clone(),
10875                simulate_disk_based_diagnostics_completion: None,
10876            },
10877        );
10878        local
10879            .languages
10880            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
10881        if let Some(file_ops_caps) = language_server
10882            .capabilities()
10883            .workspace
10884            .as_ref()
10885            .and_then(|ws| ws.file_operations.as_ref())
10886        {
10887            let did_rename_caps = file_ops_caps.did_rename.as_ref();
10888            let will_rename_caps = file_ops_caps.will_rename.as_ref();
10889            if did_rename_caps.or(will_rename_caps).is_some() {
10890                let watcher = RenamePathsWatchedForServer::default()
10891                    .with_did_rename_patterns(did_rename_caps)
10892                    .with_will_rename_patterns(will_rename_caps);
10893                local
10894                    .language_server_paths_watched_for_rename
10895                    .insert(server_id, watcher);
10896            }
10897        }
10898
10899        self.language_server_statuses.insert(
10900            server_id,
10901            LanguageServerStatus {
10902                name: language_server.name(),
10903                pending_work: Default::default(),
10904                has_pending_diagnostic_updates: false,
10905                progress_tokens: Default::default(),
10906            },
10907        );
10908
10909        cx.emit(LspStoreEvent::LanguageServerAdded(
10910            server_id,
10911            language_server.name(),
10912            Some(key.worktree_id),
10913        ));
10914        cx.emit(LspStoreEvent::RefreshInlayHints);
10915
10916        let server_capabilities = language_server.capabilities();
10917        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
10918            downstream_client
10919                .send(proto::StartLanguageServer {
10920                    project_id: *project_id,
10921                    server: Some(proto::LanguageServer {
10922                        id: server_id.to_proto(),
10923                        name: language_server.name().to_string(),
10924                        worktree_id: Some(key.worktree_id.to_proto()),
10925                    }),
10926                    capabilities: serde_json::to_string(&server_capabilities)
10927                        .expect("serializing server LSP capabilities"),
10928                })
10929                .log_err();
10930        }
10931        self.lsp_server_capabilities
10932            .insert(server_id, server_capabilities);
10933
10934        // Tell the language server about every open buffer in the worktree that matches the language.
10935        // Also check for buffers in worktrees that reused this server
10936        let mut worktrees_using_server = vec![key.worktree_id];
10937        if let Some(local) = self.as_local() {
10938            // Find all worktrees that have this server in their language server tree
10939            for (worktree_id, servers) in &local.lsp_tree.instances {
10940                if *worktree_id != key.worktree_id {
10941                    for server_map in servers.roots.values() {
10942                        if server_map.contains_key(&key.name) {
10943                            worktrees_using_server.push(*worktree_id);
10944                        }
10945                    }
10946                }
10947            }
10948        }
10949
10950        let mut buffer_paths_registered = Vec::new();
10951        self.buffer_store.clone().update(cx, |buffer_store, cx| {
10952            for buffer_handle in buffer_store.buffers() {
10953                let buffer = buffer_handle.read(cx);
10954                let file = match File::from_dyn(buffer.file()) {
10955                    Some(file) => file,
10956                    None => continue,
10957                };
10958                let language = match buffer.language() {
10959                    Some(language) => language,
10960                    None => continue,
10961                };
10962
10963                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
10964                    || !self
10965                        .languages
10966                        .lsp_adapters(&language.name())
10967                        .iter()
10968                        .any(|a| a.name == key.name)
10969                {
10970                    continue;
10971                }
10972                // didOpen
10973                let file = match file.as_local() {
10974                    Some(file) => file,
10975                    None => continue,
10976                };
10977
10978                let local = self.as_local_mut().unwrap();
10979
10980                let buffer_id = buffer.remote_id();
10981                if local.registered_buffers.contains_key(&buffer_id) {
10982                    let versions = local
10983                        .buffer_snapshots
10984                        .entry(buffer_id)
10985                        .or_default()
10986                        .entry(server_id)
10987                        .and_modify(|_| {
10988                            assert!(
10989                            false,
10990                            "There should not be an existing snapshot for a newly inserted buffer"
10991                        )
10992                        })
10993                        .or_insert_with(|| {
10994                            vec![LspBufferSnapshot {
10995                                version: 0,
10996                                snapshot: buffer.text_snapshot(),
10997                            }]
10998                        });
10999
11000                    let snapshot = versions.last().unwrap();
11001                    let version = snapshot.version;
11002                    let initial_snapshot = &snapshot.snapshot;
11003                    let uri = lsp::Url::from_file_path(file.abs_path(cx)).unwrap();
11004                    language_server.register_buffer(
11005                        uri,
11006                        adapter.language_id(&language.name()),
11007                        version,
11008                        initial_snapshot.text(),
11009                    );
11010                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11011                    local
11012                        .buffers_opened_in_servers
11013                        .entry(buffer_id)
11014                        .or_default()
11015                        .insert(server_id);
11016                }
11017                buffer_handle.update(cx, |buffer, cx| {
11018                    buffer.set_completion_triggers(
11019                        server_id,
11020                        language_server
11021                            .capabilities()
11022                            .completion_provider
11023                            .as_ref()
11024                            .and_then(|provider| {
11025                                provider
11026                                    .trigger_characters
11027                                    .as_ref()
11028                                    .map(|characters| characters.iter().cloned().collect())
11029                            })
11030                            .unwrap_or_default(),
11031                        cx,
11032                    )
11033                });
11034            }
11035        });
11036
11037        for (buffer_id, abs_path) in buffer_paths_registered {
11038            cx.emit(LspStoreEvent::LanguageServerUpdate {
11039                language_server_id: server_id,
11040                name: Some(adapter.name()),
11041                message: proto::update_language_server::Variant::RegisteredForBuffer(
11042                    proto::RegisteredForBuffer {
11043                        buffer_abs_path: abs_path.to_string_lossy().to_string(),
11044                        buffer_id: buffer_id.to_proto(),
11045                    },
11046                ),
11047            });
11048        }
11049
11050        cx.notify();
11051    }
11052
11053    pub fn language_servers_running_disk_based_diagnostics(
11054        &self,
11055    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11056        self.language_server_statuses
11057            .iter()
11058            .filter_map(|(id, status)| {
11059                if status.has_pending_diagnostic_updates {
11060                    Some(*id)
11061                } else {
11062                    None
11063                }
11064            })
11065    }
11066
11067    pub(crate) fn cancel_language_server_work_for_buffers(
11068        &mut self,
11069        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11070        cx: &mut Context<Self>,
11071    ) {
11072        if let Some((client, project_id)) = self.upstream_client() {
11073            let request = client.request(proto::CancelLanguageServerWork {
11074                project_id,
11075                work: Some(proto::cancel_language_server_work::Work::Buffers(
11076                    proto::cancel_language_server_work::Buffers {
11077                        buffer_ids: buffers
11078                            .into_iter()
11079                            .map(|b| b.read(cx).remote_id().to_proto())
11080                            .collect(),
11081                    },
11082                )),
11083            });
11084            cx.background_spawn(request).detach_and_log_err(cx);
11085        } else if let Some(local) = self.as_local() {
11086            let servers = buffers
11087                .into_iter()
11088                .flat_map(|buffer| {
11089                    buffer.update(cx, |buffer, cx| {
11090                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11091                    })
11092                })
11093                .collect::<HashSet<_>>();
11094            for server_id in servers {
11095                self.cancel_language_server_work(server_id, None, cx);
11096            }
11097        }
11098    }
11099
11100    pub(crate) fn cancel_language_server_work(
11101        &mut self,
11102        server_id: LanguageServerId,
11103        token_to_cancel: Option<String>,
11104        cx: &mut Context<Self>,
11105    ) {
11106        if let Some(local) = self.as_local() {
11107            let status = self.language_server_statuses.get(&server_id);
11108            let server = local.language_servers.get(&server_id);
11109            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11110            {
11111                for (token, progress) in &status.pending_work {
11112                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11113                        && token != token_to_cancel
11114                    {
11115                        continue;
11116                    }
11117                    if progress.is_cancellable {
11118                        server
11119                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11120                                &WorkDoneProgressCancelParams {
11121                                    token: lsp::NumberOrString::String(token.clone()),
11122                                },
11123                            )
11124                            .ok();
11125                    }
11126                }
11127            }
11128        } else if let Some((client, project_id)) = self.upstream_client() {
11129            let request = client.request(proto::CancelLanguageServerWork {
11130                project_id,
11131                work: Some(
11132                    proto::cancel_language_server_work::Work::LanguageServerWork(
11133                        proto::cancel_language_server_work::LanguageServerWork {
11134                            language_server_id: server_id.to_proto(),
11135                            token: token_to_cancel,
11136                        },
11137                    ),
11138                ),
11139            });
11140            cx.background_spawn(request).detach_and_log_err(cx);
11141        }
11142    }
11143
11144    fn register_supplementary_language_server(
11145        &mut self,
11146        id: LanguageServerId,
11147        name: LanguageServerName,
11148        server: Arc<LanguageServer>,
11149        cx: &mut Context<Self>,
11150    ) {
11151        if let Some(local) = self.as_local_mut() {
11152            local
11153                .supplementary_language_servers
11154                .insert(id, (name.clone(), server));
11155            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11156        }
11157    }
11158
11159    fn unregister_supplementary_language_server(
11160        &mut self,
11161        id: LanguageServerId,
11162        cx: &mut Context<Self>,
11163    ) {
11164        if let Some(local) = self.as_local_mut() {
11165            local.supplementary_language_servers.remove(&id);
11166            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11167        }
11168    }
11169
11170    pub(crate) fn supplementary_language_servers(
11171        &self,
11172    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11173        self.as_local().into_iter().flat_map(|local| {
11174            local
11175                .supplementary_language_servers
11176                .iter()
11177                .map(|(id, (name, _))| (*id, name.clone()))
11178        })
11179    }
11180
11181    pub fn language_server_adapter_for_id(
11182        &self,
11183        id: LanguageServerId,
11184    ) -> Option<Arc<CachedLspAdapter>> {
11185        self.as_local()
11186            .and_then(|local| local.language_servers.get(&id))
11187            .and_then(|language_server_state| match language_server_state {
11188                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11189                _ => None,
11190            })
11191    }
11192
11193    pub(super) fn update_local_worktree_language_servers(
11194        &mut self,
11195        worktree_handle: &Entity<Worktree>,
11196        changes: &[(Arc<Path>, ProjectEntryId, PathChange)],
11197        cx: &mut Context<Self>,
11198    ) {
11199        if changes.is_empty() {
11200            return;
11201        }
11202
11203        let Some(local) = self.as_local() else { return };
11204
11205        local.prettier_store.update(cx, |prettier_store, cx| {
11206            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11207        });
11208
11209        let worktree_id = worktree_handle.read(cx).id();
11210        let mut language_server_ids = local
11211            .language_server_ids
11212            .iter()
11213            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11214            .collect::<Vec<_>>();
11215        language_server_ids.sort();
11216        language_server_ids.dedup();
11217
11218        let abs_path = worktree_handle.read(cx).abs_path();
11219        for server_id in &language_server_ids {
11220            if let Some(LanguageServerState::Running { server, .. }) =
11221                local.language_servers.get(server_id)
11222                && let Some(watched_paths) = local
11223                    .language_server_watched_paths
11224                    .get(server_id)
11225                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11226            {
11227                let params = lsp::DidChangeWatchedFilesParams {
11228                    changes: changes
11229                        .iter()
11230                        .filter_map(|(path, _, change)| {
11231                            if !watched_paths.is_match(path) {
11232                                return None;
11233                            }
11234                            let typ = match change {
11235                                PathChange::Loaded => return None,
11236                                PathChange::Added => lsp::FileChangeType::CREATED,
11237                                PathChange::Removed => lsp::FileChangeType::DELETED,
11238                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11239                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11240                            };
11241                            Some(lsp::FileEvent {
11242                                uri: lsp::Url::from_file_path(abs_path.join(path)).unwrap(),
11243                                typ,
11244                            })
11245                        })
11246                        .collect(),
11247                };
11248                if !params.changes.is_empty() {
11249                    server
11250                        .notify::<lsp::notification::DidChangeWatchedFiles>(&params)
11251                        .ok();
11252                }
11253            }
11254        }
11255        for (path, _, _) in changes {
11256            if let Some(file_name) = path.file_name().and_then(|file_name| file_name.to_str())
11257                && local.watched_manifest_filenames.contains(file_name)
11258            {
11259                self.request_workspace_config_refresh();
11260                break;
11261            }
11262        }
11263    }
11264
11265    pub fn wait_for_remote_buffer(
11266        &mut self,
11267        id: BufferId,
11268        cx: &mut Context<Self>,
11269    ) -> Task<Result<Entity<Buffer>>> {
11270        self.buffer_store.update(cx, |buffer_store, cx| {
11271            buffer_store.wait_for_remote_buffer(id, cx)
11272        })
11273    }
11274
11275    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11276        proto::Symbol {
11277            language_server_name: symbol.language_server_name.0.to_string(),
11278            source_worktree_id: symbol.source_worktree_id.to_proto(),
11279            language_server_id: symbol.source_language_server_id.to_proto(),
11280            worktree_id: symbol.path.worktree_id.to_proto(),
11281            path: symbol.path.path.as_ref().to_proto(),
11282            name: symbol.name.clone(),
11283            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11284            start: Some(proto::PointUtf16 {
11285                row: symbol.range.start.0.row,
11286                column: symbol.range.start.0.column,
11287            }),
11288            end: Some(proto::PointUtf16 {
11289                row: symbol.range.end.0.row,
11290                column: symbol.range.end.0.column,
11291            }),
11292            signature: symbol.signature.to_vec(),
11293        }
11294    }
11295
11296    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11297        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11298        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11299        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11300        let path = ProjectPath {
11301            worktree_id,
11302            path: Arc::<Path>::from_proto(serialized_symbol.path),
11303        };
11304
11305        let start = serialized_symbol.start.context("invalid start")?;
11306        let end = serialized_symbol.end.context("invalid end")?;
11307        Ok(CoreSymbol {
11308            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11309            source_worktree_id,
11310            source_language_server_id: LanguageServerId::from_proto(
11311                serialized_symbol.language_server_id,
11312            ),
11313            path,
11314            name: serialized_symbol.name,
11315            range: Unclipped(PointUtf16::new(start.row, start.column))
11316                ..Unclipped(PointUtf16::new(end.row, end.column)),
11317            kind,
11318            signature: serialized_symbol
11319                .signature
11320                .try_into()
11321                .map_err(|_| anyhow!("invalid signature"))?,
11322        })
11323    }
11324
11325    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11326        let mut serialized_completion = proto::Completion {
11327            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11328            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11329            new_text: completion.new_text.clone(),
11330            ..proto::Completion::default()
11331        };
11332        match &completion.source {
11333            CompletionSource::Lsp {
11334                insert_range,
11335                server_id,
11336                lsp_completion,
11337                lsp_defaults,
11338                resolved,
11339            } => {
11340                let (old_insert_start, old_insert_end) = insert_range
11341                    .as_ref()
11342                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11343                    .unzip();
11344
11345                serialized_completion.old_insert_start = old_insert_start;
11346                serialized_completion.old_insert_end = old_insert_end;
11347                serialized_completion.source = proto::completion::Source::Lsp as i32;
11348                serialized_completion.server_id = server_id.0 as u64;
11349                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11350                serialized_completion.lsp_defaults = lsp_defaults
11351                    .as_deref()
11352                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11353                serialized_completion.resolved = *resolved;
11354            }
11355            CompletionSource::BufferWord {
11356                word_range,
11357                resolved,
11358            } => {
11359                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11360                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11361                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11362                serialized_completion.resolved = *resolved;
11363            }
11364            CompletionSource::Custom => {
11365                serialized_completion.source = proto::completion::Source::Custom as i32;
11366                serialized_completion.resolved = true;
11367            }
11368            CompletionSource::Dap { sort_text } => {
11369                serialized_completion.source = proto::completion::Source::Dap as i32;
11370                serialized_completion.sort_text = Some(sort_text.clone());
11371            }
11372        }
11373
11374        serialized_completion
11375    }
11376
11377    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11378        let old_replace_start = completion
11379            .old_replace_start
11380            .and_then(deserialize_anchor)
11381            .context("invalid old start")?;
11382        let old_replace_end = completion
11383            .old_replace_end
11384            .and_then(deserialize_anchor)
11385            .context("invalid old end")?;
11386        let insert_range = {
11387            match completion.old_insert_start.zip(completion.old_insert_end) {
11388                Some((start, end)) => {
11389                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11390                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11391                    Some(start..end)
11392                }
11393                None => None,
11394            }
11395        };
11396        Ok(CoreCompletion {
11397            replace_range: old_replace_start..old_replace_end,
11398            new_text: completion.new_text,
11399            source: match proto::completion::Source::from_i32(completion.source) {
11400                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11401                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11402                    insert_range,
11403                    server_id: LanguageServerId::from_proto(completion.server_id),
11404                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11405                    lsp_defaults: completion
11406                        .lsp_defaults
11407                        .as_deref()
11408                        .map(serde_json::from_slice)
11409                        .transpose()?,
11410                    resolved: completion.resolved,
11411                },
11412                Some(proto::completion::Source::BufferWord) => {
11413                    let word_range = completion
11414                        .buffer_word_start
11415                        .and_then(deserialize_anchor)
11416                        .context("invalid buffer word start")?
11417                        ..completion
11418                            .buffer_word_end
11419                            .and_then(deserialize_anchor)
11420                            .context("invalid buffer word end")?;
11421                    CompletionSource::BufferWord {
11422                        word_range,
11423                        resolved: completion.resolved,
11424                    }
11425                }
11426                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11427                    sort_text: completion
11428                        .sort_text
11429                        .context("expected sort text to exist")?,
11430                },
11431                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11432            },
11433        })
11434    }
11435
11436    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11437        let (kind, lsp_action) = match &action.lsp_action {
11438            LspAction::Action(code_action) => (
11439                proto::code_action::Kind::Action as i32,
11440                serde_json::to_vec(code_action).unwrap(),
11441            ),
11442            LspAction::Command(command) => (
11443                proto::code_action::Kind::Command as i32,
11444                serde_json::to_vec(command).unwrap(),
11445            ),
11446            LspAction::CodeLens(code_lens) => (
11447                proto::code_action::Kind::CodeLens as i32,
11448                serde_json::to_vec(code_lens).unwrap(),
11449            ),
11450        };
11451
11452        proto::CodeAction {
11453            server_id: action.server_id.0 as u64,
11454            start: Some(serialize_anchor(&action.range.start)),
11455            end: Some(serialize_anchor(&action.range.end)),
11456            lsp_action,
11457            kind,
11458            resolved: action.resolved,
11459        }
11460    }
11461
11462    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11463        let start = action
11464            .start
11465            .and_then(deserialize_anchor)
11466            .context("invalid start")?;
11467        let end = action
11468            .end
11469            .and_then(deserialize_anchor)
11470            .context("invalid end")?;
11471        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11472            Some(proto::code_action::Kind::Action) => {
11473                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11474            }
11475            Some(proto::code_action::Kind::Command) => {
11476                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11477            }
11478            Some(proto::code_action::Kind::CodeLens) => {
11479                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11480            }
11481            None => anyhow::bail!("Unknown action kind {}", action.kind),
11482        };
11483        Ok(CodeAction {
11484            server_id: LanguageServerId(action.server_id as usize),
11485            range: start..end,
11486            resolved: action.resolved,
11487            lsp_action,
11488        })
11489    }
11490
11491    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11492        match &formatting_result {
11493            Ok(_) => self.last_formatting_failure = None,
11494            Err(error) => {
11495                let error_string = format!("{error:#}");
11496                log::error!("Formatting failed: {error_string}");
11497                self.last_formatting_failure
11498                    .replace(error_string.lines().join(" "));
11499            }
11500        }
11501    }
11502
11503    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11504        self.lsp_server_capabilities.remove(&for_server);
11505        for buffer_colors in self.lsp_document_colors.values_mut() {
11506            buffer_colors.colors.remove(&for_server);
11507            buffer_colors.cache_version += 1;
11508        }
11509        for buffer_lens in self.lsp_code_lens.values_mut() {
11510            buffer_lens.lens.remove(&for_server);
11511        }
11512        if let Some(local) = self.as_local_mut() {
11513            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11514            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11515                buffer_servers.remove(&for_server);
11516            }
11517        }
11518    }
11519
11520    pub fn result_id(
11521        &self,
11522        server_id: LanguageServerId,
11523        buffer_id: BufferId,
11524        cx: &App,
11525    ) -> Option<String> {
11526        let abs_path = self
11527            .buffer_store
11528            .read(cx)
11529            .get(buffer_id)
11530            .and_then(|b| File::from_dyn(b.read(cx).file()))
11531            .map(|f| f.abs_path(cx))?;
11532        self.as_local()?
11533            .buffer_pull_diagnostics_result_ids
11534            .get(&server_id)?
11535            .get(&abs_path)?
11536            .clone()
11537    }
11538
11539    pub fn all_result_ids(&self, server_id: LanguageServerId) -> HashMap<PathBuf, String> {
11540        let Some(local) = self.as_local() else {
11541            return HashMap::default();
11542        };
11543        local
11544            .buffer_pull_diagnostics_result_ids
11545            .get(&server_id)
11546            .into_iter()
11547            .flatten()
11548            .filter_map(|(abs_path, result_id)| Some((abs_path.clone(), result_id.clone()?)))
11549            .collect()
11550    }
11551
11552    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
11553        if let Some(LanguageServerState::Running {
11554            workspace_refresh_task: Some(workspace_refresh_task),
11555            ..
11556        }) = self
11557            .as_local_mut()
11558            .and_then(|local| local.language_servers.get_mut(&server_id))
11559        {
11560            workspace_refresh_task.refresh_tx.try_send(()).ok();
11561        }
11562    }
11563
11564    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
11565        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
11566            return;
11567        };
11568        let Some(local) = self.as_local_mut() else {
11569            return;
11570        };
11571
11572        for server_id in buffer.update(cx, |buffer, cx| {
11573            local.language_server_ids_for_buffer(buffer, cx)
11574        }) {
11575            if let Some(LanguageServerState::Running {
11576                workspace_refresh_task: Some(workspace_refresh_task),
11577                ..
11578            }) = local.language_servers.get_mut(&server_id)
11579            {
11580                workspace_refresh_task.refresh_tx.try_send(()).ok();
11581            }
11582        }
11583    }
11584
11585    fn apply_workspace_diagnostic_report(
11586        &mut self,
11587        server_id: LanguageServerId,
11588        report: lsp::WorkspaceDiagnosticReportResult,
11589        cx: &mut Context<Self>,
11590    ) {
11591        let workspace_diagnostics =
11592            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(report, server_id);
11593        let mut unchanged_buffers = HashSet::default();
11594        let mut changed_buffers = HashSet::default();
11595        let workspace_diagnostics_updates = workspace_diagnostics
11596            .into_iter()
11597            .filter_map(
11598                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
11599                    LspPullDiagnostics::Response {
11600                        server_id,
11601                        uri,
11602                        diagnostics,
11603                    } => Some((server_id, uri, diagnostics, workspace_diagnostics.version)),
11604                    LspPullDiagnostics::Default => None,
11605                },
11606            )
11607            .fold(
11608                HashMap::default(),
11609                |mut acc, (server_id, uri, diagnostics, version)| {
11610                    let (result_id, diagnostics) = match diagnostics {
11611                        PulledDiagnostics::Unchanged { result_id } => {
11612                            unchanged_buffers.insert(uri.clone());
11613                            (Some(result_id), Vec::new())
11614                        }
11615                        PulledDiagnostics::Changed {
11616                            result_id,
11617                            diagnostics,
11618                        } => {
11619                            changed_buffers.insert(uri.clone());
11620                            (result_id, diagnostics)
11621                        }
11622                    };
11623                    let disk_based_sources = Cow::Owned(
11624                        self.language_server_adapter_for_id(server_id)
11625                            .as_ref()
11626                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
11627                            .unwrap_or(&[])
11628                            .to_vec(),
11629                    );
11630                    acc.entry(server_id)
11631                        .or_insert_with(Vec::new)
11632                        .push(DocumentDiagnosticsUpdate {
11633                            server_id,
11634                            diagnostics: lsp::PublishDiagnosticsParams {
11635                                uri,
11636                                diagnostics,
11637                                version,
11638                            },
11639                            result_id,
11640                            disk_based_sources,
11641                        });
11642                    acc
11643                },
11644            );
11645
11646        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
11647            self.merge_lsp_diagnostics(
11648                DiagnosticSourceKind::Pulled,
11649                diagnostic_updates,
11650                |buffer, old_diagnostic, cx| {
11651                    File::from_dyn(buffer.file())
11652                        .and_then(|file| {
11653                            let abs_path = file.as_local()?.abs_path(cx);
11654                            lsp::Url::from_file_path(abs_path).ok()
11655                        })
11656                        .is_none_or(|buffer_uri| {
11657                            unchanged_buffers.contains(&buffer_uri)
11658                                || match old_diagnostic.source_kind {
11659                                    DiagnosticSourceKind::Pulled => {
11660                                        !changed_buffers.contains(&buffer_uri)
11661                                    }
11662                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
11663                                        true
11664                                    }
11665                                }
11666                        })
11667                },
11668                cx,
11669            )
11670            .log_err();
11671        }
11672    }
11673
11674    fn register_server_capabilities(
11675        &mut self,
11676        server_id: LanguageServerId,
11677        params: lsp::RegistrationParams,
11678        cx: &mut Context<Self>,
11679    ) -> anyhow::Result<()> {
11680        let server = self
11681            .language_server_for_id(server_id)
11682            .with_context(|| format!("no server {server_id} found"))?;
11683        for reg in params.registrations {
11684            match reg.method.as_str() {
11685                "workspace/didChangeWatchedFiles" => {
11686                    if let Some(options) = reg.register_options {
11687                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11688                            let caps = serde_json::from_value(options)?;
11689                            local_lsp_store
11690                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
11691                            true
11692                        } else {
11693                            false
11694                        };
11695                        if notify {
11696                            notify_server_capabilities_updated(&server, cx);
11697                        }
11698                    }
11699                }
11700                "workspace/didChangeConfiguration" => {
11701                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11702                }
11703                "workspace/symbol" => {
11704                    let options = parse_register_capabilities(reg)?;
11705                    server.update_capabilities(|capabilities| {
11706                        capabilities.workspace_symbol_provider = Some(options);
11707                    });
11708                    notify_server_capabilities_updated(&server, cx);
11709                }
11710                "workspace/fileOperations" => {
11711                    if let Some(options) = reg.register_options {
11712                        let caps = serde_json::from_value(options)?;
11713                        server.update_capabilities(|capabilities| {
11714                            capabilities
11715                                .workspace
11716                                .get_or_insert_default()
11717                                .file_operations = Some(caps);
11718                        });
11719                        notify_server_capabilities_updated(&server, cx);
11720                    }
11721                }
11722                "workspace/executeCommand" => {
11723                    if let Some(options) = reg.register_options {
11724                        let options = serde_json::from_value(options)?;
11725                        server.update_capabilities(|capabilities| {
11726                            capabilities.execute_command_provider = Some(options);
11727                        });
11728                        notify_server_capabilities_updated(&server, cx);
11729                    }
11730                }
11731                "textDocument/rangeFormatting" => {
11732                    let options = parse_register_capabilities(reg)?;
11733                    server.update_capabilities(|capabilities| {
11734                        capabilities.document_range_formatting_provider = Some(options);
11735                    });
11736                    notify_server_capabilities_updated(&server, cx);
11737                }
11738                "textDocument/onTypeFormatting" => {
11739                    if let Some(options) = reg
11740                        .register_options
11741                        .map(serde_json::from_value)
11742                        .transpose()?
11743                    {
11744                        server.update_capabilities(|capabilities| {
11745                            capabilities.document_on_type_formatting_provider = Some(options);
11746                        });
11747                        notify_server_capabilities_updated(&server, cx);
11748                    }
11749                }
11750                "textDocument/formatting" => {
11751                    let options = parse_register_capabilities(reg)?;
11752                    server.update_capabilities(|capabilities| {
11753                        capabilities.document_formatting_provider = Some(options);
11754                    });
11755                    notify_server_capabilities_updated(&server, cx);
11756                }
11757                "textDocument/rename" => {
11758                    let options = parse_register_capabilities(reg)?;
11759                    server.update_capabilities(|capabilities| {
11760                        capabilities.rename_provider = Some(options);
11761                    });
11762                    notify_server_capabilities_updated(&server, cx);
11763                }
11764                "textDocument/inlayHint" => {
11765                    let options = parse_register_capabilities(reg)?;
11766                    server.update_capabilities(|capabilities| {
11767                        capabilities.inlay_hint_provider = Some(options);
11768                    });
11769                    notify_server_capabilities_updated(&server, cx);
11770                }
11771                "textDocument/documentSymbol" => {
11772                    let options = parse_register_capabilities(reg)?;
11773                    server.update_capabilities(|capabilities| {
11774                        capabilities.document_symbol_provider = Some(options);
11775                    });
11776                    notify_server_capabilities_updated(&server, cx);
11777                }
11778                "textDocument/codeAction" => {
11779                    if let Some(options) = reg
11780                        .register_options
11781                        .map(serde_json::from_value)
11782                        .transpose()?
11783                    {
11784                        server.update_capabilities(|capabilities| {
11785                            capabilities.code_action_provider =
11786                                Some(lsp::CodeActionProviderCapability::Options(options));
11787                        });
11788                        notify_server_capabilities_updated(&server, cx);
11789                    }
11790                }
11791                "textDocument/definition" => {
11792                    let options = parse_register_capabilities(reg)?;
11793                    server.update_capabilities(|capabilities| {
11794                        capabilities.definition_provider = Some(options);
11795                    });
11796                    notify_server_capabilities_updated(&server, cx);
11797                }
11798                "textDocument/completion" => {
11799                    if let Some(caps) = reg
11800                        .register_options
11801                        .map(serde_json::from_value)
11802                        .transpose()?
11803                    {
11804                        server.update_capabilities(|capabilities| {
11805                            capabilities.completion_provider = Some(caps);
11806                        });
11807                        notify_server_capabilities_updated(&server, cx);
11808                    }
11809                }
11810                "textDocument/hover" => {
11811                    if let Some(caps) = reg
11812                        .register_options
11813                        .map(serde_json::from_value)
11814                        .transpose()?
11815                    {
11816                        server.update_capabilities(|capabilities| {
11817                            capabilities.hover_provider = Some(caps);
11818                        });
11819                        notify_server_capabilities_updated(&server, cx);
11820                    }
11821                }
11822                "textDocument/signatureHelp" => {
11823                    if let Some(caps) = reg
11824                        .register_options
11825                        .map(serde_json::from_value)
11826                        .transpose()?
11827                    {
11828                        server.update_capabilities(|capabilities| {
11829                            capabilities.signature_help_provider = Some(caps);
11830                        });
11831                        notify_server_capabilities_updated(&server, cx);
11832                    }
11833                }
11834                "textDocument/didChange" => {
11835                    if let Some(options) = reg.register_options {
11836                        let options: lsp::TextDocumentChangeRegistrationOptions =
11837                            serde_json::from_value(options)?;
11838                        server.update_dynamic_capabilities(|dyn_caps| {
11839                            let map = dyn_caps
11840                                .text_document_sync_did_change
11841                                .get_or_insert_with(HashMap::default);
11842                            map.insert(reg.id, options);
11843                        });
11844                        notify_server_capabilities_updated(&server, cx);
11845                    }
11846                }
11847                "textDocument/didSave" => {
11848                    if let Some(options) = reg.register_options {
11849                        let options: lsp::TextDocumentSaveRegistrationOptions =
11850                            serde_json::from_value(options)?;
11851                        server.update_dynamic_capabilities(|dyn_caps| {
11852                            let map = dyn_caps
11853                                .text_document_sync_did_save
11854                                .get_or_insert_with(HashMap::default);
11855                            map.insert(reg.id, options);
11856                        });
11857                        notify_server_capabilities_updated(&server, cx);
11858                    }
11859                }
11860                "textDocument/codeLens" => {
11861                    if let Some(caps) = reg
11862                        .register_options
11863                        .map(serde_json::from_value)
11864                        .transpose()?
11865                    {
11866                        server.update_capabilities(|capabilities| {
11867                            capabilities.code_lens_provider = Some(caps);
11868                        });
11869                        notify_server_capabilities_updated(&server, cx);
11870                    }
11871                }
11872                "textDocument/diagnostic" => {
11873                    if let Some(caps) = reg
11874                        .register_options
11875                        .map(serde_json::from_value)
11876                        .transpose()?
11877                    {
11878                        server.update_capabilities(|capabilities| {
11879                            capabilities.diagnostic_provider = Some(caps);
11880                        });
11881                        notify_server_capabilities_updated(&server, cx);
11882                    }
11883                }
11884                "textDocument/documentColor" => {
11885                    if let Some(caps) = reg
11886                        .register_options
11887                        .map(serde_json::from_value)
11888                        .transpose()?
11889                    {
11890                        server.update_capabilities(|capabilities| {
11891                            capabilities.color_provider = Some(caps);
11892                        });
11893                        notify_server_capabilities_updated(&server, cx);
11894                    }
11895                }
11896                _ => log::warn!("unhandled capability registration: {reg:?}"),
11897            }
11898        }
11899
11900        Ok(())
11901    }
11902
11903    fn unregister_server_capabilities(
11904        &mut self,
11905        server_id: LanguageServerId,
11906        params: lsp::UnregistrationParams,
11907        cx: &mut Context<Self>,
11908    ) -> anyhow::Result<()> {
11909        let server = self
11910            .language_server_for_id(server_id)
11911            .with_context(|| format!("no server {server_id} found"))?;
11912        for unreg in params.unregisterations.iter() {
11913            match unreg.method.as_str() {
11914                "workspace/didChangeWatchedFiles" => {
11915                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11916                        local_lsp_store
11917                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
11918                        true
11919                    } else {
11920                        false
11921                    };
11922                    if notify {
11923                        notify_server_capabilities_updated(&server, cx);
11924                    }
11925                }
11926                "workspace/didChangeConfiguration" => {
11927                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11928                }
11929                "workspace/symbol" => {
11930                    server.update_capabilities(|capabilities| {
11931                        capabilities.workspace_symbol_provider = None
11932                    });
11933                    notify_server_capabilities_updated(&server, cx);
11934                }
11935                "workspace/fileOperations" => {
11936                    server.update_capabilities(|capabilities| {
11937                        capabilities
11938                            .workspace
11939                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
11940                                workspace_folders: None,
11941                                file_operations: None,
11942                            })
11943                            .file_operations = None;
11944                    });
11945                    notify_server_capabilities_updated(&server, cx);
11946                }
11947                "workspace/executeCommand" => {
11948                    server.update_capabilities(|capabilities| {
11949                        capabilities.execute_command_provider = None;
11950                    });
11951                    notify_server_capabilities_updated(&server, cx);
11952                }
11953                "textDocument/rangeFormatting" => {
11954                    server.update_capabilities(|capabilities| {
11955                        capabilities.document_range_formatting_provider = None
11956                    });
11957                    notify_server_capabilities_updated(&server, cx);
11958                }
11959                "textDocument/onTypeFormatting" => {
11960                    server.update_capabilities(|capabilities| {
11961                        capabilities.document_on_type_formatting_provider = None;
11962                    });
11963                    notify_server_capabilities_updated(&server, cx);
11964                }
11965                "textDocument/formatting" => {
11966                    server.update_capabilities(|capabilities| {
11967                        capabilities.document_formatting_provider = None;
11968                    });
11969                    notify_server_capabilities_updated(&server, cx);
11970                }
11971                "textDocument/rename" => {
11972                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
11973                    notify_server_capabilities_updated(&server, cx);
11974                }
11975                "textDocument/codeAction" => {
11976                    server.update_capabilities(|capabilities| {
11977                        capabilities.code_action_provider = None;
11978                    });
11979                    notify_server_capabilities_updated(&server, cx);
11980                }
11981                "textDocument/definition" => {
11982                    server.update_capabilities(|capabilities| {
11983                        capabilities.definition_provider = None;
11984                    });
11985                    notify_server_capabilities_updated(&server, cx);
11986                }
11987                "textDocument/completion" => {
11988                    server.update_capabilities(|capabilities| {
11989                        capabilities.completion_provider = None;
11990                    });
11991                    notify_server_capabilities_updated(&server, cx);
11992                }
11993                "textDocument/hover" => {
11994                    server.update_capabilities(|capabilities| {
11995                        capabilities.hover_provider = None;
11996                    });
11997                    notify_server_capabilities_updated(&server, cx);
11998                }
11999                "textDocument/signatureHelp" => {
12000                    server.update_capabilities(|capabilities| {
12001                        capabilities.signature_help_provider = None;
12002                    });
12003                    notify_server_capabilities_updated(&server, cx);
12004                }
12005                "textDocument/didChange" => {
12006                    server.update_dynamic_capabilities(|dyn_caps| {
12007                        if let Some(map) = dyn_caps.text_document_sync_did_change.as_mut() {
12008                            map.remove(&unreg.id);
12009                        }
12010                    });
12011                    notify_server_capabilities_updated(&server, cx);
12012                }
12013                "textDocument/didSave" => {
12014                    server.update_dynamic_capabilities(|dyn_caps| {
12015                        if let Some(map) = dyn_caps.text_document_sync_did_save.as_mut() {
12016                            map.remove(&unreg.id);
12017                        }
12018                    });
12019                    notify_server_capabilities_updated(&server, cx);
12020                }
12021                "textDocument/codeLens" => {
12022                    server.update_capabilities(|capabilities| {
12023                        capabilities.code_lens_provider = None;
12024                    });
12025                    notify_server_capabilities_updated(&server, cx);
12026                }
12027                "textDocument/diagnostic" => {
12028                    server.update_capabilities(|capabilities| {
12029                        capabilities.diagnostic_provider = None;
12030                    });
12031                    notify_server_capabilities_updated(&server, cx);
12032                }
12033                "textDocument/documentColor" => {
12034                    server.update_capabilities(|capabilities| {
12035                        capabilities.color_provider = None;
12036                    });
12037                    notify_server_capabilities_updated(&server, cx);
12038                }
12039                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12040            }
12041        }
12042
12043        Ok(())
12044    }
12045
12046    async fn query_lsp_locally<T>(
12047        lsp_store: Entity<Self>,
12048        sender_id: proto::PeerId,
12049        lsp_request_id: LspRequestId,
12050        proto_request: T::ProtoRequest,
12051        position: Option<Anchor>,
12052        mut cx: AsyncApp,
12053    ) -> Result<()>
12054    where
12055        T: LspCommand + Clone,
12056        T::ProtoRequest: proto::LspRequestMessage,
12057        <T::ProtoRequest as proto::RequestMessage>::Response:
12058            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12059    {
12060        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12061        let version = deserialize_version(proto_request.buffer_version());
12062        let buffer = lsp_store.update(&mut cx, |this, cx| {
12063            this.buffer_store.read(cx).get_existing(buffer_id)
12064        })??;
12065        buffer
12066            .update(&mut cx, |buffer, _| {
12067                buffer.wait_for_version(version.clone())
12068            })?
12069            .await?;
12070        let buffer_version = buffer.read_with(&cx, |buffer, _| buffer.version())?;
12071        let request =
12072            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12073        lsp_store.update(&mut cx, |lsp_store, cx| {
12074            let request_task =
12075                lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx);
12076            let existing_queries = lsp_store
12077                .running_lsp_requests
12078                .entry(TypeId::of::<T>())
12079                .or_default();
12080            if T::ProtoRequest::stop_previous_requests()
12081                || buffer_version.changed_since(&existing_queries.0)
12082            {
12083                existing_queries.1.clear();
12084            }
12085            existing_queries.1.insert(
12086                lsp_request_id,
12087                cx.spawn(async move |lsp_store, cx| {
12088                    let response = request_task.await;
12089                    lsp_store
12090                        .update(cx, |lsp_store, cx| {
12091                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12092                            {
12093                                let response = response
12094                                    .into_iter()
12095                                    .map(|(server_id, response)| {
12096                                        (
12097                                            server_id.to_proto(),
12098                                            T::response_to_proto(
12099                                                response,
12100                                                lsp_store,
12101                                                sender_id,
12102                                                &buffer_version,
12103                                                cx,
12104                                            )
12105                                            .into(),
12106                                        )
12107                                    })
12108                                    .collect::<HashMap<_, _>>();
12109                                match client.send_lsp_response::<T::ProtoRequest>(
12110                                    project_id,
12111                                    lsp_request_id,
12112                                    response,
12113                                ) {
12114                                    Ok(()) => {}
12115                                    Err(e) => {
12116                                        log::error!("Failed to send LSP response: {e:#}",)
12117                                    }
12118                                }
12119                            }
12120                        })
12121                        .ok();
12122                }),
12123            );
12124        })?;
12125        Ok(())
12126    }
12127
12128    #[cfg(any(test, feature = "test-support"))]
12129    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
12130        let data = self.lsp_code_lens.get_mut(&buffer_id)?;
12131        Some(data.update.take()?.1)
12132    }
12133}
12134
12135// Registration with registerOptions as null, should fallback to true.
12136// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
12137fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
12138    reg: lsp::Registration,
12139) -> Result<OneOf<bool, T>> {
12140    Ok(match reg.register_options {
12141        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
12142        None => OneOf::Left(true),
12143    })
12144}
12145
12146fn subscribe_to_binary_statuses(
12147    languages: &Arc<LanguageRegistry>,
12148    cx: &mut Context<'_, LspStore>,
12149) -> Task<()> {
12150    let mut server_statuses = languages.language_server_binary_statuses();
12151    cx.spawn(async move |lsp_store, cx| {
12152        while let Some((server_name, binary_status)) = server_statuses.next().await {
12153            if lsp_store
12154                .update(cx, |_, cx| {
12155                    let mut message = None;
12156                    let binary_status = match binary_status {
12157                        BinaryStatus::None => proto::ServerBinaryStatus::None,
12158                        BinaryStatus::CheckingForUpdate => {
12159                            proto::ServerBinaryStatus::CheckingForUpdate
12160                        }
12161                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
12162                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
12163                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
12164                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
12165                        BinaryStatus::Failed { error } => {
12166                            message = Some(error);
12167                            proto::ServerBinaryStatus::Failed
12168                        }
12169                    };
12170                    cx.emit(LspStoreEvent::LanguageServerUpdate {
12171                        // Binary updates are about the binary that might not have any language server id at that point.
12172                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
12173                        language_server_id: LanguageServerId(0),
12174                        name: Some(server_name),
12175                        message: proto::update_language_server::Variant::StatusUpdate(
12176                            proto::StatusUpdate {
12177                                message,
12178                                status: Some(proto::status_update::Status::Binary(
12179                                    binary_status as i32,
12180                                )),
12181                            },
12182                        ),
12183                    });
12184                })
12185                .is_err()
12186            {
12187                break;
12188            }
12189        }
12190    })
12191}
12192
12193fn lsp_workspace_diagnostics_refresh(
12194    server: Arc<LanguageServer>,
12195    cx: &mut Context<'_, LspStore>,
12196) -> Option<WorkspaceRefreshTask> {
12197    let identifier = match server.capabilities().diagnostic_provider? {
12198        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
12199            if !diagnostic_options.workspace_diagnostics {
12200                return None;
12201            }
12202            diagnostic_options.identifier
12203        }
12204        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
12205            let diagnostic_options = registration_options.diagnostic_options;
12206            if !diagnostic_options.workspace_diagnostics {
12207                return None;
12208            }
12209            diagnostic_options.identifier
12210        }
12211    };
12212
12213    let (progress_tx, mut progress_rx) = mpsc::channel(1);
12214    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
12215    refresh_tx.try_send(()).ok();
12216
12217    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
12218        let mut attempts = 0;
12219        let max_attempts = 50;
12220        let mut requests = 0;
12221
12222        loop {
12223            let Some(()) = refresh_rx.recv().await else {
12224                return;
12225            };
12226
12227            'request: loop {
12228                requests += 1;
12229                if attempts > max_attempts {
12230                    log::error!(
12231                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
12232                    );
12233                    return;
12234                }
12235                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
12236                cx.background_executor()
12237                    .timer(Duration::from_millis(backoff_millis))
12238                    .await;
12239                attempts += 1;
12240
12241                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
12242                    lsp_store
12243                        .all_result_ids(server.server_id())
12244                        .into_iter()
12245                        .filter_map(|(abs_path, result_id)| {
12246                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
12247                            Some(lsp::PreviousResultId {
12248                                uri,
12249                                value: result_id,
12250                            })
12251                        })
12252                        .collect()
12253                }) else {
12254                    return;
12255                };
12256
12257                let token = format!("workspace/diagnostic-{}-{}", server.server_id(), requests);
12258
12259                progress_rx.try_recv().ok();
12260                let timer =
12261                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
12262                let progress = pin!(progress_rx.recv().fuse());
12263                let response_result = server
12264                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
12265                        lsp::WorkspaceDiagnosticParams {
12266                            previous_result_ids,
12267                            identifier: identifier.clone(),
12268                            work_done_progress_params: Default::default(),
12269                            partial_result_params: lsp::PartialResultParams {
12270                                partial_result_token: Some(lsp::ProgressToken::String(token)),
12271                            },
12272                        },
12273                        select(timer, progress).then(|either| match either {
12274                            Either::Left((message, ..)) => ready(message).left_future(),
12275                            Either::Right(..) => pending::<String>().right_future(),
12276                        }),
12277                    )
12278                    .await;
12279
12280                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
12281                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
12282                match response_result {
12283                    ConnectionResult::Timeout => {
12284                        log::error!("Timeout during workspace diagnostics pull");
12285                        continue 'request;
12286                    }
12287                    ConnectionResult::ConnectionReset => {
12288                        log::error!("Server closed a workspace diagnostics pull request");
12289                        continue 'request;
12290                    }
12291                    ConnectionResult::Result(Err(e)) => {
12292                        log::error!("Error during workspace diagnostics pull: {e:#}");
12293                        break 'request;
12294                    }
12295                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
12296                        attempts = 0;
12297                        if lsp_store
12298                            .update(cx, |lsp_store, cx| {
12299                                lsp_store.apply_workspace_diagnostic_report(
12300                                    server.server_id(),
12301                                    pulled_diagnostics,
12302                                    cx,
12303                                )
12304                            })
12305                            .is_err()
12306                        {
12307                            return;
12308                        }
12309                        break 'request;
12310                    }
12311                }
12312            }
12313        }
12314    });
12315
12316    Some(WorkspaceRefreshTask {
12317        refresh_tx,
12318        progress_tx,
12319        task: workspace_query_language_server,
12320    })
12321}
12322
12323fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
12324    let CompletionSource::BufferWord {
12325        word_range,
12326        resolved,
12327    } = &mut completion.source
12328    else {
12329        return;
12330    };
12331    if *resolved {
12332        return;
12333    }
12334
12335    if completion.new_text
12336        != snapshot
12337            .text_for_range(word_range.clone())
12338            .collect::<String>()
12339    {
12340        return;
12341    }
12342
12343    let mut offset = 0;
12344    for chunk in snapshot.chunks(word_range.clone(), true) {
12345        let end_offset = offset + chunk.text.len();
12346        if let Some(highlight_id) = chunk.syntax_highlight_id {
12347            completion
12348                .label
12349                .runs
12350                .push((offset..end_offset, highlight_id));
12351        }
12352        offset = end_offset;
12353    }
12354    *resolved = true;
12355}
12356
12357impl EventEmitter<LspStoreEvent> for LspStore {}
12358
12359fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
12360    hover
12361        .contents
12362        .retain(|hover_block| !hover_block.text.trim().is_empty());
12363    if hover.contents.is_empty() {
12364        None
12365    } else {
12366        Some(hover)
12367    }
12368}
12369
12370async fn populate_labels_for_completions(
12371    new_completions: Vec<CoreCompletion>,
12372    language: Option<Arc<Language>>,
12373    lsp_adapter: Option<Arc<CachedLspAdapter>>,
12374) -> Vec<Completion> {
12375    let lsp_completions = new_completions
12376        .iter()
12377        .filter_map(|new_completion| {
12378            new_completion
12379                .source
12380                .lsp_completion(true)
12381                .map(|lsp_completion| lsp_completion.into_owned())
12382        })
12383        .collect::<Vec<_>>();
12384
12385    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
12386        lsp_adapter
12387            .labels_for_completions(&lsp_completions, language)
12388            .await
12389            .log_err()
12390            .unwrap_or_default()
12391    } else {
12392        Vec::new()
12393    }
12394    .into_iter()
12395    .fuse();
12396
12397    let mut completions = Vec::new();
12398    for completion in new_completions {
12399        match completion.source.lsp_completion(true) {
12400            Some(lsp_completion) => {
12401                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
12402
12403                let mut label = labels.next().flatten().unwrap_or_else(|| {
12404                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
12405                });
12406                ensure_uniform_list_compatible_label(&mut label);
12407                completions.push(Completion {
12408                    label,
12409                    documentation,
12410                    replace_range: completion.replace_range,
12411                    new_text: completion.new_text,
12412                    insert_text_mode: lsp_completion.insert_text_mode,
12413                    source: completion.source,
12414                    icon_path: None,
12415                    confirm: None,
12416                });
12417            }
12418            None => {
12419                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
12420                ensure_uniform_list_compatible_label(&mut label);
12421                completions.push(Completion {
12422                    label,
12423                    documentation: None,
12424                    replace_range: completion.replace_range,
12425                    new_text: completion.new_text,
12426                    source: completion.source,
12427                    insert_text_mode: None,
12428                    icon_path: None,
12429                    confirm: None,
12430                });
12431            }
12432        }
12433    }
12434    completions
12435}
12436
12437#[derive(Debug)]
12438pub enum LanguageServerToQuery {
12439    /// Query language servers in order of users preference, up until one capable of handling the request is found.
12440    FirstCapable,
12441    /// Query a specific language server.
12442    Other(LanguageServerId),
12443}
12444
12445#[derive(Default)]
12446struct RenamePathsWatchedForServer {
12447    did_rename: Vec<RenameActionPredicate>,
12448    will_rename: Vec<RenameActionPredicate>,
12449}
12450
12451impl RenamePathsWatchedForServer {
12452    fn with_did_rename_patterns(
12453        mut self,
12454        did_rename: Option<&FileOperationRegistrationOptions>,
12455    ) -> Self {
12456        if let Some(did_rename) = did_rename {
12457            self.did_rename = did_rename
12458                .filters
12459                .iter()
12460                .filter_map(|filter| filter.try_into().log_err())
12461                .collect();
12462        }
12463        self
12464    }
12465    fn with_will_rename_patterns(
12466        mut self,
12467        will_rename: Option<&FileOperationRegistrationOptions>,
12468    ) -> Self {
12469        if let Some(will_rename) = will_rename {
12470            self.will_rename = will_rename
12471                .filters
12472                .iter()
12473                .filter_map(|filter| filter.try_into().log_err())
12474                .collect();
12475        }
12476        self
12477    }
12478
12479    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
12480        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
12481    }
12482    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
12483        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
12484    }
12485}
12486
12487impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
12488    type Error = globset::Error;
12489    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
12490        Ok(Self {
12491            kind: ops.pattern.matches.clone(),
12492            glob: GlobBuilder::new(&ops.pattern.glob)
12493                .case_insensitive(
12494                    ops.pattern
12495                        .options
12496                        .as_ref()
12497                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
12498                )
12499                .build()?
12500                .compile_matcher(),
12501        })
12502    }
12503}
12504struct RenameActionPredicate {
12505    glob: GlobMatcher,
12506    kind: Option<FileOperationPatternKind>,
12507}
12508
12509impl RenameActionPredicate {
12510    // Returns true if language server should be notified
12511    fn eval(&self, path: &str, is_dir: bool) -> bool {
12512        self.kind.as_ref().is_none_or(|kind| {
12513            let expected_kind = if is_dir {
12514                FileOperationPatternKind::Folder
12515            } else {
12516                FileOperationPatternKind::File
12517            };
12518            kind == &expected_kind
12519        }) && self.glob.is_match(path)
12520    }
12521}
12522
12523#[derive(Default)]
12524struct LanguageServerWatchedPaths {
12525    worktree_paths: HashMap<WorktreeId, GlobSet>,
12526    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
12527}
12528
12529#[derive(Default)]
12530struct LanguageServerWatchedPathsBuilder {
12531    worktree_paths: HashMap<WorktreeId, GlobSet>,
12532    abs_paths: HashMap<Arc<Path>, GlobSet>,
12533}
12534
12535impl LanguageServerWatchedPathsBuilder {
12536    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
12537        self.worktree_paths.insert(worktree_id, glob_set);
12538    }
12539    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
12540        self.abs_paths.insert(path, glob_set);
12541    }
12542    fn build(
12543        self,
12544        fs: Arc<dyn Fs>,
12545        language_server_id: LanguageServerId,
12546        cx: &mut Context<LspStore>,
12547    ) -> LanguageServerWatchedPaths {
12548        let project = cx.weak_entity();
12549
12550        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
12551        let abs_paths = self
12552            .abs_paths
12553            .into_iter()
12554            .map(|(abs_path, globset)| {
12555                let task = cx.spawn({
12556                    let abs_path = abs_path.clone();
12557                    let fs = fs.clone();
12558
12559                    let lsp_store = project.clone();
12560                    async move |_, cx| {
12561                        maybe!(async move {
12562                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
12563                            while let Some(update) = push_updates.0.next().await {
12564                                let action = lsp_store
12565                                    .update(cx, |this, _| {
12566                                        let Some(local) = this.as_local() else {
12567                                            return ControlFlow::Break(());
12568                                        };
12569                                        let Some(watcher) = local
12570                                            .language_server_watched_paths
12571                                            .get(&language_server_id)
12572                                        else {
12573                                            return ControlFlow::Break(());
12574                                        };
12575                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
12576                                            "Watched abs path is not registered with a watcher",
12577                                        );
12578                                        let matching_entries = update
12579                                            .into_iter()
12580                                            .filter(|event| globs.is_match(&event.path))
12581                                            .collect::<Vec<_>>();
12582                                        this.lsp_notify_abs_paths_changed(
12583                                            language_server_id,
12584                                            matching_entries,
12585                                        );
12586                                        ControlFlow::Continue(())
12587                                    })
12588                                    .ok()?;
12589
12590                                if action.is_break() {
12591                                    break;
12592                                }
12593                            }
12594                            Some(())
12595                        })
12596                        .await;
12597                    }
12598                });
12599                (abs_path, (globset, task))
12600            })
12601            .collect();
12602        LanguageServerWatchedPaths {
12603            worktree_paths: self.worktree_paths,
12604            abs_paths,
12605        }
12606    }
12607}
12608
12609struct LspBufferSnapshot {
12610    version: i32,
12611    snapshot: TextBufferSnapshot,
12612}
12613
12614/// A prompt requested by LSP server.
12615#[derive(Clone, Debug)]
12616pub struct LanguageServerPromptRequest {
12617    pub level: PromptLevel,
12618    pub message: String,
12619    pub actions: Vec<MessageActionItem>,
12620    pub lsp_name: String,
12621    pub(crate) response_channel: Sender<MessageActionItem>,
12622}
12623
12624impl LanguageServerPromptRequest {
12625    pub async fn respond(self, index: usize) -> Option<()> {
12626        if let Some(response) = self.actions.into_iter().nth(index) {
12627            self.response_channel.send(response).await.ok()
12628        } else {
12629            None
12630        }
12631    }
12632}
12633impl PartialEq for LanguageServerPromptRequest {
12634    fn eq(&self, other: &Self) -> bool {
12635        self.message == other.message && self.actions == other.actions
12636    }
12637}
12638
12639#[derive(Clone, Debug, PartialEq)]
12640pub enum LanguageServerLogType {
12641    Log(MessageType),
12642    Trace(Option<String>),
12643}
12644
12645impl LanguageServerLogType {
12646    pub fn to_proto(&self) -> proto::language_server_log::LogType {
12647        match self {
12648            Self::Log(log_type) => {
12649                let message_type = match *log_type {
12650                    MessageType::ERROR => 1,
12651                    MessageType::WARNING => 2,
12652                    MessageType::INFO => 3,
12653                    MessageType::LOG => 4,
12654                    other => {
12655                        log::warn!("Unknown lsp log message type: {:?}", other);
12656                        4
12657                    }
12658                };
12659                proto::language_server_log::LogType::LogMessageType(message_type)
12660            }
12661            Self::Trace(message) => {
12662                proto::language_server_log::LogType::LogTrace(proto::LspLogTrace {
12663                    message: message.clone(),
12664                })
12665            }
12666        }
12667    }
12668
12669    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
12670        match log_type {
12671            proto::language_server_log::LogType::LogMessageType(message_type) => {
12672                Self::Log(match message_type {
12673                    1 => MessageType::ERROR,
12674                    2 => MessageType::WARNING,
12675                    3 => MessageType::INFO,
12676                    4 => MessageType::LOG,
12677                    _ => MessageType::LOG,
12678                })
12679            }
12680            proto::language_server_log::LogType::LogTrace(trace) => Self::Trace(trace.message),
12681        }
12682    }
12683}
12684
12685pub struct WorkspaceRefreshTask {
12686    refresh_tx: mpsc::Sender<()>,
12687    progress_tx: mpsc::Sender<()>,
12688    #[allow(dead_code)]
12689    task: Task<()>,
12690}
12691
12692pub enum LanguageServerState {
12693    Starting {
12694        startup: Task<Option<Arc<LanguageServer>>>,
12695        /// List of language servers that will be added to the workspace once it's initialization completes.
12696        pending_workspace_folders: Arc<Mutex<BTreeSet<Url>>>,
12697    },
12698
12699    Running {
12700        adapter: Arc<CachedLspAdapter>,
12701        server: Arc<LanguageServer>,
12702        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
12703        workspace_refresh_task: Option<WorkspaceRefreshTask>,
12704    },
12705}
12706
12707impl LanguageServerState {
12708    fn add_workspace_folder(&self, uri: Url) {
12709        match self {
12710            LanguageServerState::Starting {
12711                pending_workspace_folders,
12712                ..
12713            } => {
12714                pending_workspace_folders.lock().insert(uri);
12715            }
12716            LanguageServerState::Running { server, .. } => {
12717                server.add_workspace_folder(uri);
12718            }
12719        }
12720    }
12721    fn _remove_workspace_folder(&self, uri: Url) {
12722        match self {
12723            LanguageServerState::Starting {
12724                pending_workspace_folders,
12725                ..
12726            } => {
12727                pending_workspace_folders.lock().remove(&uri);
12728            }
12729            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
12730        }
12731    }
12732}
12733
12734impl std::fmt::Debug for LanguageServerState {
12735    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12736        match self {
12737            LanguageServerState::Starting { .. } => {
12738                f.debug_struct("LanguageServerState::Starting").finish()
12739            }
12740            LanguageServerState::Running { .. } => {
12741                f.debug_struct("LanguageServerState::Running").finish()
12742            }
12743        }
12744    }
12745}
12746
12747#[derive(Clone, Debug, Serialize)]
12748pub struct LanguageServerProgress {
12749    pub is_disk_based_diagnostics_progress: bool,
12750    pub is_cancellable: bool,
12751    pub title: Option<String>,
12752    pub message: Option<String>,
12753    pub percentage: Option<usize>,
12754    #[serde(skip_serializing)]
12755    pub last_update_at: Instant,
12756}
12757
12758#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
12759pub struct DiagnosticSummary {
12760    pub error_count: usize,
12761    pub warning_count: usize,
12762}
12763
12764impl DiagnosticSummary {
12765    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
12766        let mut this = Self {
12767            error_count: 0,
12768            warning_count: 0,
12769        };
12770
12771        for entry in diagnostics {
12772            if entry.diagnostic.is_primary {
12773                match entry.diagnostic.severity {
12774                    DiagnosticSeverity::ERROR => this.error_count += 1,
12775                    DiagnosticSeverity::WARNING => this.warning_count += 1,
12776                    _ => {}
12777                }
12778            }
12779        }
12780
12781        this
12782    }
12783
12784    pub fn is_empty(&self) -> bool {
12785        self.error_count == 0 && self.warning_count == 0
12786    }
12787
12788    pub fn to_proto(
12789        self,
12790        language_server_id: LanguageServerId,
12791        path: &Path,
12792    ) -> proto::DiagnosticSummary {
12793        proto::DiagnosticSummary {
12794            path: path.to_proto(),
12795            language_server_id: language_server_id.0 as u64,
12796            error_count: self.error_count as u32,
12797            warning_count: self.warning_count as u32,
12798        }
12799    }
12800}
12801
12802#[derive(Clone, Debug)]
12803pub enum CompletionDocumentation {
12804    /// There is no documentation for this completion.
12805    Undocumented,
12806    /// A single line of documentation.
12807    SingleLine(SharedString),
12808    /// Multiple lines of plain text documentation.
12809    MultiLinePlainText(SharedString),
12810    /// Markdown documentation.
12811    MultiLineMarkdown(SharedString),
12812    /// Both single line and multiple lines of plain text documentation.
12813    SingleLineAndMultiLinePlainText {
12814        single_line: SharedString,
12815        plain_text: Option<SharedString>,
12816    },
12817}
12818
12819impl From<lsp::Documentation> for CompletionDocumentation {
12820    fn from(docs: lsp::Documentation) -> Self {
12821        match docs {
12822            lsp::Documentation::String(text) => {
12823                if text.lines().count() <= 1 {
12824                    CompletionDocumentation::SingleLine(text.into())
12825                } else {
12826                    CompletionDocumentation::MultiLinePlainText(text.into())
12827                }
12828            }
12829
12830            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
12831                lsp::MarkupKind::PlainText => {
12832                    if value.lines().count() <= 1 {
12833                        CompletionDocumentation::SingleLine(value.into())
12834                    } else {
12835                        CompletionDocumentation::MultiLinePlainText(value.into())
12836                    }
12837                }
12838
12839                lsp::MarkupKind::Markdown => {
12840                    CompletionDocumentation::MultiLineMarkdown(value.into())
12841                }
12842            },
12843        }
12844    }
12845}
12846
12847fn glob_literal_prefix(glob: &Path) -> PathBuf {
12848    glob.components()
12849        .take_while(|component| match component {
12850            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
12851            _ => true,
12852        })
12853        .collect()
12854}
12855
12856pub struct SshLspAdapter {
12857    name: LanguageServerName,
12858    binary: LanguageServerBinary,
12859    initialization_options: Option<String>,
12860    code_action_kinds: Option<Vec<CodeActionKind>>,
12861}
12862
12863impl SshLspAdapter {
12864    pub fn new(
12865        name: LanguageServerName,
12866        binary: LanguageServerBinary,
12867        initialization_options: Option<String>,
12868        code_action_kinds: Option<String>,
12869    ) -> Self {
12870        Self {
12871            name,
12872            binary,
12873            initialization_options,
12874            code_action_kinds: code_action_kinds
12875                .as_ref()
12876                .and_then(|c| serde_json::from_str(c).ok()),
12877        }
12878    }
12879}
12880
12881#[async_trait(?Send)]
12882impl LspAdapter for SshLspAdapter {
12883    fn name(&self) -> LanguageServerName {
12884        self.name.clone()
12885    }
12886
12887    async fn initialization_options(
12888        self: Arc<Self>,
12889        _: &dyn Fs,
12890        _: &Arc<dyn LspAdapterDelegate>,
12891    ) -> Result<Option<serde_json::Value>> {
12892        let Some(options) = &self.initialization_options else {
12893            return Ok(None);
12894        };
12895        let result = serde_json::from_str(options)?;
12896        Ok(result)
12897    }
12898
12899    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
12900        self.code_action_kinds.clone()
12901    }
12902
12903    async fn check_if_user_installed(
12904        &self,
12905        _: &dyn LspAdapterDelegate,
12906        _: Option<Toolchain>,
12907        _: &AsyncApp,
12908    ) -> Option<LanguageServerBinary> {
12909        Some(self.binary.clone())
12910    }
12911
12912    async fn cached_server_binary(
12913        &self,
12914        _: PathBuf,
12915        _: &dyn LspAdapterDelegate,
12916    ) -> Option<LanguageServerBinary> {
12917        None
12918    }
12919
12920    async fn fetch_latest_server_version(
12921        &self,
12922        _: &dyn LspAdapterDelegate,
12923    ) -> Result<Box<dyn 'static + Send + Any>> {
12924        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
12925    }
12926
12927    async fn fetch_server_binary(
12928        &self,
12929        _: Box<dyn 'static + Send + Any>,
12930        _: PathBuf,
12931        _: &dyn LspAdapterDelegate,
12932    ) -> Result<LanguageServerBinary> {
12933        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
12934    }
12935}
12936
12937pub fn language_server_settings<'a>(
12938    delegate: &'a dyn LspAdapterDelegate,
12939    language: &LanguageServerName,
12940    cx: &'a App,
12941) -> Option<&'a LspSettings> {
12942    language_server_settings_for(
12943        SettingsLocation {
12944            worktree_id: delegate.worktree_id(),
12945            path: delegate.worktree_root_path(),
12946        },
12947        language,
12948        cx,
12949    )
12950}
12951
12952pub(crate) fn language_server_settings_for<'a>(
12953    location: SettingsLocation<'a>,
12954    language: &LanguageServerName,
12955    cx: &'a App,
12956) -> Option<&'a LspSettings> {
12957    ProjectSettings::get(Some(location), cx).lsp.get(language)
12958}
12959
12960pub struct LocalLspAdapterDelegate {
12961    lsp_store: WeakEntity<LspStore>,
12962    worktree: worktree::Snapshot,
12963    fs: Arc<dyn Fs>,
12964    http_client: Arc<dyn HttpClient>,
12965    language_registry: Arc<LanguageRegistry>,
12966    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
12967}
12968
12969impl LocalLspAdapterDelegate {
12970    pub fn new(
12971        language_registry: Arc<LanguageRegistry>,
12972        environment: &Entity<ProjectEnvironment>,
12973        lsp_store: WeakEntity<LspStore>,
12974        worktree: &Entity<Worktree>,
12975        http_client: Arc<dyn HttpClient>,
12976        fs: Arc<dyn Fs>,
12977        cx: &mut App,
12978    ) -> Arc<Self> {
12979        let load_shell_env_task = environment.update(cx, |env, cx| {
12980            env.get_worktree_environment(worktree.clone(), cx)
12981        });
12982
12983        Arc::new(Self {
12984            lsp_store,
12985            worktree: worktree.read(cx).snapshot(),
12986            fs,
12987            http_client,
12988            language_registry,
12989            load_shell_env_task,
12990        })
12991    }
12992
12993    fn from_local_lsp(
12994        local: &LocalLspStore,
12995        worktree: &Entity<Worktree>,
12996        cx: &mut App,
12997    ) -> Arc<Self> {
12998        Self::new(
12999            local.languages.clone(),
13000            &local.environment,
13001            local.weak.clone(),
13002            worktree,
13003            local.http_client.clone(),
13004            local.fs.clone(),
13005            cx,
13006        )
13007    }
13008}
13009
13010#[async_trait]
13011impl LspAdapterDelegate for LocalLspAdapterDelegate {
13012    fn show_notification(&self, message: &str, cx: &mut App) {
13013        self.lsp_store
13014            .update(cx, |_, cx| {
13015                cx.emit(LspStoreEvent::Notification(message.to_owned()))
13016            })
13017            .ok();
13018    }
13019
13020    fn http_client(&self) -> Arc<dyn HttpClient> {
13021        self.http_client.clone()
13022    }
13023
13024    fn worktree_id(&self) -> WorktreeId {
13025        self.worktree.id()
13026    }
13027
13028    fn worktree_root_path(&self) -> &Path {
13029        self.worktree.abs_path().as_ref()
13030    }
13031
13032    async fn shell_env(&self) -> HashMap<String, String> {
13033        let task = self.load_shell_env_task.clone();
13034        task.await.unwrap_or_default()
13035    }
13036
13037    async fn npm_package_installed_version(
13038        &self,
13039        package_name: &str,
13040    ) -> Result<Option<(PathBuf, String)>> {
13041        let local_package_directory = self.worktree_root_path();
13042        let node_modules_directory = local_package_directory.join("node_modules");
13043
13044        if let Some(version) =
13045            read_package_installed_version(node_modules_directory.clone(), package_name).await?
13046        {
13047            return Ok(Some((node_modules_directory, version)));
13048        }
13049        let Some(npm) = self.which("npm".as_ref()).await else {
13050            log::warn!(
13051                "Failed to find npm executable for {:?}",
13052                local_package_directory
13053            );
13054            return Ok(None);
13055        };
13056
13057        let env = self.shell_env().await;
13058        let output = util::command::new_smol_command(&npm)
13059            .args(["root", "-g"])
13060            .envs(env)
13061            .current_dir(local_package_directory)
13062            .output()
13063            .await?;
13064        let global_node_modules =
13065            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
13066
13067        if let Some(version) =
13068            read_package_installed_version(global_node_modules.clone(), package_name).await?
13069        {
13070            return Ok(Some((global_node_modules, version)));
13071        }
13072        return Ok(None);
13073    }
13074
13075    #[cfg(not(target_os = "windows"))]
13076    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
13077        let worktree_abs_path = self.worktree.abs_path();
13078        let shell_path = self.shell_env().await.get("PATH").cloned();
13079        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
13080    }
13081
13082    #[cfg(target_os = "windows")]
13083    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
13084        // todo(windows) Getting the shell env variables in a current directory on Windows is more complicated than other platforms
13085        //               there isn't a 'default shell' necessarily. The closest would be the default profile on the windows terminal
13086        //               SEE: https://learn.microsoft.com/en-us/windows/terminal/customize-settings/startup
13087        which::which(command).ok()
13088    }
13089
13090    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
13091        let working_dir = self.worktree_root_path();
13092        let output = util::command::new_smol_command(&command.path)
13093            .args(command.arguments)
13094            .envs(command.env.clone().unwrap_or_default())
13095            .current_dir(working_dir)
13096            .output()
13097            .await?;
13098
13099        anyhow::ensure!(
13100            output.status.success(),
13101            "{}, stdout: {:?}, stderr: {:?}",
13102            output.status,
13103            String::from_utf8_lossy(&output.stdout),
13104            String::from_utf8_lossy(&output.stderr)
13105        );
13106        Ok(())
13107    }
13108
13109    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
13110        self.language_registry
13111            .update_lsp_binary_status(server_name, status);
13112    }
13113
13114    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
13115        self.language_registry
13116            .all_lsp_adapters()
13117            .into_iter()
13118            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
13119            .collect()
13120    }
13121
13122    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
13123        let dir = self.language_registry.language_server_download_dir(name)?;
13124
13125        if !dir.exists() {
13126            smol::fs::create_dir_all(&dir)
13127                .await
13128                .context("failed to create container directory")
13129                .log_err()?;
13130        }
13131
13132        Some(dir)
13133    }
13134
13135    async fn read_text_file(&self, path: PathBuf) -> Result<String> {
13136        let entry = self
13137            .worktree
13138            .entry_for_path(&path)
13139            .with_context(|| format!("no worktree entry for path {path:?}"))?;
13140        let abs_path = self
13141            .worktree
13142            .absolutize(&entry.path)
13143            .with_context(|| format!("cannot absolutize path {path:?}"))?;
13144
13145        self.fs.load(&abs_path).await
13146    }
13147}
13148
13149async fn populate_labels_for_symbols(
13150    symbols: Vec<CoreSymbol>,
13151    language_registry: &Arc<LanguageRegistry>,
13152    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13153    output: &mut Vec<Symbol>,
13154) {
13155    #[allow(clippy::mutable_key_type)]
13156    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
13157
13158    let mut unknown_paths = BTreeSet::new();
13159    for symbol in symbols {
13160        let language = language_registry
13161            .language_for_file_path(&symbol.path.path)
13162            .await
13163            .ok()
13164            .or_else(|| {
13165                unknown_paths.insert(symbol.path.path.clone());
13166                None
13167            });
13168        symbols_by_language
13169            .entry(language)
13170            .or_default()
13171            .push(symbol);
13172    }
13173
13174    for unknown_path in unknown_paths {
13175        log::info!(
13176            "no language found for symbol path {}",
13177            unknown_path.display()
13178        );
13179    }
13180
13181    let mut label_params = Vec::new();
13182    for (language, mut symbols) in symbols_by_language {
13183        label_params.clear();
13184        label_params.extend(
13185            symbols
13186                .iter_mut()
13187                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
13188        );
13189
13190        let mut labels = Vec::new();
13191        if let Some(language) = language {
13192            let lsp_adapter = lsp_adapter.clone().or_else(|| {
13193                language_registry
13194                    .lsp_adapters(&language.name())
13195                    .first()
13196                    .cloned()
13197            });
13198            if let Some(lsp_adapter) = lsp_adapter {
13199                labels = lsp_adapter
13200                    .labels_for_symbols(&label_params, &language)
13201                    .await
13202                    .log_err()
13203                    .unwrap_or_default();
13204            }
13205        }
13206
13207        for ((symbol, (name, _)), label) in symbols
13208            .into_iter()
13209            .zip(label_params.drain(..))
13210            .zip(labels.into_iter().chain(iter::repeat(None)))
13211        {
13212            output.push(Symbol {
13213                language_server_name: symbol.language_server_name,
13214                source_worktree_id: symbol.source_worktree_id,
13215                source_language_server_id: symbol.source_language_server_id,
13216                path: symbol.path,
13217                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
13218                name,
13219                kind: symbol.kind,
13220                range: symbol.range,
13221                signature: symbol.signature,
13222            });
13223        }
13224    }
13225}
13226
13227/// Completion items are displayed in a `UniformList`.
13228/// Usually, those items are single-line strings, but in LSP responses,
13229/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
13230/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
13231/// 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,
13232/// breaking the completions menu presentation.
13233///
13234/// 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.
13235fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
13236    let mut new_text = String::with_capacity(label.text.len());
13237    let mut offset_map = vec![0; label.text.len() + 1];
13238    let mut last_char_was_space = false;
13239    let mut new_idx = 0;
13240    let chars = label.text.char_indices().fuse();
13241    let mut newlines_removed = false;
13242
13243    for (idx, c) in chars {
13244        offset_map[idx] = new_idx;
13245
13246        match c {
13247            '\n' if last_char_was_space => {
13248                newlines_removed = true;
13249            }
13250            '\t' | ' ' if last_char_was_space => {}
13251            '\n' if !last_char_was_space => {
13252                new_text.push(' ');
13253                new_idx += 1;
13254                last_char_was_space = true;
13255                newlines_removed = true;
13256            }
13257            ' ' | '\t' => {
13258                new_text.push(' ');
13259                new_idx += 1;
13260                last_char_was_space = true;
13261            }
13262            _ => {
13263                new_text.push(c);
13264                new_idx += c.len_utf8();
13265                last_char_was_space = false;
13266            }
13267        }
13268    }
13269    offset_map[label.text.len()] = new_idx;
13270
13271    // Only modify the label if newlines were removed.
13272    if !newlines_removed {
13273        return;
13274    }
13275
13276    let last_index = new_idx;
13277    let mut run_ranges_errors = Vec::new();
13278    label.runs.retain_mut(|(range, _)| {
13279        match offset_map.get(range.start) {
13280            Some(&start) => range.start = start,
13281            None => {
13282                run_ranges_errors.push(range.clone());
13283                return false;
13284            }
13285        }
13286
13287        match offset_map.get(range.end) {
13288            Some(&end) => range.end = end,
13289            None => {
13290                run_ranges_errors.push(range.clone());
13291                range.end = last_index;
13292            }
13293        }
13294        true
13295    });
13296    if !run_ranges_errors.is_empty() {
13297        log::error!(
13298            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
13299            label.text
13300        );
13301    }
13302
13303    let mut wrong_filter_range = None;
13304    if label.filter_range == (0..label.text.len()) {
13305        label.filter_range = 0..new_text.len();
13306    } else {
13307        let mut original_filter_range = Some(label.filter_range.clone());
13308        match offset_map.get(label.filter_range.start) {
13309            Some(&start) => label.filter_range.start = start,
13310            None => {
13311                wrong_filter_range = original_filter_range.take();
13312                label.filter_range.start = last_index;
13313            }
13314        }
13315
13316        match offset_map.get(label.filter_range.end) {
13317            Some(&end) => label.filter_range.end = end,
13318            None => {
13319                wrong_filter_range = original_filter_range.take();
13320                label.filter_range.end = last_index;
13321            }
13322        }
13323    }
13324    if let Some(wrong_filter_range) = wrong_filter_range {
13325        log::error!(
13326            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
13327            label.text
13328        );
13329    }
13330
13331    label.text = new_text;
13332}
13333
13334#[cfg(test)]
13335mod tests {
13336    use language::HighlightId;
13337
13338    use super::*;
13339
13340    #[test]
13341    fn test_glob_literal_prefix() {
13342        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
13343        assert_eq!(
13344            glob_literal_prefix(Path::new("node_modules/**/*.js")),
13345            Path::new("node_modules")
13346        );
13347        assert_eq!(
13348            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13349            Path::new("foo")
13350        );
13351        assert_eq!(
13352            glob_literal_prefix(Path::new("foo/bar/baz.js")),
13353            Path::new("foo/bar/baz.js")
13354        );
13355
13356        #[cfg(target_os = "windows")]
13357        {
13358            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
13359            assert_eq!(
13360                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
13361                Path::new("node_modules")
13362            );
13363            assert_eq!(
13364                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13365                Path::new("foo")
13366            );
13367            assert_eq!(
13368                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
13369                Path::new("foo/bar/baz.js")
13370            );
13371        }
13372    }
13373
13374    #[test]
13375    fn test_multi_len_chars_normalization() {
13376        let mut label = CodeLabel {
13377            text: "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
13378            runs: vec![(0..6, HighlightId(1))],
13379            filter_range: 0..6,
13380        };
13381        ensure_uniform_list_compatible_label(&mut label);
13382        assert_eq!(
13383            label,
13384            CodeLabel {
13385                text: "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
13386                runs: vec![(0..6, HighlightId(1))],
13387                filter_range: 0..6,
13388            }
13389        );
13390    }
13391}