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 log_store;
   15pub mod lsp_ext_command;
   16pub mod rust_analyzer_ext;
   17pub mod vue_language_server_ext;
   18
   19mod inlay_hint_cache;
   20
   21use self::inlay_hint_cache::BufferInlayHints;
   22use crate::{
   23    CodeAction, ColorPresentation, Completion, CompletionDisplayOptions, CompletionResponse,
   24    CompletionSource, CoreCompletion, DocumentColor, Hover, InlayHint, InlayId, LocationLink,
   25    LspAction, LspPullDiagnostics, ManifestProvidersStore, Project, ProjectItem, ProjectPath,
   26    ProjectTransaction, PulledDiagnostics, ResolveState, Symbol,
   27    buffer_store::{BufferStore, BufferStoreEvent},
   28    environment::ProjectEnvironment,
   29    lsp_command::{self, *},
   30    lsp_store::{
   31        self,
   32        log_store::{GlobalLogStore, LanguageServerKind},
   33    },
   34    manifest_tree::{
   35        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   36        ManifestTree,
   37    },
   38    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   39    project_settings::{LspSettings, ProjectSettings},
   40    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   41    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   42    yarn::YarnPathStore,
   43};
   44use anyhow::{Context as _, Result, anyhow};
   45use async_trait::async_trait;
   46use client::{TypedEnvelope, proto};
   47use clock::Global;
   48use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   49use futures::{
   50    AsyncWriteExt, Future, FutureExt, StreamExt,
   51    future::{Either, Shared, join_all, pending, select},
   52    select, select_biased,
   53    stream::FuturesUnordered,
   54};
   55use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   56use gpui::{
   57    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString, Task,
   58    WeakEntity,
   59};
   60use http_client::HttpClient;
   61use itertools::Itertools as _;
   62use language::{
   63    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, CodeLabel, Diagnostic,
   64    DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language, LanguageName,
   65    LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller, ManifestDelegate,
   66    ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Toolchain,
   67    Transaction, Unclipped,
   68    language_settings::{FormatOnSave, Formatter, LanguageSettings, language_settings},
   69    point_to_lsp,
   70    proto::{
   71        deserialize_anchor, deserialize_lsp_edit, deserialize_version, serialize_anchor,
   72        serialize_lsp_edit, serialize_version,
   73    },
   74    range_from_lsp, range_to_lsp,
   75    row_chunk::RowChunk,
   76};
   77use lsp::{
   78    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   79    DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   80    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   81    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LSP_REQUEST_TIMEOUT,
   82    LanguageServer, LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId,
   83    LanguageServerName, LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType,
   84    OneOf, RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri,
   85    WillRenameFiles, WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   86};
   87use node_runtime::read_package_installed_version;
   88use parking_lot::Mutex;
   89use postage::{mpsc, sink::Sink, stream::Stream, watch};
   90use rand::prelude::*;
   91use rpc::{
   92    AnyProtoClient, ErrorCode, ErrorExt as _,
   93    proto::{LspRequestId, LspRequestMessage as _},
   94};
   95use serde::Serialize;
   96use settings::{Settings, SettingsLocation, SettingsStore};
   97use sha2::{Digest, Sha256};
   98use smol::channel::Sender;
   99use snippet::Snippet;
  100use std::{
  101    any::TypeId,
  102    borrow::Cow,
  103    cell::RefCell,
  104    cmp::{Ordering, Reverse},
  105    convert::TryInto,
  106    ffi::OsStr,
  107    future::ready,
  108    iter, mem,
  109    ops::{ControlFlow, Range},
  110    path::{self, Path, PathBuf},
  111    pin::pin,
  112    rc::Rc,
  113    sync::{
  114        Arc,
  115        atomic::{self, AtomicUsize},
  116    },
  117    time::{Duration, Instant},
  118};
  119use sum_tree::Dimensions;
  120use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  121
  122use util::{
  123    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  124    paths::{PathStyle, SanitizedPath},
  125    post_inc,
  126    rel_path::RelPath,
  127};
  128
  129pub use fs::*;
  130pub use language::Location;
  131pub use lsp_store::inlay_hint_cache::{CacheInlayHints, InvalidationStrategy};
  132#[cfg(any(test, feature = "test-support"))]
  133pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  134pub use worktree::{
  135    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  136    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  137};
  138
  139const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  140pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  141const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  142const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  143
  144#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  145pub enum ProgressToken {
  146    Number(i32),
  147    String(SharedString),
  148}
  149
  150impl std::fmt::Display for ProgressToken {
  151    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  152        match self {
  153            Self::Number(number) => write!(f, "{number}"),
  154            Self::String(string) => write!(f, "{string}"),
  155        }
  156    }
  157}
  158
  159impl ProgressToken {
  160    fn from_lsp(value: lsp::NumberOrString) -> Self {
  161        match value {
  162            lsp::NumberOrString::Number(number) => Self::Number(number),
  163            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  164        }
  165    }
  166
  167    fn to_lsp(&self) -> lsp::NumberOrString {
  168        match self {
  169            Self::Number(number) => lsp::NumberOrString::Number(*number),
  170            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  171        }
  172    }
  173
  174    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  175        Some(match value.value? {
  176            proto::progress_token::Value::Number(number) => Self::Number(number),
  177            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  178        })
  179    }
  180
  181    fn to_proto(&self) -> proto::ProgressToken {
  182        proto::ProgressToken {
  183            value: Some(match self {
  184                Self::Number(number) => proto::progress_token::Value::Number(*number),
  185                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  186            }),
  187        }
  188    }
  189}
  190
  191#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  192pub enum FormatTrigger {
  193    Save,
  194    Manual,
  195}
  196
  197pub enum LspFormatTarget {
  198    Buffers,
  199    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  200}
  201
  202pub type OpenLspBufferHandle = Entity<Entity<Buffer>>;
  203
  204impl FormatTrigger {
  205    fn from_proto(value: i32) -> FormatTrigger {
  206        match value {
  207            0 => FormatTrigger::Save,
  208            1 => FormatTrigger::Manual,
  209            _ => FormatTrigger::Save,
  210        }
  211    }
  212}
  213
  214#[derive(Clone)]
  215struct UnifiedLanguageServer {
  216    id: LanguageServerId,
  217    project_roots: HashSet<Arc<RelPath>>,
  218}
  219
  220#[derive(Clone, Hash, PartialEq, Eq)]
  221struct LanguageServerSeed {
  222    worktree_id: WorktreeId,
  223    name: LanguageServerName,
  224    toolchain: Option<Toolchain>,
  225    settings: Arc<LspSettings>,
  226}
  227
  228#[derive(Debug)]
  229pub struct DocumentDiagnosticsUpdate<'a, D> {
  230    pub diagnostics: D,
  231    pub result_id: Option<String>,
  232    pub server_id: LanguageServerId,
  233    pub disk_based_sources: Cow<'a, [String]>,
  234}
  235
  236pub struct DocumentDiagnostics {
  237    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  238    document_abs_path: PathBuf,
  239    version: Option<i32>,
  240}
  241
  242#[derive(Default, Debug)]
  243struct DynamicRegistrations {
  244    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  245    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  246}
  247
  248pub struct LocalLspStore {
  249    weak: WeakEntity<LspStore>,
  250    worktree_store: Entity<WorktreeStore>,
  251    toolchain_store: Entity<LocalToolchainStore>,
  252    http_client: Arc<dyn HttpClient>,
  253    environment: Entity<ProjectEnvironment>,
  254    fs: Arc<dyn Fs>,
  255    languages: Arc<LanguageRegistry>,
  256    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  257    yarn: Entity<YarnPathStore>,
  258    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  259    buffers_being_formatted: HashSet<BufferId>,
  260    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  261    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  262    watched_manifest_filenames: HashSet<ManifestName>,
  263    language_server_paths_watched_for_rename:
  264        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  265    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  266    supplementary_language_servers:
  267        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  268    prettier_store: Entity<PrettierStore>,
  269    next_diagnostic_group_id: usize,
  270    diagnostics: HashMap<
  271        WorktreeId,
  272        HashMap<
  273            Arc<RelPath>,
  274            Vec<(
  275                LanguageServerId,
  276                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  277            )>,
  278        >,
  279    >,
  280    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  281    _subscription: gpui::Subscription,
  282    lsp_tree: LanguageServerTree,
  283    registered_buffers: HashMap<BufferId, usize>,
  284    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  285    buffer_pull_diagnostics_result_ids: HashMap<LanguageServerId, HashMap<PathBuf, Option<String>>>,
  286}
  287
  288impl LocalLspStore {
  289    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  290    pub fn running_language_server_for_id(
  291        &self,
  292        id: LanguageServerId,
  293    ) -> Option<&Arc<LanguageServer>> {
  294        let language_server_state = self.language_servers.get(&id)?;
  295
  296        match language_server_state {
  297            LanguageServerState::Running { server, .. } => Some(server),
  298            LanguageServerState::Starting { .. } => None,
  299        }
  300    }
  301
  302    fn get_or_insert_language_server(
  303        &mut self,
  304        worktree_handle: &Entity<Worktree>,
  305        delegate: Arc<LocalLspAdapterDelegate>,
  306        disposition: &Arc<LaunchDisposition>,
  307        language_name: &LanguageName,
  308        cx: &mut App,
  309    ) -> LanguageServerId {
  310        let key = LanguageServerSeed {
  311            worktree_id: worktree_handle.read(cx).id(),
  312            name: disposition.server_name.clone(),
  313            settings: disposition.settings.clone(),
  314            toolchain: disposition.toolchain.clone(),
  315        };
  316        if let Some(state) = self.language_server_ids.get_mut(&key) {
  317            state.project_roots.insert(disposition.path.path.clone());
  318            state.id
  319        } else {
  320            let adapter = self
  321                .languages
  322                .lsp_adapters(language_name)
  323                .into_iter()
  324                .find(|adapter| adapter.name() == disposition.server_name)
  325                .expect("To find LSP adapter");
  326            let new_language_server_id = self.start_language_server(
  327                worktree_handle,
  328                delegate,
  329                adapter,
  330                disposition.settings.clone(),
  331                key.clone(),
  332                cx,
  333            );
  334            if let Some(state) = self.language_server_ids.get_mut(&key) {
  335                state.project_roots.insert(disposition.path.path.clone());
  336            } else {
  337                debug_assert!(
  338                    false,
  339                    "Expected `start_language_server` to ensure that `key` exists in a map"
  340                );
  341            }
  342            new_language_server_id
  343        }
  344    }
  345
  346    fn start_language_server(
  347        &mut self,
  348        worktree_handle: &Entity<Worktree>,
  349        delegate: Arc<LocalLspAdapterDelegate>,
  350        adapter: Arc<CachedLspAdapter>,
  351        settings: Arc<LspSettings>,
  352        key: LanguageServerSeed,
  353        cx: &mut App,
  354    ) -> LanguageServerId {
  355        let worktree = worktree_handle.read(cx);
  356
  357        let root_path = worktree.abs_path();
  358        let toolchain = key.toolchain.clone();
  359        let override_options = settings.initialization_options.clone();
  360
  361        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  362
  363        let server_id = self.languages.next_language_server_id();
  364        log::trace!(
  365            "attempting to start language server {:?}, path: {root_path:?}, id: {server_id}",
  366            adapter.name.0
  367        );
  368
  369        let binary = self.get_language_server_binary(
  370            adapter.clone(),
  371            settings,
  372            toolchain.clone(),
  373            delegate.clone(),
  374            true,
  375            cx,
  376        );
  377        let pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>> = Default::default();
  378
  379        let pending_server = cx.spawn({
  380            let adapter = adapter.clone();
  381            let server_name = adapter.name.clone();
  382            let stderr_capture = stderr_capture.clone();
  383            #[cfg(any(test, feature = "test-support"))]
  384            let lsp_store = self.weak.clone();
  385            let pending_workspace_folders = pending_workspace_folders.clone();
  386            async move |cx| {
  387                let binary = binary.await?;
  388                #[cfg(any(test, feature = "test-support"))]
  389                if let Some(server) = lsp_store
  390                    .update(&mut cx.clone(), |this, cx| {
  391                        this.languages.create_fake_language_server(
  392                            server_id,
  393                            &server_name,
  394                            binary.clone(),
  395                            &mut cx.to_async(),
  396                        )
  397                    })
  398                    .ok()
  399                    .flatten()
  400                {
  401                    return Ok(server);
  402                }
  403
  404                let code_action_kinds = adapter.code_action_kinds();
  405                lsp::LanguageServer::new(
  406                    stderr_capture,
  407                    server_id,
  408                    server_name,
  409                    binary,
  410                    &root_path,
  411                    code_action_kinds,
  412                    Some(pending_workspace_folders),
  413                    cx,
  414                )
  415            }
  416        });
  417
  418        let startup = {
  419            let server_name = adapter.name.0.clone();
  420            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  421            let key = key.clone();
  422            let adapter = adapter.clone();
  423            let lsp_store = self.weak.clone();
  424            let pending_workspace_folders = pending_workspace_folders.clone();
  425
  426            let pull_diagnostics = ProjectSettings::get_global(cx)
  427                .diagnostics
  428                .lsp_pull_diagnostics
  429                .enabled;
  430            cx.spawn(async move |cx| {
  431                let result = async {
  432                    let language_server = pending_server.await?;
  433
  434                    let workspace_config = Self::workspace_configuration_for_adapter(
  435                        adapter.adapter.clone(),
  436                        &delegate,
  437                        toolchain,
  438                        cx,
  439                    )
  440                    .await?;
  441
  442                    let mut initialization_options = Self::initialization_options_for_adapter(
  443                        adapter.adapter.clone(),
  444                        &delegate,
  445                    )
  446                    .await?;
  447
  448                    match (&mut initialization_options, override_options) {
  449                        (Some(initialization_options), Some(override_options)) => {
  450                            merge_json_value_into(override_options, initialization_options);
  451                        }
  452                        (None, override_options) => initialization_options = override_options,
  453                        _ => {}
  454                    }
  455
  456                    let initialization_params = cx.update(|cx| {
  457                        let mut params =
  458                            language_server.default_initialize_params(pull_diagnostics, cx);
  459                        params.initialization_options = initialization_options;
  460                        adapter.adapter.prepare_initialize_params(params, cx)
  461                    })??;
  462
  463                    Self::setup_lsp_messages(
  464                        lsp_store.clone(),
  465                        &language_server,
  466                        delegate.clone(),
  467                        adapter.clone(),
  468                    );
  469
  470                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  471                        settings: workspace_config,
  472                    };
  473                    let language_server = cx
  474                        .update(|cx| {
  475                            language_server.initialize(
  476                                initialization_params,
  477                                Arc::new(did_change_configuration_params.clone()),
  478                                cx,
  479                            )
  480                        })?
  481                        .await
  482                        .inspect_err(|_| {
  483                            if let Some(lsp_store) = lsp_store.upgrade() {
  484                                lsp_store
  485                                    .update(cx, |lsp_store, cx| {
  486                                        lsp_store.cleanup_lsp_data(server_id);
  487                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  488                                    })
  489                                    .ok();
  490                            }
  491                        })?;
  492
  493                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  494                        did_change_configuration_params,
  495                    )?;
  496
  497                    anyhow::Ok(language_server)
  498                }
  499                .await;
  500
  501                match result {
  502                    Ok(server) => {
  503                        lsp_store
  504                            .update(cx, |lsp_store, cx| {
  505                                lsp_store.insert_newly_running_language_server(
  506                                    adapter,
  507                                    server.clone(),
  508                                    server_id,
  509                                    key,
  510                                    pending_workspace_folders,
  511                                    cx,
  512                                );
  513                            })
  514                            .ok();
  515                        stderr_capture.lock().take();
  516                        Some(server)
  517                    }
  518
  519                    Err(err) => {
  520                        let log = stderr_capture.lock().take().unwrap_or_default();
  521                        delegate.update_status(
  522                            adapter.name(),
  523                            BinaryStatus::Failed {
  524                                error: if log.is_empty() {
  525                                    format!("{err:#}")
  526                                } else {
  527                                    format!("{err:#}\n-- stderr --\n{log}")
  528                                },
  529                            },
  530                        );
  531                        log::error!("Failed to start language server {server_name:?}: {err:?}");
  532                        if !log.is_empty() {
  533                            log::error!("server stderr: {log}");
  534                        }
  535                        None
  536                    }
  537                }
  538            })
  539        };
  540        let state = LanguageServerState::Starting {
  541            startup,
  542            pending_workspace_folders,
  543        };
  544
  545        self.languages
  546            .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  547
  548        self.language_servers.insert(server_id, state);
  549        self.language_server_ids
  550            .entry(key)
  551            .or_insert(UnifiedLanguageServer {
  552                id: server_id,
  553                project_roots: Default::default(),
  554            });
  555        server_id
  556    }
  557
  558    fn get_language_server_binary(
  559        &self,
  560        adapter: Arc<CachedLspAdapter>,
  561        settings: Arc<LspSettings>,
  562        toolchain: Option<Toolchain>,
  563        delegate: Arc<dyn LspAdapterDelegate>,
  564        allow_binary_download: bool,
  565        cx: &mut App,
  566    ) -> Task<Result<LanguageServerBinary>> {
  567        if let Some(settings) = &settings.binary
  568            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  569        {
  570            let settings = settings.clone();
  571
  572            return cx.background_spawn(async move {
  573                let mut env = delegate.shell_env().await;
  574                env.extend(settings.env.unwrap_or_default());
  575
  576                Ok(LanguageServerBinary {
  577                    path: delegate.resolve_executable_path(path),
  578                    env: Some(env),
  579                    arguments: settings
  580                        .arguments
  581                        .unwrap_or_default()
  582                        .iter()
  583                        .map(Into::into)
  584                        .collect(),
  585                })
  586            });
  587        }
  588        let lsp_binary_options = LanguageServerBinaryOptions {
  589            allow_path_lookup: !settings
  590                .binary
  591                .as_ref()
  592                .and_then(|b| b.ignore_system_version)
  593                .unwrap_or_default(),
  594            allow_binary_download,
  595            pre_release: settings
  596                .fetch
  597                .as_ref()
  598                .and_then(|f| f.pre_release)
  599                .unwrap_or(false),
  600        };
  601
  602        cx.spawn(async move |cx| {
  603            let (existing_binary, maybe_download_binary) = adapter
  604                .clone()
  605                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  606                .await
  607                .await;
  608
  609            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  610
  611            let mut binary = match (existing_binary, maybe_download_binary) {
  612                (binary, None) => binary?,
  613                (Err(_), Some(downloader)) => downloader.await?,
  614                (Ok(existing_binary), Some(downloader)) => {
  615                    let mut download_timeout = cx
  616                        .background_executor()
  617                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  618                        .fuse();
  619                    let mut downloader = downloader.fuse();
  620                    futures::select! {
  621                        _ = download_timeout => {
  622                            // Return existing binary and kick the existing work to the background.
  623                            cx.spawn(async move |_| downloader.await).detach();
  624                            Ok(existing_binary)
  625                        },
  626                        downloaded_or_existing_binary = downloader => {
  627                            // If download fails, this results in the existing binary.
  628                            downloaded_or_existing_binary
  629                        }
  630                    }?
  631                }
  632            };
  633            let mut shell_env = delegate.shell_env().await;
  634
  635            shell_env.extend(binary.env.unwrap_or_default());
  636
  637            if let Some(settings) = settings.binary.as_ref() {
  638                if let Some(arguments) = &settings.arguments {
  639                    binary.arguments = arguments.iter().map(Into::into).collect();
  640                }
  641                if let Some(env) = &settings.env {
  642                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  643                }
  644            }
  645
  646            binary.env = Some(shell_env);
  647            Ok(binary)
  648        })
  649    }
  650
  651    fn setup_lsp_messages(
  652        lsp_store: WeakEntity<LspStore>,
  653        language_server: &LanguageServer,
  654        delegate: Arc<dyn LspAdapterDelegate>,
  655        adapter: Arc<CachedLspAdapter>,
  656    ) {
  657        let name = language_server.name();
  658        let server_id = language_server.server_id();
  659        language_server
  660            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  661                let adapter = adapter.clone();
  662                let this = lsp_store.clone();
  663                move |mut params, cx| {
  664                    let adapter = adapter.clone();
  665                    if let Some(this) = this.upgrade() {
  666                        this.update(cx, |this, cx| {
  667                            {
  668                                let buffer = params
  669                                    .uri
  670                                    .to_file_path()
  671                                    .map(|file_path| this.get_buffer(&file_path, cx))
  672                                    .ok()
  673                                    .flatten();
  674                                adapter.process_diagnostics(&mut params, server_id, buffer);
  675                            }
  676
  677                            this.merge_lsp_diagnostics(
  678                                DiagnosticSourceKind::Pushed,
  679                                vec![DocumentDiagnosticsUpdate {
  680                                    server_id,
  681                                    diagnostics: params,
  682                                    result_id: None,
  683                                    disk_based_sources: Cow::Borrowed(
  684                                        &adapter.disk_based_diagnostic_sources,
  685                                    ),
  686                                }],
  687                                |_, diagnostic, cx| match diagnostic.source_kind {
  688                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  689                                        adapter.retain_old_diagnostic(diagnostic, cx)
  690                                    }
  691                                    DiagnosticSourceKind::Pulled => true,
  692                                },
  693                                cx,
  694                            )
  695                            .log_err();
  696                        })
  697                        .ok();
  698                    }
  699                }
  700            })
  701            .detach();
  702        language_server
  703            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  704                let adapter = adapter.adapter.clone();
  705                let delegate = delegate.clone();
  706                let this = lsp_store.clone();
  707                move |params, cx| {
  708                    let adapter = adapter.clone();
  709                    let delegate = delegate.clone();
  710                    let this = this.clone();
  711                    let mut cx = cx.clone();
  712                    async move {
  713                        let toolchain_for_id = this
  714                            .update(&mut cx, |this, _| {
  715                                this.as_local()?.language_server_ids.iter().find_map(
  716                                    |(seed, value)| {
  717                                        (value.id == server_id).then(|| seed.toolchain.clone())
  718                                    },
  719                                )
  720                            })?
  721                            .context("Expected the LSP store to be in a local mode")?;
  722                        let workspace_config = Self::workspace_configuration_for_adapter(
  723                            adapter.clone(),
  724                            &delegate,
  725                            toolchain_for_id,
  726                            &mut cx,
  727                        )
  728                        .await?;
  729
  730                        Ok(params
  731                            .items
  732                            .into_iter()
  733                            .map(|item| {
  734                                if let Some(section) = &item.section {
  735                                    workspace_config
  736                                        .get(section)
  737                                        .cloned()
  738                                        .unwrap_or(serde_json::Value::Null)
  739                                } else {
  740                                    workspace_config.clone()
  741                                }
  742                            })
  743                            .collect())
  744                    }
  745                }
  746            })
  747            .detach();
  748
  749        language_server
  750            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  751                let this = lsp_store.clone();
  752                move |_, cx| {
  753                    let this = this.clone();
  754                    let cx = cx.clone();
  755                    async move {
  756                        let Some(server) =
  757                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  758                        else {
  759                            return Ok(None);
  760                        };
  761                        let root = server.workspace_folders();
  762                        Ok(Some(
  763                            root.into_iter()
  764                                .map(|uri| WorkspaceFolder {
  765                                    uri,
  766                                    name: Default::default(),
  767                                })
  768                                .collect(),
  769                        ))
  770                    }
  771                }
  772            })
  773            .detach();
  774        // Even though we don't have handling for these requests, respond to them to
  775        // avoid stalling any language server like `gopls` which waits for a response
  776        // to these requests when initializing.
  777        language_server
  778            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  779                let this = lsp_store.clone();
  780                move |params, cx| {
  781                    let this = this.clone();
  782                    let mut cx = cx.clone();
  783                    async move {
  784                        this.update(&mut cx, |this, _| {
  785                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  786                            {
  787                                status
  788                                    .progress_tokens
  789                                    .insert(ProgressToken::from_lsp(params.token));
  790                            }
  791                        })?;
  792
  793                        Ok(())
  794                    }
  795                }
  796            })
  797            .detach();
  798
  799        language_server
  800            .on_request::<lsp::request::RegisterCapability, _, _>({
  801                let lsp_store = lsp_store.clone();
  802                move |params, cx| {
  803                    let lsp_store = lsp_store.clone();
  804                    let mut cx = cx.clone();
  805                    async move {
  806                        lsp_store
  807                            .update(&mut cx, |lsp_store, cx| {
  808                                if lsp_store.as_local().is_some() {
  809                                    match lsp_store
  810                                        .register_server_capabilities(server_id, params, cx)
  811                                    {
  812                                        Ok(()) => {}
  813                                        Err(e) => {
  814                                            log::error!(
  815                                                "Failed to register server capabilities: {e:#}"
  816                                            );
  817                                        }
  818                                    };
  819                                }
  820                            })
  821                            .ok();
  822                        Ok(())
  823                    }
  824                }
  825            })
  826            .detach();
  827
  828        language_server
  829            .on_request::<lsp::request::UnregisterCapability, _, _>({
  830                let lsp_store = lsp_store.clone();
  831                move |params, cx| {
  832                    let lsp_store = lsp_store.clone();
  833                    let mut cx = cx.clone();
  834                    async move {
  835                        lsp_store
  836                            .update(&mut cx, |lsp_store, cx| {
  837                                if lsp_store.as_local().is_some() {
  838                                    match lsp_store
  839                                        .unregister_server_capabilities(server_id, params, cx)
  840                                    {
  841                                        Ok(()) => {}
  842                                        Err(e) => {
  843                                            log::error!(
  844                                                "Failed to unregister server capabilities: {e:#}"
  845                                            );
  846                                        }
  847                                    }
  848                                }
  849                            })
  850                            .ok();
  851                        Ok(())
  852                    }
  853                }
  854            })
  855            .detach();
  856
  857        language_server
  858            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  859                let this = lsp_store.clone();
  860                move |params, cx| {
  861                    let mut cx = cx.clone();
  862                    let this = this.clone();
  863                    async move {
  864                        LocalLspStore::on_lsp_workspace_edit(
  865                            this.clone(),
  866                            params,
  867                            server_id,
  868                            &mut cx,
  869                        )
  870                        .await
  871                    }
  872                }
  873            })
  874            .detach();
  875
  876        language_server
  877            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  878                let lsp_store = lsp_store.clone();
  879                let request_id = Arc::new(AtomicUsize::new(0));
  880                move |(), cx| {
  881                    let lsp_store = lsp_store.clone();
  882                    let request_id = request_id.clone();
  883                    let mut cx = cx.clone();
  884                    async move {
  885                        lsp_store
  886                            .update(&mut cx, |lsp_store, cx| {
  887                                let request_id =
  888                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
  889                                cx.emit(LspStoreEvent::RefreshInlayHints {
  890                                    server_id,
  891                                    request_id,
  892                                });
  893                                lsp_store
  894                                    .downstream_client
  895                                    .as_ref()
  896                                    .map(|(client, project_id)| {
  897                                        client.send(proto::RefreshInlayHints {
  898                                            project_id: *project_id,
  899                                            server_id: server_id.to_proto(),
  900                                            request_id: request_id.map(|id| id as u64),
  901                                        })
  902                                    })
  903                            })?
  904                            .transpose()?;
  905                        Ok(())
  906                    }
  907                }
  908            })
  909            .detach();
  910
  911        language_server
  912            .on_request::<lsp::request::CodeLensRefresh, _, _>({
  913                let this = lsp_store.clone();
  914                move |(), cx| {
  915                    let this = this.clone();
  916                    let mut cx = cx.clone();
  917                    async move {
  918                        this.update(&mut cx, |this, cx| {
  919                            cx.emit(LspStoreEvent::RefreshCodeLens);
  920                            this.downstream_client.as_ref().map(|(client, project_id)| {
  921                                client.send(proto::RefreshCodeLens {
  922                                    project_id: *project_id,
  923                                })
  924                            })
  925                        })?
  926                        .transpose()?;
  927                        Ok(())
  928                    }
  929                }
  930            })
  931            .detach();
  932
  933        language_server
  934            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
  935                let this = lsp_store.clone();
  936                move |(), cx| {
  937                    let this = this.clone();
  938                    let mut cx = cx.clone();
  939                    async move {
  940                        this.update(&mut cx, |lsp_store, _| {
  941                            lsp_store.pull_workspace_diagnostics(server_id);
  942                            lsp_store
  943                                .downstream_client
  944                                .as_ref()
  945                                .map(|(client, project_id)| {
  946                                    client.send(proto::PullWorkspaceDiagnostics {
  947                                        project_id: *project_id,
  948                                        server_id: server_id.to_proto(),
  949                                    })
  950                                })
  951                        })?
  952                        .transpose()?;
  953                        Ok(())
  954                    }
  955                }
  956            })
  957            .detach();
  958
  959        language_server
  960            .on_request::<lsp::request::ShowMessageRequest, _, _>({
  961                let this = lsp_store.clone();
  962                let name = name.to_string();
  963                move |params, cx| {
  964                    let this = this.clone();
  965                    let name = name.to_string();
  966                    let mut cx = cx.clone();
  967                    async move {
  968                        let actions = params.actions.unwrap_or_default();
  969                        let (tx, rx) = smol::channel::bounded(1);
  970                        let request = LanguageServerPromptRequest {
  971                            level: match params.typ {
  972                                lsp::MessageType::ERROR => PromptLevel::Critical,
  973                                lsp::MessageType::WARNING => PromptLevel::Warning,
  974                                _ => PromptLevel::Info,
  975                            },
  976                            message: params.message,
  977                            actions,
  978                            response_channel: tx,
  979                            lsp_name: name.clone(),
  980                        };
  981
  982                        let did_update = this
  983                            .update(&mut cx, |_, cx| {
  984                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
  985                            })
  986                            .is_ok();
  987                        if did_update {
  988                            let response = rx.recv().await.ok();
  989                            Ok(response)
  990                        } else {
  991                            Ok(None)
  992                        }
  993                    }
  994                }
  995            })
  996            .detach();
  997        language_server
  998            .on_notification::<lsp::notification::ShowMessage, _>({
  999                let this = lsp_store.clone();
 1000                let name = name.to_string();
 1001                move |params, cx| {
 1002                    let this = this.clone();
 1003                    let name = name.to_string();
 1004                    let mut cx = cx.clone();
 1005
 1006                    let (tx, _) = smol::channel::bounded(1);
 1007                    let request = LanguageServerPromptRequest {
 1008                        level: match params.typ {
 1009                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1010                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1011                            _ => PromptLevel::Info,
 1012                        },
 1013                        message: params.message,
 1014                        actions: vec![],
 1015                        response_channel: tx,
 1016                        lsp_name: name,
 1017                    };
 1018
 1019                    let _ = this.update(&mut cx, |_, cx| {
 1020                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1021                    });
 1022                }
 1023            })
 1024            .detach();
 1025
 1026        let disk_based_diagnostics_progress_token =
 1027            adapter.disk_based_diagnostics_progress_token.clone();
 1028
 1029        language_server
 1030            .on_notification::<lsp::notification::Progress, _>({
 1031                let this = lsp_store.clone();
 1032                move |params, cx| {
 1033                    if let Some(this) = this.upgrade() {
 1034                        this.update(cx, |this, cx| {
 1035                            this.on_lsp_progress(
 1036                                params,
 1037                                server_id,
 1038                                disk_based_diagnostics_progress_token.clone(),
 1039                                cx,
 1040                            );
 1041                        })
 1042                        .ok();
 1043                    }
 1044                }
 1045            })
 1046            .detach();
 1047
 1048        language_server
 1049            .on_notification::<lsp::notification::LogMessage, _>({
 1050                let this = lsp_store.clone();
 1051                move |params, cx| {
 1052                    if let Some(this) = this.upgrade() {
 1053                        this.update(cx, |_, cx| {
 1054                            cx.emit(LspStoreEvent::LanguageServerLog(
 1055                                server_id,
 1056                                LanguageServerLogType::Log(params.typ),
 1057                                params.message,
 1058                            ));
 1059                        })
 1060                        .ok();
 1061                    }
 1062                }
 1063            })
 1064            .detach();
 1065
 1066        language_server
 1067            .on_notification::<lsp::notification::LogTrace, _>({
 1068                let this = lsp_store.clone();
 1069                move |params, cx| {
 1070                    let mut cx = cx.clone();
 1071                    if let Some(this) = this.upgrade() {
 1072                        this.update(&mut cx, |_, cx| {
 1073                            cx.emit(LspStoreEvent::LanguageServerLog(
 1074                                server_id,
 1075                                LanguageServerLogType::Trace {
 1076                                    verbose_info: params.verbose,
 1077                                },
 1078                                params.message,
 1079                            ));
 1080                        })
 1081                        .ok();
 1082                    }
 1083                }
 1084            })
 1085            .detach();
 1086
 1087        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1088        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1089        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1090        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1091    }
 1092
 1093    fn shutdown_language_servers_on_quit(
 1094        &mut self,
 1095        _: &mut Context<LspStore>,
 1096    ) -> impl Future<Output = ()> + use<> {
 1097        let shutdown_futures = self
 1098            .language_servers
 1099            .drain()
 1100            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1101            .collect::<Vec<_>>();
 1102
 1103        async move {
 1104            join_all(shutdown_futures).await;
 1105        }
 1106    }
 1107
 1108    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1109        match server_state {
 1110            LanguageServerState::Running { server, .. } => {
 1111                if let Some(shutdown) = server.shutdown() {
 1112                    shutdown.await;
 1113                }
 1114            }
 1115            LanguageServerState::Starting { startup, .. } => {
 1116                if let Some(server) = startup.await
 1117                    && let Some(shutdown) = server.shutdown()
 1118                {
 1119                    shutdown.await;
 1120                }
 1121            }
 1122        }
 1123        Ok(())
 1124    }
 1125
 1126    fn language_servers_for_worktree(
 1127        &self,
 1128        worktree_id: WorktreeId,
 1129    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1130        self.language_server_ids
 1131            .iter()
 1132            .filter_map(move |(seed, state)| {
 1133                if seed.worktree_id != worktree_id {
 1134                    return None;
 1135                }
 1136
 1137                if let Some(LanguageServerState::Running { server, .. }) =
 1138                    self.language_servers.get(&state.id)
 1139                {
 1140                    Some(server)
 1141                } else {
 1142                    None
 1143                }
 1144            })
 1145    }
 1146
 1147    fn language_server_ids_for_project_path(
 1148        &self,
 1149        project_path: ProjectPath,
 1150        language: &Language,
 1151        cx: &mut App,
 1152    ) -> Vec<LanguageServerId> {
 1153        let Some(worktree) = self
 1154            .worktree_store
 1155            .read(cx)
 1156            .worktree_for_id(project_path.worktree_id, cx)
 1157        else {
 1158            return Vec::new();
 1159        };
 1160        let delegate: Arc<dyn ManifestDelegate> =
 1161            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1162
 1163        self.lsp_tree
 1164            .get(
 1165                project_path,
 1166                language.name(),
 1167                language.manifest(),
 1168                &delegate,
 1169                cx,
 1170            )
 1171            .collect::<Vec<_>>()
 1172    }
 1173
 1174    fn language_server_ids_for_buffer(
 1175        &self,
 1176        buffer: &Buffer,
 1177        cx: &mut App,
 1178    ) -> Vec<LanguageServerId> {
 1179        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1180            let worktree_id = file.worktree_id(cx);
 1181
 1182            let path: Arc<RelPath> = file
 1183                .path()
 1184                .parent()
 1185                .map(Arc::from)
 1186                .unwrap_or_else(|| file.path().clone());
 1187            let worktree_path = ProjectPath { worktree_id, path };
 1188            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1189        } else {
 1190            Vec::new()
 1191        }
 1192    }
 1193
 1194    fn language_servers_for_buffer<'a>(
 1195        &'a self,
 1196        buffer: &'a Buffer,
 1197        cx: &'a mut App,
 1198    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1199        self.language_server_ids_for_buffer(buffer, cx)
 1200            .into_iter()
 1201            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1202                LanguageServerState::Running {
 1203                    adapter, server, ..
 1204                } => Some((adapter, server)),
 1205                _ => None,
 1206            })
 1207    }
 1208
 1209    async fn execute_code_action_kind_locally(
 1210        lsp_store: WeakEntity<LspStore>,
 1211        mut buffers: Vec<Entity<Buffer>>,
 1212        kind: CodeActionKind,
 1213        push_to_history: bool,
 1214        cx: &mut AsyncApp,
 1215    ) -> anyhow::Result<ProjectTransaction> {
 1216        // Do not allow multiple concurrent code actions requests for the
 1217        // same buffer.
 1218        lsp_store.update(cx, |this, cx| {
 1219            let this = this.as_local_mut().unwrap();
 1220            buffers.retain(|buffer| {
 1221                this.buffers_being_formatted
 1222                    .insert(buffer.read(cx).remote_id())
 1223            });
 1224        })?;
 1225        let _cleanup = defer({
 1226            let this = lsp_store.clone();
 1227            let mut cx = cx.clone();
 1228            let buffers = &buffers;
 1229            move || {
 1230                this.update(&mut cx, |this, cx| {
 1231                    let this = this.as_local_mut().unwrap();
 1232                    for buffer in buffers {
 1233                        this.buffers_being_formatted
 1234                            .remove(&buffer.read(cx).remote_id());
 1235                    }
 1236                })
 1237                .ok();
 1238            }
 1239        });
 1240        let mut project_transaction = ProjectTransaction::default();
 1241
 1242        for buffer in &buffers {
 1243            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1244                buffer.update(cx, |buffer, cx| {
 1245                    lsp_store
 1246                        .as_local()
 1247                        .unwrap()
 1248                        .language_servers_for_buffer(buffer, cx)
 1249                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1250                        .collect::<Vec<_>>()
 1251                })
 1252            })?;
 1253            for (_, language_server) in adapters_and_servers.iter() {
 1254                let actions = Self::get_server_code_actions_from_action_kinds(
 1255                    &lsp_store,
 1256                    language_server.server_id(),
 1257                    vec![kind.clone()],
 1258                    buffer,
 1259                    cx,
 1260                )
 1261                .await?;
 1262                Self::execute_code_actions_on_server(
 1263                    &lsp_store,
 1264                    language_server,
 1265                    actions,
 1266                    push_to_history,
 1267                    &mut project_transaction,
 1268                    cx,
 1269                )
 1270                .await?;
 1271            }
 1272        }
 1273        Ok(project_transaction)
 1274    }
 1275
 1276    async fn format_locally(
 1277        lsp_store: WeakEntity<LspStore>,
 1278        mut buffers: Vec<FormattableBuffer>,
 1279        push_to_history: bool,
 1280        trigger: FormatTrigger,
 1281        logger: zlog::Logger,
 1282        cx: &mut AsyncApp,
 1283    ) -> anyhow::Result<ProjectTransaction> {
 1284        // Do not allow multiple concurrent formatting requests for the
 1285        // same buffer.
 1286        lsp_store.update(cx, |this, cx| {
 1287            let this = this.as_local_mut().unwrap();
 1288            buffers.retain(|buffer| {
 1289                this.buffers_being_formatted
 1290                    .insert(buffer.handle.read(cx).remote_id())
 1291            });
 1292        })?;
 1293
 1294        let _cleanup = defer({
 1295            let this = lsp_store.clone();
 1296            let mut cx = cx.clone();
 1297            let buffers = &buffers;
 1298            move || {
 1299                this.update(&mut cx, |this, cx| {
 1300                    let this = this.as_local_mut().unwrap();
 1301                    for buffer in buffers {
 1302                        this.buffers_being_formatted
 1303                            .remove(&buffer.handle.read(cx).remote_id());
 1304                    }
 1305                })
 1306                .ok();
 1307            }
 1308        });
 1309
 1310        let mut project_transaction = ProjectTransaction::default();
 1311
 1312        for buffer in &buffers {
 1313            zlog::debug!(
 1314                logger =>
 1315                "formatting buffer '{:?}'",
 1316                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1317            );
 1318            // Create an empty transaction to hold all of the formatting edits.
 1319            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1320                // ensure no transactions created while formatting are
 1321                // grouped with the previous transaction in the history
 1322                // based on the transaction group interval
 1323                buffer.finalize_last_transaction();
 1324                buffer
 1325                    .start_transaction()
 1326                    .context("transaction already open")?;
 1327                buffer.end_transaction(cx);
 1328                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1329                buffer.finalize_last_transaction();
 1330                anyhow::Ok(transaction_id)
 1331            })??;
 1332
 1333            let result = Self::format_buffer_locally(
 1334                lsp_store.clone(),
 1335                buffer,
 1336                formatting_transaction_id,
 1337                trigger,
 1338                logger,
 1339                cx,
 1340            )
 1341            .await;
 1342
 1343            buffer.handle.update(cx, |buffer, cx| {
 1344                let Some(formatting_transaction) =
 1345                    buffer.get_transaction(formatting_transaction_id).cloned()
 1346                else {
 1347                    zlog::warn!(logger => "no formatting transaction");
 1348                    return;
 1349                };
 1350                if formatting_transaction.edit_ids.is_empty() {
 1351                    zlog::debug!(logger => "no changes made while formatting");
 1352                    buffer.forget_transaction(formatting_transaction_id);
 1353                    return;
 1354                }
 1355                if !push_to_history {
 1356                    zlog::trace!(logger => "forgetting format transaction");
 1357                    buffer.forget_transaction(formatting_transaction.id);
 1358                }
 1359                project_transaction
 1360                    .0
 1361                    .insert(cx.entity(), formatting_transaction);
 1362            })?;
 1363
 1364            result?;
 1365        }
 1366
 1367        Ok(project_transaction)
 1368    }
 1369
 1370    async fn format_buffer_locally(
 1371        lsp_store: WeakEntity<LspStore>,
 1372        buffer: &FormattableBuffer,
 1373        formatting_transaction_id: clock::Lamport,
 1374        trigger: FormatTrigger,
 1375        logger: zlog::Logger,
 1376        cx: &mut AsyncApp,
 1377    ) -> Result<()> {
 1378        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1379            buffer.handle.update(cx, |buffer, cx| {
 1380                let adapters_and_servers = lsp_store
 1381                    .as_local()
 1382                    .unwrap()
 1383                    .language_servers_for_buffer(buffer, cx)
 1384                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1385                    .collect::<Vec<_>>();
 1386                let settings =
 1387                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1388                        .into_owned();
 1389                (adapters_and_servers, settings)
 1390            })
 1391        })?;
 1392
 1393        /// Apply edits to the buffer that will become part of the formatting transaction.
 1394        /// Fails if the buffer has been edited since the start of that transaction.
 1395        fn extend_formatting_transaction(
 1396            buffer: &FormattableBuffer,
 1397            formatting_transaction_id: text::TransactionId,
 1398            cx: &mut AsyncApp,
 1399            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1400        ) -> anyhow::Result<()> {
 1401            buffer.handle.update(cx, |buffer, cx| {
 1402                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1403                if last_transaction_id != Some(formatting_transaction_id) {
 1404                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1405                }
 1406                buffer.start_transaction();
 1407                operation(buffer, cx);
 1408                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1409                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1410                }
 1411                Ok(())
 1412            })?
 1413        }
 1414
 1415        // handle whitespace formatting
 1416        if settings.remove_trailing_whitespace_on_save {
 1417            zlog::trace!(logger => "removing trailing whitespace");
 1418            let diff = buffer
 1419                .handle
 1420                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))?
 1421                .await;
 1422            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1423                buffer.apply_diff(diff, cx);
 1424            })?;
 1425        }
 1426
 1427        if settings.ensure_final_newline_on_save {
 1428            zlog::trace!(logger => "ensuring final newline");
 1429            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1430                buffer.ensure_final_newline(cx);
 1431            })?;
 1432        }
 1433
 1434        // Formatter for `code_actions_on_format` that runs before
 1435        // the rest of the formatters
 1436        let mut code_actions_on_format_formatters = None;
 1437        let should_run_code_actions_on_format = !matches!(
 1438            (trigger, &settings.format_on_save),
 1439            (FormatTrigger::Save, &FormatOnSave::Off)
 1440        );
 1441        if should_run_code_actions_on_format {
 1442            let have_code_actions_to_run_on_format = settings
 1443                .code_actions_on_format
 1444                .values()
 1445                .any(|enabled| *enabled);
 1446            if have_code_actions_to_run_on_format {
 1447                zlog::trace!(logger => "going to run code actions on format");
 1448                code_actions_on_format_formatters = Some(
 1449                    settings
 1450                        .code_actions_on_format
 1451                        .iter()
 1452                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1453                        .cloned()
 1454                        .map(Formatter::CodeAction)
 1455                        .collect::<Vec<_>>(),
 1456                );
 1457            }
 1458        }
 1459
 1460        let formatters = match (trigger, &settings.format_on_save) {
 1461            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1462            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1463                settings.formatter.as_ref()
 1464            }
 1465        };
 1466
 1467        let formatters = code_actions_on_format_formatters
 1468            .iter()
 1469            .flatten()
 1470            .chain(formatters);
 1471
 1472        for formatter in formatters {
 1473            let formatter = if formatter == &Formatter::Auto {
 1474                if settings.prettier.allowed {
 1475                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1476                    &Formatter::Prettier
 1477                } else {
 1478                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1479                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1480                }
 1481            } else {
 1482                formatter
 1483            };
 1484            match formatter {
 1485                Formatter::Auto => unreachable!("Auto resolved above"),
 1486                Formatter::Prettier => {
 1487                    let logger = zlog::scoped!(logger => "prettier");
 1488                    zlog::trace!(logger => "formatting");
 1489                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1490
 1491                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1492                        lsp_store.prettier_store().unwrap().downgrade()
 1493                    })?;
 1494                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1495                        .await
 1496                        .transpose()?;
 1497                    let Some(diff) = diff else {
 1498                        zlog::trace!(logger => "No changes");
 1499                        continue;
 1500                    };
 1501
 1502                    extend_formatting_transaction(
 1503                        buffer,
 1504                        formatting_transaction_id,
 1505                        cx,
 1506                        |buffer, cx| {
 1507                            buffer.apply_diff(diff, cx);
 1508                        },
 1509                    )?;
 1510                }
 1511                Formatter::External { command, arguments } => {
 1512                    let logger = zlog::scoped!(logger => "command");
 1513                    zlog::trace!(logger => "formatting");
 1514                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1515
 1516                    let diff = Self::format_via_external_command(
 1517                        buffer,
 1518                        command.as_ref(),
 1519                        arguments.as_deref(),
 1520                        cx,
 1521                    )
 1522                    .await
 1523                    .with_context(|| {
 1524                        format!("Failed to format buffer via external command: {}", command)
 1525                    })?;
 1526                    let Some(diff) = diff else {
 1527                        zlog::trace!(logger => "No changes");
 1528                        continue;
 1529                    };
 1530
 1531                    extend_formatting_transaction(
 1532                        buffer,
 1533                        formatting_transaction_id,
 1534                        cx,
 1535                        |buffer, cx| {
 1536                            buffer.apply_diff(diff, cx);
 1537                        },
 1538                    )?;
 1539                }
 1540                Formatter::LanguageServer(specifier) => {
 1541                    let logger = zlog::scoped!(logger => "language-server");
 1542                    zlog::trace!(logger => "formatting");
 1543                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1544
 1545                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1546                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1547                        continue;
 1548                    };
 1549
 1550                    let language_server = match specifier {
 1551                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1552                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1553                                if adapter.name.0.as_ref() == name {
 1554                                    Some(server.clone())
 1555                                } else {
 1556                                    None
 1557                                }
 1558                            })
 1559                        }
 1560                        settings::LanguageServerFormatterSpecifier::Current => {
 1561                            adapters_and_servers.first().map(|e| e.1.clone())
 1562                        }
 1563                    };
 1564
 1565                    let Some(language_server) = language_server else {
 1566                        log::debug!(
 1567                            "No language server found to format buffer '{:?}'. Skipping",
 1568                            buffer_path_abs.as_path().to_string_lossy()
 1569                        );
 1570                        continue;
 1571                    };
 1572
 1573                    zlog::trace!(
 1574                        logger =>
 1575                        "Formatting buffer '{:?}' using language server '{:?}'",
 1576                        buffer_path_abs.as_path().to_string_lossy(),
 1577                        language_server.name()
 1578                    );
 1579
 1580                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1581                        zlog::trace!(logger => "formatting ranges");
 1582                        Self::format_ranges_via_lsp(
 1583                            &lsp_store,
 1584                            &buffer.handle,
 1585                            ranges,
 1586                            buffer_path_abs,
 1587                            &language_server,
 1588                            &settings,
 1589                            cx,
 1590                        )
 1591                        .await
 1592                        .context("Failed to format ranges via language server")?
 1593                    } else {
 1594                        zlog::trace!(logger => "formatting full");
 1595                        Self::format_via_lsp(
 1596                            &lsp_store,
 1597                            &buffer.handle,
 1598                            buffer_path_abs,
 1599                            &language_server,
 1600                            &settings,
 1601                            cx,
 1602                        )
 1603                        .await
 1604                        .context("failed to format via language server")?
 1605                    };
 1606
 1607                    if edits.is_empty() {
 1608                        zlog::trace!(logger => "No changes");
 1609                        continue;
 1610                    }
 1611                    extend_formatting_transaction(
 1612                        buffer,
 1613                        formatting_transaction_id,
 1614                        cx,
 1615                        |buffer, cx| {
 1616                            buffer.edit(edits, None, cx);
 1617                        },
 1618                    )?;
 1619                }
 1620                Formatter::CodeAction(code_action_name) => {
 1621                    let logger = zlog::scoped!(logger => "code-actions");
 1622                    zlog::trace!(logger => "formatting");
 1623                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1624
 1625                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1626                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1627                        continue;
 1628                    };
 1629
 1630                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1631                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1632
 1633                    let mut actions_and_servers = Vec::new();
 1634
 1635                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1636                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1637                            &lsp_store,
 1638                            language_server.server_id(),
 1639                            vec![code_action_kind.clone()],
 1640                            &buffer.handle,
 1641                            cx,
 1642                        )
 1643                        .await
 1644                        .with_context(|| {
 1645                            format!(
 1646                                "Failed to resolve code action {:?} with language server {}",
 1647                                code_action_kind,
 1648                                language_server.name()
 1649                            )
 1650                        });
 1651                        let Ok(actions) = actions_result else {
 1652                            // note: it may be better to set result to the error and break formatters here
 1653                            // but for now we try to execute the actions that we can resolve and skip the rest
 1654                            zlog::error!(
 1655                                logger =>
 1656                                "Failed to resolve code action {:?} with language server {}",
 1657                                code_action_kind,
 1658                                language_server.name()
 1659                            );
 1660                            continue;
 1661                        };
 1662                        for action in actions {
 1663                            actions_and_servers.push((action, index));
 1664                        }
 1665                    }
 1666
 1667                    if actions_and_servers.is_empty() {
 1668                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1669                        continue;
 1670                    }
 1671
 1672                    'actions: for (mut action, server_index) in actions_and_servers {
 1673                        let server = &adapters_and_servers[server_index].1;
 1674
 1675                        let describe_code_action = |action: &CodeAction| {
 1676                            format!(
 1677                                "code action '{}' with title \"{}\" on server {}",
 1678                                action
 1679                                    .lsp_action
 1680                                    .action_kind()
 1681                                    .unwrap_or("unknown".into())
 1682                                    .as_str(),
 1683                                action.lsp_action.title(),
 1684                                server.name(),
 1685                            )
 1686                        };
 1687
 1688                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1689
 1690                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1691                            zlog::error!(
 1692                                logger =>
 1693                                "Failed to resolve {}. Error: {}",
 1694                                describe_code_action(&action),
 1695                                err
 1696                            );
 1697                            continue;
 1698                        }
 1699
 1700                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1701                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1702                            // but filters out and logs warnings for code actions that require unreasonably
 1703                            // difficult handling on our part, such as:
 1704                            // - applying edits that call commands
 1705                            //   which can result in arbitrary workspace edits being sent from the server that
 1706                            //   have no way of being tied back to the command that initiated them (i.e. we
 1707                            //   can't know which edits are part of the format request, or if the server is done sending
 1708                            //   actions in response to the command)
 1709                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1710                            //   as we then would need to handle such changes correctly in the local history as well
 1711                            //   as the remote history through the ProjectTransaction
 1712                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1713                            // Supporting these actions is not impossible, but not supported as of yet.
 1714                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1715                                zlog::trace!(
 1716                                    logger =>
 1717                                    "No changes for code action. Skipping {}",
 1718                                    describe_code_action(&action),
 1719                                );
 1720                                continue;
 1721                            }
 1722
 1723                            let mut operations = Vec::new();
 1724                            if let Some(document_changes) = edit.document_changes {
 1725                                match document_changes {
 1726                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1727                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1728                                    ),
 1729                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1730                                }
 1731                            } else if let Some(changes) = edit.changes {
 1732                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1733                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1734                                        text_document:
 1735                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1736                                                uri,
 1737                                                version: None,
 1738                                            },
 1739                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1740                                    })
 1741                                }));
 1742                            }
 1743
 1744                            let mut edits = Vec::with_capacity(operations.len());
 1745
 1746                            if operations.is_empty() {
 1747                                zlog::trace!(
 1748                                    logger =>
 1749                                    "No changes for code action. Skipping {}",
 1750                                    describe_code_action(&action),
 1751                                );
 1752                                continue;
 1753                            }
 1754                            for operation in operations {
 1755                                let op = match operation {
 1756                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1757                                    lsp::DocumentChangeOperation::Op(_) => {
 1758                                        zlog::warn!(
 1759                                            logger =>
 1760                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1761                                            describe_code_action(&action),
 1762                                        );
 1763                                        continue 'actions;
 1764                                    }
 1765                                };
 1766                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1767                                    zlog::warn!(
 1768                                        logger =>
 1769                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1770                                        &op.text_document.uri,
 1771                                        describe_code_action(&action),
 1772                                    );
 1773                                    continue 'actions;
 1774                                };
 1775                                if &file_path != buffer_path_abs {
 1776                                    zlog::warn!(
 1777                                        logger =>
 1778                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1779                                        file_path,
 1780                                        buffer_path_abs,
 1781                                        describe_code_action(&action),
 1782                                    );
 1783                                    continue 'actions;
 1784                                }
 1785
 1786                                let mut lsp_edits = Vec::new();
 1787                                for edit in op.edits {
 1788                                    match edit {
 1789                                        Edit::Plain(edit) => {
 1790                                            if !lsp_edits.contains(&edit) {
 1791                                                lsp_edits.push(edit);
 1792                                            }
 1793                                        }
 1794                                        Edit::Annotated(edit) => {
 1795                                            if !lsp_edits.contains(&edit.text_edit) {
 1796                                                lsp_edits.push(edit.text_edit);
 1797                                            }
 1798                                        }
 1799                                        Edit::Snippet(_) => {
 1800                                            zlog::warn!(
 1801                                                logger =>
 1802                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1803                                                describe_code_action(&action),
 1804                                            );
 1805                                            continue 'actions;
 1806                                        }
 1807                                    }
 1808                                }
 1809                                let edits_result = lsp_store
 1810                                    .update(cx, |lsp_store, cx| {
 1811                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1812                                            &buffer.handle,
 1813                                            lsp_edits,
 1814                                            server.server_id(),
 1815                                            op.text_document.version,
 1816                                            cx,
 1817                                        )
 1818                                    })?
 1819                                    .await;
 1820                                let Ok(resolved_edits) = edits_result else {
 1821                                    zlog::warn!(
 1822                                        logger =>
 1823                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1824                                        buffer_path_abs.as_path(),
 1825                                        describe_code_action(&action),
 1826                                    );
 1827                                    continue 'actions;
 1828                                };
 1829                                edits.extend(resolved_edits);
 1830                            }
 1831
 1832                            if edits.is_empty() {
 1833                                zlog::warn!(logger => "No edits resolved from LSP");
 1834                                continue;
 1835                            }
 1836
 1837                            extend_formatting_transaction(
 1838                                buffer,
 1839                                formatting_transaction_id,
 1840                                cx,
 1841                                |buffer, cx| {
 1842                                    zlog::info!(
 1843                                        "Applying edits {edits:?}. Content: {:?}",
 1844                                        buffer.text()
 1845                                    );
 1846                                    buffer.edit(edits, None, cx);
 1847                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 1848                                },
 1849                            )?;
 1850                        }
 1851
 1852                        if let Some(command) = action.lsp_action.command() {
 1853                            zlog::warn!(
 1854                                logger =>
 1855                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1856                                &command.command,
 1857                            );
 1858
 1859                            // bail early if command is invalid
 1860                            let server_capabilities = server.capabilities();
 1861                            let available_commands = server_capabilities
 1862                                .execute_command_provider
 1863                                .as_ref()
 1864                                .map(|options| options.commands.as_slice())
 1865                                .unwrap_or_default();
 1866                            if !available_commands.contains(&command.command) {
 1867                                zlog::warn!(
 1868                                    logger =>
 1869                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1870                                    command.command,
 1871                                    server.name(),
 1872                                );
 1873                                continue;
 1874                            }
 1875
 1876                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 1877                            extend_formatting_transaction(
 1878                                buffer,
 1879                                formatting_transaction_id,
 1880                                cx,
 1881                                |_, _| {},
 1882                            )?;
 1883                            zlog::info!(logger => "Executing command {}", &command.command);
 1884
 1885                            lsp_store.update(cx, |this, _| {
 1886                                this.as_local_mut()
 1887                                    .unwrap()
 1888                                    .last_workspace_edits_by_language_server
 1889                                    .remove(&server.server_id());
 1890                            })?;
 1891
 1892                            let execute_command_result = server
 1893                                .request::<lsp::request::ExecuteCommand>(
 1894                                    lsp::ExecuteCommandParams {
 1895                                        command: command.command.clone(),
 1896                                        arguments: command.arguments.clone().unwrap_or_default(),
 1897                                        ..Default::default()
 1898                                    },
 1899                                )
 1900                                .await
 1901                                .into_response();
 1902
 1903                            if execute_command_result.is_err() {
 1904                                zlog::error!(
 1905                                    logger =>
 1906                                    "Failed to execute command '{}' as part of {}",
 1907                                    &command.command,
 1908                                    describe_code_action(&action),
 1909                                );
 1910                                continue 'actions;
 1911                            }
 1912
 1913                            let mut project_transaction_command =
 1914                                lsp_store.update(cx, |this, _| {
 1915                                    this.as_local_mut()
 1916                                        .unwrap()
 1917                                        .last_workspace_edits_by_language_server
 1918                                        .remove(&server.server_id())
 1919                                        .unwrap_or_default()
 1920                                })?;
 1921
 1922                            if let Some(transaction) =
 1923                                project_transaction_command.0.remove(&buffer.handle)
 1924                            {
 1925                                zlog::trace!(
 1926                                    logger =>
 1927                                    "Successfully captured {} edits that resulted from command {}",
 1928                                    transaction.edit_ids.len(),
 1929                                    &command.command,
 1930                                );
 1931                                let transaction_id_project_transaction = transaction.id;
 1932                                buffer.handle.update(cx, |buffer, _| {
 1933                                    // it may have been removed from history if push_to_history was
 1934                                    // false in deserialize_workspace_edit. If so push it so we
 1935                                    // can merge it with the format transaction
 1936                                    // and pop the combined transaction off the history stack
 1937                                    // later if push_to_history is false
 1938                                    if buffer.get_transaction(transaction.id).is_none() {
 1939                                        buffer.push_transaction(transaction, Instant::now());
 1940                                    }
 1941                                    buffer.merge_transactions(
 1942                                        transaction_id_project_transaction,
 1943                                        formatting_transaction_id,
 1944                                    );
 1945                                })?;
 1946                            }
 1947
 1948                            if !project_transaction_command.0.is_empty() {
 1949                                let mut extra_buffers = String::new();
 1950                                for buffer in project_transaction_command.0.keys() {
 1951                                    buffer
 1952                                        .read_with(cx, |b, cx| {
 1953                                            if let Some(path) = b.project_path(cx) {
 1954                                                if !extra_buffers.is_empty() {
 1955                                                    extra_buffers.push_str(", ");
 1956                                                }
 1957                                                extra_buffers.push_str(path.path.as_unix_str());
 1958                                            }
 1959                                        })
 1960                                        .ok();
 1961                                }
 1962                                zlog::warn!(
 1963                                    logger =>
 1964                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 1965                                    &command.command,
 1966                                    extra_buffers,
 1967                                );
 1968                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 1969                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 1970                                // add it so it's included, and merge it into the format transaction when its created later
 1971                            }
 1972                        }
 1973                    }
 1974                }
 1975            }
 1976        }
 1977
 1978        Ok(())
 1979    }
 1980
 1981    pub async fn format_ranges_via_lsp(
 1982        this: &WeakEntity<LspStore>,
 1983        buffer_handle: &Entity<Buffer>,
 1984        ranges: &[Range<Anchor>],
 1985        abs_path: &Path,
 1986        language_server: &Arc<LanguageServer>,
 1987        settings: &LanguageSettings,
 1988        cx: &mut AsyncApp,
 1989    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 1990        let capabilities = &language_server.capabilities();
 1991        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 1992        if range_formatting_provider == Some(&OneOf::Left(false)) {
 1993            anyhow::bail!(
 1994                "{} language server does not support range formatting",
 1995                language_server.name()
 1996            );
 1997        }
 1998
 1999        let uri = file_path_to_lsp_url(abs_path)?;
 2000        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2001
 2002        let lsp_edits = {
 2003            let mut lsp_ranges = Vec::new();
 2004            this.update(cx, |_this, cx| {
 2005                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2006                // not have been sent to the language server. This seems like a fairly systemic
 2007                // issue, though, the resolution probably is not specific to formatting.
 2008                //
 2009                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2010                // LSP.
 2011                let snapshot = buffer_handle.read(cx).snapshot();
 2012                for range in ranges {
 2013                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2014                }
 2015                anyhow::Ok(())
 2016            })??;
 2017
 2018            let mut edits = None;
 2019            for range in lsp_ranges {
 2020                if let Some(mut edit) = language_server
 2021                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2022                        text_document: text_document.clone(),
 2023                        range,
 2024                        options: lsp_command::lsp_formatting_options(settings),
 2025                        work_done_progress_params: Default::default(),
 2026                    })
 2027                    .await
 2028                    .into_response()?
 2029                {
 2030                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2031                }
 2032            }
 2033            edits
 2034        };
 2035
 2036        if let Some(lsp_edits) = lsp_edits {
 2037            this.update(cx, |this, cx| {
 2038                this.as_local_mut().unwrap().edits_from_lsp(
 2039                    buffer_handle,
 2040                    lsp_edits,
 2041                    language_server.server_id(),
 2042                    None,
 2043                    cx,
 2044                )
 2045            })?
 2046            .await
 2047        } else {
 2048            Ok(Vec::with_capacity(0))
 2049        }
 2050    }
 2051
 2052    async fn format_via_lsp(
 2053        this: &WeakEntity<LspStore>,
 2054        buffer: &Entity<Buffer>,
 2055        abs_path: &Path,
 2056        language_server: &Arc<LanguageServer>,
 2057        settings: &LanguageSettings,
 2058        cx: &mut AsyncApp,
 2059    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2060        let logger = zlog::scoped!("lsp_format");
 2061        zlog::debug!(logger => "Formatting via LSP");
 2062
 2063        let uri = file_path_to_lsp_url(abs_path)?;
 2064        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2065        let capabilities = &language_server.capabilities();
 2066
 2067        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2068        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2069
 2070        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2071            let _timer = zlog::time!(logger => "format-full");
 2072            language_server
 2073                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 2074                    text_document,
 2075                    options: lsp_command::lsp_formatting_options(settings),
 2076                    work_done_progress_params: Default::default(),
 2077                })
 2078                .await
 2079                .into_response()?
 2080        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2081            let _timer = zlog::time!(logger => "format-range");
 2082            let buffer_start = lsp::Position::new(0, 0);
 2083            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 2084            language_server
 2085                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2086                    text_document: text_document.clone(),
 2087                    range: lsp::Range::new(buffer_start, buffer_end),
 2088                    options: lsp_command::lsp_formatting_options(settings),
 2089                    work_done_progress_params: Default::default(),
 2090                })
 2091                .await
 2092                .into_response()?
 2093        } else {
 2094            None
 2095        };
 2096
 2097        if let Some(lsp_edits) = lsp_edits {
 2098            this.update(cx, |this, cx| {
 2099                this.as_local_mut().unwrap().edits_from_lsp(
 2100                    buffer,
 2101                    lsp_edits,
 2102                    language_server.server_id(),
 2103                    None,
 2104                    cx,
 2105                )
 2106            })?
 2107            .await
 2108        } else {
 2109            Ok(Vec::with_capacity(0))
 2110        }
 2111    }
 2112
 2113    async fn format_via_external_command(
 2114        buffer: &FormattableBuffer,
 2115        command: &str,
 2116        arguments: Option<&[String]>,
 2117        cx: &mut AsyncApp,
 2118    ) -> Result<Option<Diff>> {
 2119        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2120            let file = File::from_dyn(buffer.file())?;
 2121            let worktree = file.worktree.read(cx);
 2122            let mut worktree_path = worktree.abs_path().to_path_buf();
 2123            if worktree.root_entry()?.is_file() {
 2124                worktree_path.pop();
 2125            }
 2126            Some(worktree_path)
 2127        })?;
 2128
 2129        let mut child = util::command::new_smol_command(command);
 2130
 2131        if let Some(buffer_env) = buffer.env.as_ref() {
 2132            child.envs(buffer_env);
 2133        }
 2134
 2135        if let Some(working_dir_path) = working_dir_path {
 2136            child.current_dir(working_dir_path);
 2137        }
 2138
 2139        if let Some(arguments) = arguments {
 2140            child.args(arguments.iter().map(|arg| {
 2141                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2142                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2143                } else {
 2144                    arg.replace("{buffer_path}", "Untitled")
 2145                }
 2146            }));
 2147        }
 2148
 2149        let mut child = child
 2150            .stdin(smol::process::Stdio::piped())
 2151            .stdout(smol::process::Stdio::piped())
 2152            .stderr(smol::process::Stdio::piped())
 2153            .spawn()?;
 2154
 2155        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2156        let text = buffer
 2157            .handle
 2158            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2159        for chunk in text.chunks() {
 2160            stdin.write_all(chunk.as_bytes()).await?;
 2161        }
 2162        stdin.flush().await?;
 2163
 2164        let output = child.output().await?;
 2165        anyhow::ensure!(
 2166            output.status.success(),
 2167            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2168            output.status.code(),
 2169            String::from_utf8_lossy(&output.stdout),
 2170            String::from_utf8_lossy(&output.stderr),
 2171        );
 2172
 2173        let stdout = String::from_utf8(output.stdout)?;
 2174        Ok(Some(
 2175            buffer
 2176                .handle
 2177                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2178                .await,
 2179        ))
 2180    }
 2181
 2182    async fn try_resolve_code_action(
 2183        lang_server: &LanguageServer,
 2184        action: &mut CodeAction,
 2185    ) -> anyhow::Result<()> {
 2186        match &mut action.lsp_action {
 2187            LspAction::Action(lsp_action) => {
 2188                if !action.resolved
 2189                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2190                    && lsp_action.data.is_some()
 2191                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2192                {
 2193                    *lsp_action = Box::new(
 2194                        lang_server
 2195                            .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2196                            .await
 2197                            .into_response()?,
 2198                    );
 2199                }
 2200            }
 2201            LspAction::CodeLens(lens) => {
 2202                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2203                    *lens = lang_server
 2204                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2205                        .await
 2206                        .into_response()?;
 2207                }
 2208            }
 2209            LspAction::Command(_) => {}
 2210        }
 2211
 2212        action.resolved = true;
 2213        anyhow::Ok(())
 2214    }
 2215
 2216    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2217        let buffer = buffer_handle.read(cx);
 2218
 2219        let file = buffer.file().cloned();
 2220
 2221        let Some(file) = File::from_dyn(file.as_ref()) else {
 2222            return;
 2223        };
 2224        if !file.is_local() {
 2225            return;
 2226        }
 2227        let path = ProjectPath::from_file(file, cx);
 2228        let worktree_id = file.worktree_id(cx);
 2229        let language = buffer.language().cloned();
 2230
 2231        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2232            for (server_id, diagnostics) in
 2233                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2234            {
 2235                self.update_buffer_diagnostics(
 2236                    buffer_handle,
 2237                    server_id,
 2238                    None,
 2239                    None,
 2240                    diagnostics,
 2241                    Vec::new(),
 2242                    cx,
 2243                )
 2244                .log_err();
 2245            }
 2246        }
 2247        let Some(language) = language else {
 2248            return;
 2249        };
 2250        let Some(snapshot) = self
 2251            .worktree_store
 2252            .read(cx)
 2253            .worktree_for_id(worktree_id, cx)
 2254            .map(|worktree| worktree.read(cx).snapshot())
 2255        else {
 2256            return;
 2257        };
 2258        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2259
 2260        for server_id in
 2261            self.lsp_tree
 2262                .get(path, language.name(), language.manifest(), &delegate, cx)
 2263        {
 2264            let server = self
 2265                .language_servers
 2266                .get(&server_id)
 2267                .and_then(|server_state| {
 2268                    if let LanguageServerState::Running { server, .. } = server_state {
 2269                        Some(server.clone())
 2270                    } else {
 2271                        None
 2272                    }
 2273                });
 2274            let server = match server {
 2275                Some(server) => server,
 2276                None => continue,
 2277            };
 2278
 2279            buffer_handle.update(cx, |buffer, cx| {
 2280                buffer.set_completion_triggers(
 2281                    server.server_id(),
 2282                    server
 2283                        .capabilities()
 2284                        .completion_provider
 2285                        .as_ref()
 2286                        .and_then(|provider| {
 2287                            provider
 2288                                .trigger_characters
 2289                                .as_ref()
 2290                                .map(|characters| characters.iter().cloned().collect())
 2291                        })
 2292                        .unwrap_or_default(),
 2293                    cx,
 2294                );
 2295            });
 2296        }
 2297    }
 2298
 2299    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2300        buffer.update(cx, |buffer, cx| {
 2301            let Some(language) = buffer.language() else {
 2302                return;
 2303            };
 2304            let path = ProjectPath {
 2305                worktree_id: old_file.worktree_id(cx),
 2306                path: old_file.path.clone(),
 2307            };
 2308            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2309                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2310                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2311            }
 2312        });
 2313    }
 2314
 2315    fn update_buffer_diagnostics(
 2316        &mut self,
 2317        buffer: &Entity<Buffer>,
 2318        server_id: LanguageServerId,
 2319        result_id: Option<String>,
 2320        version: Option<i32>,
 2321        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2322        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2323        cx: &mut Context<LspStore>,
 2324    ) -> Result<()> {
 2325        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2326            Ordering::Equal
 2327                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2328                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2329                .then_with(|| a.severity.cmp(&b.severity))
 2330                .then_with(|| a.message.cmp(&b.message))
 2331        }
 2332
 2333        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2334        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2335        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2336
 2337        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2338            Ordering::Equal
 2339                .then_with(|| a.range.start.cmp(&b.range.start))
 2340                .then_with(|| b.range.end.cmp(&a.range.end))
 2341                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2342        });
 2343
 2344        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2345
 2346        let edits_since_save = std::cell::LazyCell::new(|| {
 2347            let saved_version = buffer.read(cx).saved_version();
 2348            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2349        });
 2350
 2351        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2352
 2353        for (new_diagnostic, entry) in diagnostics {
 2354            let start;
 2355            let end;
 2356            if new_diagnostic && entry.diagnostic.is_disk_based {
 2357                // Some diagnostics are based on files on disk instead of buffers'
 2358                // current contents. Adjust these diagnostics' ranges to reflect
 2359                // any unsaved edits.
 2360                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2361                // and were properly adjusted on reuse.
 2362                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2363                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2364            } else {
 2365                start = entry.range.start;
 2366                end = entry.range.end;
 2367            }
 2368
 2369            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2370                ..snapshot.clip_point_utf16(end, Bias::Right);
 2371
 2372            // Expand empty ranges by one codepoint
 2373            if range.start == range.end {
 2374                // This will be go to the next boundary when being clipped
 2375                range.end.column += 1;
 2376                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2377                if range.start == range.end && range.end.column > 0 {
 2378                    range.start.column -= 1;
 2379                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2380                }
 2381            }
 2382
 2383            sanitized_diagnostics.push(DiagnosticEntry {
 2384                range,
 2385                diagnostic: entry.diagnostic,
 2386            });
 2387        }
 2388        drop(edits_since_save);
 2389
 2390        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2391        buffer.update(cx, |buffer, cx| {
 2392            if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2393                self.buffer_pull_diagnostics_result_ids
 2394                    .entry(server_id)
 2395                    .or_default()
 2396                    .insert(abs_path, result_id);
 2397            }
 2398
 2399            buffer.update_diagnostics(server_id, set, cx)
 2400        });
 2401
 2402        Ok(())
 2403    }
 2404
 2405    fn register_language_server_for_invisible_worktree(
 2406        &mut self,
 2407        worktree: &Entity<Worktree>,
 2408        language_server_id: LanguageServerId,
 2409        cx: &mut App,
 2410    ) {
 2411        let worktree = worktree.read(cx);
 2412        let worktree_id = worktree.id();
 2413        debug_assert!(!worktree.is_visible());
 2414        let Some(mut origin_seed) = self
 2415            .language_server_ids
 2416            .iter()
 2417            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2418        else {
 2419            return;
 2420        };
 2421        origin_seed.worktree_id = worktree_id;
 2422        self.language_server_ids
 2423            .entry(origin_seed)
 2424            .or_insert_with(|| UnifiedLanguageServer {
 2425                id: language_server_id,
 2426                project_roots: Default::default(),
 2427            });
 2428    }
 2429
 2430    fn register_buffer_with_language_servers(
 2431        &mut self,
 2432        buffer_handle: &Entity<Buffer>,
 2433        only_register_servers: HashSet<LanguageServerSelector>,
 2434        cx: &mut Context<LspStore>,
 2435    ) {
 2436        let buffer = buffer_handle.read(cx);
 2437        let buffer_id = buffer.remote_id();
 2438
 2439        let Some(file) = File::from_dyn(buffer.file()) else {
 2440            return;
 2441        };
 2442        if !file.is_local() {
 2443            return;
 2444        }
 2445
 2446        let abs_path = file.abs_path(cx);
 2447        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2448            return;
 2449        };
 2450        let initial_snapshot = buffer.text_snapshot();
 2451        let worktree_id = file.worktree_id(cx);
 2452
 2453        let Some(language) = buffer.language().cloned() else {
 2454            return;
 2455        };
 2456        let path: Arc<RelPath> = file
 2457            .path()
 2458            .parent()
 2459            .map(Arc::from)
 2460            .unwrap_or_else(|| file.path().clone());
 2461        let Some(worktree) = self
 2462            .worktree_store
 2463            .read(cx)
 2464            .worktree_for_id(worktree_id, cx)
 2465        else {
 2466            return;
 2467        };
 2468        let language_name = language.name();
 2469        let (reused, delegate, servers) = self
 2470            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2471            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2472            .unwrap_or_else(|| {
 2473                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2474                let delegate: Arc<dyn ManifestDelegate> =
 2475                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2476
 2477                let servers = self
 2478                    .lsp_tree
 2479                    .walk(
 2480                        ProjectPath { worktree_id, path },
 2481                        language.name(),
 2482                        language.manifest(),
 2483                        &delegate,
 2484                        cx,
 2485                    )
 2486                    .collect::<Vec<_>>();
 2487                (false, lsp_delegate, servers)
 2488            });
 2489        let servers_and_adapters = servers
 2490            .into_iter()
 2491            .filter_map(|server_node| {
 2492                if reused && server_node.server_id().is_none() {
 2493                    return None;
 2494                }
 2495                if !only_register_servers.is_empty() {
 2496                    if let Some(server_id) = server_node.server_id()
 2497                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2498                    {
 2499                        return None;
 2500                    }
 2501                    if let Some(name) = server_node.name()
 2502                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2503                    {
 2504                        return None;
 2505                    }
 2506                }
 2507
 2508                let server_id = server_node.server_id_or_init(|disposition| {
 2509                    let path = &disposition.path;
 2510
 2511                    {
 2512                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2513
 2514                        let server_id = self.get_or_insert_language_server(
 2515                            &worktree,
 2516                            delegate.clone(),
 2517                            disposition,
 2518                            &language_name,
 2519                            cx,
 2520                        );
 2521
 2522                        if let Some(state) = self.language_servers.get(&server_id)
 2523                            && let Ok(uri) = uri
 2524                        {
 2525                            state.add_workspace_folder(uri);
 2526                        };
 2527                        server_id
 2528                    }
 2529                })?;
 2530                let server_state = self.language_servers.get(&server_id)?;
 2531                if let LanguageServerState::Running {
 2532                    server, adapter, ..
 2533                } = server_state
 2534                {
 2535                    Some((server.clone(), adapter.clone()))
 2536                } else {
 2537                    None
 2538                }
 2539            })
 2540            .collect::<Vec<_>>();
 2541        for (server, adapter) in servers_and_adapters {
 2542            buffer_handle.update(cx, |buffer, cx| {
 2543                buffer.set_completion_triggers(
 2544                    server.server_id(),
 2545                    server
 2546                        .capabilities()
 2547                        .completion_provider
 2548                        .as_ref()
 2549                        .and_then(|provider| {
 2550                            provider
 2551                                .trigger_characters
 2552                                .as_ref()
 2553                                .map(|characters| characters.iter().cloned().collect())
 2554                        })
 2555                        .unwrap_or_default(),
 2556                    cx,
 2557                );
 2558            });
 2559
 2560            let snapshot = LspBufferSnapshot {
 2561                version: 0,
 2562                snapshot: initial_snapshot.clone(),
 2563            };
 2564
 2565            let mut registered = false;
 2566            self.buffer_snapshots
 2567                .entry(buffer_id)
 2568                .or_default()
 2569                .entry(server.server_id())
 2570                .or_insert_with(|| {
 2571                    registered = true;
 2572                    server.register_buffer(
 2573                        uri.clone(),
 2574                        adapter.language_id(&language.name()),
 2575                        0,
 2576                        initial_snapshot.text(),
 2577                    );
 2578
 2579                    vec![snapshot]
 2580                });
 2581
 2582            self.buffers_opened_in_servers
 2583                .entry(buffer_id)
 2584                .or_default()
 2585                .insert(server.server_id());
 2586            if registered {
 2587                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2588                    language_server_id: server.server_id(),
 2589                    name: None,
 2590                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2591                        proto::RegisteredForBuffer {
 2592                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2593                            buffer_id: buffer_id.to_proto(),
 2594                        },
 2595                    ),
 2596                });
 2597            }
 2598        }
 2599    }
 2600
 2601    fn reuse_existing_language_server<'lang_name>(
 2602        &self,
 2603        server_tree: &LanguageServerTree,
 2604        worktree: &Entity<Worktree>,
 2605        language_name: &'lang_name LanguageName,
 2606        cx: &mut App,
 2607    ) -> Option<(
 2608        Arc<LocalLspAdapterDelegate>,
 2609        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2610    )> {
 2611        if worktree.read(cx).is_visible() {
 2612            return None;
 2613        }
 2614
 2615        let worktree_store = self.worktree_store.read(cx);
 2616        let servers = server_tree
 2617            .instances
 2618            .iter()
 2619            .filter(|(worktree_id, _)| {
 2620                worktree_store
 2621                    .worktree_for_id(**worktree_id, cx)
 2622                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2623            })
 2624            .flat_map(|(worktree_id, servers)| {
 2625                servers
 2626                    .roots
 2627                    .iter()
 2628                    .flat_map(|(_, language_servers)| language_servers)
 2629                    .map(move |(_, (server_node, server_languages))| {
 2630                        (worktree_id, server_node, server_languages)
 2631                    })
 2632                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2633                    .map(|(worktree_id, server_node, _)| {
 2634                        (
 2635                            *worktree_id,
 2636                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2637                        )
 2638                    })
 2639            })
 2640            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2641                acc.entry(worktree_id)
 2642                    .or_insert_with(Vec::new)
 2643                    .push(server_node);
 2644                acc
 2645            })
 2646            .into_values()
 2647            .max_by_key(|servers| servers.len())?;
 2648
 2649        let worktree_id = worktree.read(cx).id();
 2650        let apply = move |tree: &mut LanguageServerTree| {
 2651            for server_node in &servers {
 2652                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2653            }
 2654            servers
 2655        };
 2656
 2657        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2658        Some((delegate, apply))
 2659    }
 2660
 2661    pub(crate) fn unregister_old_buffer_from_language_servers(
 2662        &mut self,
 2663        buffer: &Entity<Buffer>,
 2664        old_file: &File,
 2665        cx: &mut App,
 2666    ) {
 2667        let old_path = match old_file.as_local() {
 2668            Some(local) => local.abs_path(cx),
 2669            None => return,
 2670        };
 2671
 2672        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2673            debug_panic!("{old_path:?} is not parseable as an URI");
 2674            return;
 2675        };
 2676        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2677    }
 2678
 2679    pub(crate) fn unregister_buffer_from_language_servers(
 2680        &mut self,
 2681        buffer: &Entity<Buffer>,
 2682        file_url: &lsp::Uri,
 2683        cx: &mut App,
 2684    ) {
 2685        buffer.update(cx, |buffer, cx| {
 2686            let _ = self.buffer_snapshots.remove(&buffer.remote_id());
 2687
 2688            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2689                language_server.unregister_buffer(file_url.clone());
 2690            }
 2691        });
 2692    }
 2693
 2694    fn buffer_snapshot_for_lsp_version(
 2695        &mut self,
 2696        buffer: &Entity<Buffer>,
 2697        server_id: LanguageServerId,
 2698        version: Option<i32>,
 2699        cx: &App,
 2700    ) -> Result<TextBufferSnapshot> {
 2701        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2702
 2703        if let Some(version) = version {
 2704            let buffer_id = buffer.read(cx).remote_id();
 2705            let snapshots = if let Some(snapshots) = self
 2706                .buffer_snapshots
 2707                .get_mut(&buffer_id)
 2708                .and_then(|m| m.get_mut(&server_id))
 2709            {
 2710                snapshots
 2711            } else if version == 0 {
 2712                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2713                // We detect this case and treat it as if the version was `None`.
 2714                return Ok(buffer.read(cx).text_snapshot());
 2715            } else {
 2716                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2717            };
 2718
 2719            let found_snapshot = snapshots
 2720                    .binary_search_by_key(&version, |e| e.version)
 2721                    .map(|ix| snapshots[ix].snapshot.clone())
 2722                    .map_err(|_| {
 2723                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2724                    })?;
 2725
 2726            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2727            Ok(found_snapshot)
 2728        } else {
 2729            Ok((buffer.read(cx)).text_snapshot())
 2730        }
 2731    }
 2732
 2733    async fn get_server_code_actions_from_action_kinds(
 2734        lsp_store: &WeakEntity<LspStore>,
 2735        language_server_id: LanguageServerId,
 2736        code_action_kinds: Vec<lsp::CodeActionKind>,
 2737        buffer: &Entity<Buffer>,
 2738        cx: &mut AsyncApp,
 2739    ) -> Result<Vec<CodeAction>> {
 2740        let actions = lsp_store
 2741            .update(cx, move |this, cx| {
 2742                let request = GetCodeActions {
 2743                    range: text::Anchor::MIN..text::Anchor::MAX,
 2744                    kinds: Some(code_action_kinds),
 2745                };
 2746                let server = LanguageServerToQuery::Other(language_server_id);
 2747                this.request_lsp(buffer.clone(), server, request, cx)
 2748            })?
 2749            .await?;
 2750        Ok(actions)
 2751    }
 2752
 2753    pub async fn execute_code_actions_on_server(
 2754        lsp_store: &WeakEntity<LspStore>,
 2755        language_server: &Arc<LanguageServer>,
 2756
 2757        actions: Vec<CodeAction>,
 2758        push_to_history: bool,
 2759        project_transaction: &mut ProjectTransaction,
 2760        cx: &mut AsyncApp,
 2761    ) -> anyhow::Result<()> {
 2762        for mut action in actions {
 2763            Self::try_resolve_code_action(language_server, &mut action)
 2764                .await
 2765                .context("resolving a formatting code action")?;
 2766
 2767            if let Some(edit) = action.lsp_action.edit() {
 2768                if edit.changes.is_none() && edit.document_changes.is_none() {
 2769                    continue;
 2770                }
 2771
 2772                let new = Self::deserialize_workspace_edit(
 2773                    lsp_store.upgrade().context("project dropped")?,
 2774                    edit.clone(),
 2775                    push_to_history,
 2776                    language_server.clone(),
 2777                    cx,
 2778                )
 2779                .await?;
 2780                project_transaction.0.extend(new.0);
 2781            }
 2782
 2783            if let Some(command) = action.lsp_action.command() {
 2784                let server_capabilities = language_server.capabilities();
 2785                let available_commands = server_capabilities
 2786                    .execute_command_provider
 2787                    .as_ref()
 2788                    .map(|options| options.commands.as_slice())
 2789                    .unwrap_or_default();
 2790                if available_commands.contains(&command.command) {
 2791                    lsp_store.update(cx, |lsp_store, _| {
 2792                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2793                            mode.last_workspace_edits_by_language_server
 2794                                .remove(&language_server.server_id());
 2795                        }
 2796                    })?;
 2797
 2798                    language_server
 2799                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2800                            command: command.command.clone(),
 2801                            arguments: command.arguments.clone().unwrap_or_default(),
 2802                            ..Default::default()
 2803                        })
 2804                        .await
 2805                        .into_response()
 2806                        .context("execute command")?;
 2807
 2808                    lsp_store.update(cx, |this, _| {
 2809                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2810                            project_transaction.0.extend(
 2811                                mode.last_workspace_edits_by_language_server
 2812                                    .remove(&language_server.server_id())
 2813                                    .unwrap_or_default()
 2814                                    .0,
 2815                            )
 2816                        }
 2817                    })?;
 2818                } else {
 2819                    log::warn!(
 2820                        "Cannot execute a command {} not listed in the language server capabilities",
 2821                        command.command
 2822                    )
 2823                }
 2824            }
 2825        }
 2826        Ok(())
 2827    }
 2828
 2829    pub async fn deserialize_text_edits(
 2830        this: Entity<LspStore>,
 2831        buffer_to_edit: Entity<Buffer>,
 2832        edits: Vec<lsp::TextEdit>,
 2833        push_to_history: bool,
 2834        _: Arc<CachedLspAdapter>,
 2835        language_server: Arc<LanguageServer>,
 2836        cx: &mut AsyncApp,
 2837    ) -> Result<Option<Transaction>> {
 2838        let edits = this
 2839            .update(cx, |this, cx| {
 2840                this.as_local_mut().unwrap().edits_from_lsp(
 2841                    &buffer_to_edit,
 2842                    edits,
 2843                    language_server.server_id(),
 2844                    None,
 2845                    cx,
 2846                )
 2847            })?
 2848            .await?;
 2849
 2850        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2851            buffer.finalize_last_transaction();
 2852            buffer.start_transaction();
 2853            for (range, text) in edits {
 2854                buffer.edit([(range, text)], None, cx);
 2855            }
 2856
 2857            if buffer.end_transaction(cx).is_some() {
 2858                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2859                if !push_to_history {
 2860                    buffer.forget_transaction(transaction.id);
 2861                }
 2862                Some(transaction)
 2863            } else {
 2864                None
 2865            }
 2866        })?;
 2867
 2868        Ok(transaction)
 2869    }
 2870
 2871    #[allow(clippy::type_complexity)]
 2872    pub(crate) fn edits_from_lsp(
 2873        &mut self,
 2874        buffer: &Entity<Buffer>,
 2875        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2876        server_id: LanguageServerId,
 2877        version: Option<i32>,
 2878        cx: &mut Context<LspStore>,
 2879    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 2880        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 2881        cx.background_spawn(async move {
 2882            let snapshot = snapshot?;
 2883            let mut lsp_edits = lsp_edits
 2884                .into_iter()
 2885                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 2886                .collect::<Vec<_>>();
 2887
 2888            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 2889
 2890            let mut lsp_edits = lsp_edits.into_iter().peekable();
 2891            let mut edits = Vec::new();
 2892            while let Some((range, mut new_text)) = lsp_edits.next() {
 2893                // Clip invalid ranges provided by the language server.
 2894                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 2895                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 2896
 2897                // Combine any LSP edits that are adjacent.
 2898                //
 2899                // Also, combine LSP edits that are separated from each other by only
 2900                // a newline. This is important because for some code actions,
 2901                // Rust-analyzer rewrites the entire buffer via a series of edits that
 2902                // are separated by unchanged newline characters.
 2903                //
 2904                // In order for the diffing logic below to work properly, any edits that
 2905                // cancel each other out must be combined into one.
 2906                while let Some((next_range, next_text)) = lsp_edits.peek() {
 2907                    if next_range.start.0 > range.end {
 2908                        if next_range.start.0.row > range.end.row + 1
 2909                            || next_range.start.0.column > 0
 2910                            || snapshot.clip_point_utf16(
 2911                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 2912                                Bias::Left,
 2913                            ) > range.end
 2914                        {
 2915                            break;
 2916                        }
 2917                        new_text.push('\n');
 2918                    }
 2919                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 2920                    new_text.push_str(next_text);
 2921                    lsp_edits.next();
 2922                }
 2923
 2924                // For multiline edits, perform a diff of the old and new text so that
 2925                // we can identify the changes more precisely, preserving the locations
 2926                // of any anchors positioned in the unchanged regions.
 2927                if range.end.row > range.start.row {
 2928                    let offset = range.start.to_offset(&snapshot);
 2929                    let old_text = snapshot.text_for_range(range).collect::<String>();
 2930                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 2931                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 2932                        (
 2933                            snapshot.anchor_after(offset + range.start)
 2934                                ..snapshot.anchor_before(offset + range.end),
 2935                            replacement,
 2936                        )
 2937                    }));
 2938                } else if range.end == range.start {
 2939                    let anchor = snapshot.anchor_after(range.start);
 2940                    edits.push((anchor..anchor, new_text.into()));
 2941                } else {
 2942                    let edit_start = snapshot.anchor_after(range.start);
 2943                    let edit_end = snapshot.anchor_before(range.end);
 2944                    edits.push((edit_start..edit_end, new_text.into()));
 2945                }
 2946            }
 2947
 2948            Ok(edits)
 2949        })
 2950    }
 2951
 2952    pub(crate) async fn deserialize_workspace_edit(
 2953        this: Entity<LspStore>,
 2954        edit: lsp::WorkspaceEdit,
 2955        push_to_history: bool,
 2956        language_server: Arc<LanguageServer>,
 2957        cx: &mut AsyncApp,
 2958    ) -> Result<ProjectTransaction> {
 2959        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 2960
 2961        let mut operations = Vec::new();
 2962        if let Some(document_changes) = edit.document_changes {
 2963            match document_changes {
 2964                lsp::DocumentChanges::Edits(edits) => {
 2965                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 2966                }
 2967                lsp::DocumentChanges::Operations(ops) => operations = ops,
 2968            }
 2969        } else if let Some(changes) = edit.changes {
 2970            operations.extend(changes.into_iter().map(|(uri, edits)| {
 2971                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 2972                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 2973                        uri,
 2974                        version: None,
 2975                    },
 2976                    edits: edits.into_iter().map(Edit::Plain).collect(),
 2977                })
 2978            }));
 2979        }
 2980
 2981        let mut project_transaction = ProjectTransaction::default();
 2982        for operation in operations {
 2983            match operation {
 2984                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 2985                    let abs_path = op
 2986                        .uri
 2987                        .to_file_path()
 2988                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2989
 2990                    if let Some(parent_path) = abs_path.parent() {
 2991                        fs.create_dir(parent_path).await?;
 2992                    }
 2993                    if abs_path.ends_with("/") {
 2994                        fs.create_dir(&abs_path).await?;
 2995                    } else {
 2996                        fs.create_file(
 2997                            &abs_path,
 2998                            op.options
 2999                                .map(|options| fs::CreateOptions {
 3000                                    overwrite: options.overwrite.unwrap_or(false),
 3001                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3002                                })
 3003                                .unwrap_or_default(),
 3004                        )
 3005                        .await?;
 3006                    }
 3007                }
 3008
 3009                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3010                    let source_abs_path = op
 3011                        .old_uri
 3012                        .to_file_path()
 3013                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3014                    let target_abs_path = op
 3015                        .new_uri
 3016                        .to_file_path()
 3017                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3018                    fs.rename(
 3019                        &source_abs_path,
 3020                        &target_abs_path,
 3021                        op.options
 3022                            .map(|options| fs::RenameOptions {
 3023                                overwrite: options.overwrite.unwrap_or(false),
 3024                                ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3025                            })
 3026                            .unwrap_or_default(),
 3027                    )
 3028                    .await?;
 3029                }
 3030
 3031                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3032                    let abs_path = op
 3033                        .uri
 3034                        .to_file_path()
 3035                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3036                    let options = op
 3037                        .options
 3038                        .map(|options| fs::RemoveOptions {
 3039                            recursive: options.recursive.unwrap_or(false),
 3040                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3041                        })
 3042                        .unwrap_or_default();
 3043                    if abs_path.ends_with("/") {
 3044                        fs.remove_dir(&abs_path, options).await?;
 3045                    } else {
 3046                        fs.remove_file(&abs_path, options).await?;
 3047                    }
 3048                }
 3049
 3050                lsp::DocumentChangeOperation::Edit(op) => {
 3051                    let buffer_to_edit = this
 3052                        .update(cx, |this, cx| {
 3053                            this.open_local_buffer_via_lsp(
 3054                                op.text_document.uri.clone(),
 3055                                language_server.server_id(),
 3056                                cx,
 3057                            )
 3058                        })?
 3059                        .await?;
 3060
 3061                    let edits = this
 3062                        .update(cx, |this, cx| {
 3063                            let path = buffer_to_edit.read(cx).project_path(cx);
 3064                            let active_entry = this.active_entry;
 3065                            let is_active_entry = path.is_some_and(|project_path| {
 3066                                this.worktree_store
 3067                                    .read(cx)
 3068                                    .entry_for_path(&project_path, cx)
 3069                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3070                            });
 3071                            let local = this.as_local_mut().unwrap();
 3072
 3073                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3074                            for edit in op.edits {
 3075                                match edit {
 3076                                    Edit::Plain(edit) => {
 3077                                        if !edits.contains(&edit) {
 3078                                            edits.push(edit)
 3079                                        }
 3080                                    }
 3081                                    Edit::Annotated(edit) => {
 3082                                        if !edits.contains(&edit.text_edit) {
 3083                                            edits.push(edit.text_edit)
 3084                                        }
 3085                                    }
 3086                                    Edit::Snippet(edit) => {
 3087                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3088                                        else {
 3089                                            continue;
 3090                                        };
 3091
 3092                                        if is_active_entry {
 3093                                            snippet_edits.push((edit.range, snippet));
 3094                                        } else {
 3095                                            // Since this buffer is not focused, apply a normal edit.
 3096                                            let new_edit = TextEdit {
 3097                                                range: edit.range,
 3098                                                new_text: snippet.text,
 3099                                            };
 3100                                            if !edits.contains(&new_edit) {
 3101                                                edits.push(new_edit);
 3102                                            }
 3103                                        }
 3104                                    }
 3105                                }
 3106                            }
 3107                            if !snippet_edits.is_empty() {
 3108                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3109                                let version = if let Some(buffer_version) = op.text_document.version
 3110                                {
 3111                                    local
 3112                                        .buffer_snapshot_for_lsp_version(
 3113                                            &buffer_to_edit,
 3114                                            language_server.server_id(),
 3115                                            Some(buffer_version),
 3116                                            cx,
 3117                                        )
 3118                                        .ok()
 3119                                        .map(|snapshot| snapshot.version)
 3120                                } else {
 3121                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3122                                };
 3123
 3124                                let most_recent_edit =
 3125                                    version.and_then(|version| version.most_recent());
 3126                                // Check if the edit that triggered that edit has been made by this participant.
 3127
 3128                                if let Some(most_recent_edit) = most_recent_edit {
 3129                                    cx.emit(LspStoreEvent::SnippetEdit {
 3130                                        buffer_id,
 3131                                        edits: snippet_edits,
 3132                                        most_recent_edit,
 3133                                    });
 3134                                }
 3135                            }
 3136
 3137                            local.edits_from_lsp(
 3138                                &buffer_to_edit,
 3139                                edits,
 3140                                language_server.server_id(),
 3141                                op.text_document.version,
 3142                                cx,
 3143                            )
 3144                        })?
 3145                        .await?;
 3146
 3147                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3148                        buffer.finalize_last_transaction();
 3149                        buffer.start_transaction();
 3150                        for (range, text) in edits {
 3151                            buffer.edit([(range, text)], None, cx);
 3152                        }
 3153
 3154                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3155                            if push_to_history {
 3156                                buffer.finalize_last_transaction();
 3157                                buffer.get_transaction(transaction_id).cloned()
 3158                            } else {
 3159                                buffer.forget_transaction(transaction_id)
 3160                            }
 3161                        })
 3162                    })?;
 3163                    if let Some(transaction) = transaction {
 3164                        project_transaction.0.insert(buffer_to_edit, transaction);
 3165                    }
 3166                }
 3167            }
 3168        }
 3169
 3170        Ok(project_transaction)
 3171    }
 3172
 3173    async fn on_lsp_workspace_edit(
 3174        this: WeakEntity<LspStore>,
 3175        params: lsp::ApplyWorkspaceEditParams,
 3176        server_id: LanguageServerId,
 3177        cx: &mut AsyncApp,
 3178    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3179        let this = this.upgrade().context("project project closed")?;
 3180        let language_server = this
 3181            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3182            .context("language server not found")?;
 3183        let transaction = Self::deserialize_workspace_edit(
 3184            this.clone(),
 3185            params.edit,
 3186            true,
 3187            language_server.clone(),
 3188            cx,
 3189        )
 3190        .await
 3191        .log_err();
 3192        this.update(cx, |this, _| {
 3193            if let Some(transaction) = transaction {
 3194                this.as_local_mut()
 3195                    .unwrap()
 3196                    .last_workspace_edits_by_language_server
 3197                    .insert(server_id, transaction);
 3198            }
 3199        })?;
 3200        Ok(lsp::ApplyWorkspaceEditResponse {
 3201            applied: true,
 3202            failed_change: None,
 3203            failure_reason: None,
 3204        })
 3205    }
 3206
 3207    fn remove_worktree(
 3208        &mut self,
 3209        id_to_remove: WorktreeId,
 3210        cx: &mut Context<LspStore>,
 3211    ) -> Vec<LanguageServerId> {
 3212        self.diagnostics.remove(&id_to_remove);
 3213        self.prettier_store.update(cx, |prettier_store, cx| {
 3214            prettier_store.remove_worktree(id_to_remove, cx);
 3215        });
 3216
 3217        let mut servers_to_remove = BTreeSet::default();
 3218        let mut servers_to_preserve = HashSet::default();
 3219        for (seed, state) in &self.language_server_ids {
 3220            if seed.worktree_id == id_to_remove {
 3221                servers_to_remove.insert(state.id);
 3222            } else {
 3223                servers_to_preserve.insert(state.id);
 3224            }
 3225        }
 3226        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3227        self.language_server_ids
 3228            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3229        for server_id_to_remove in &servers_to_remove {
 3230            self.language_server_watched_paths
 3231                .remove(server_id_to_remove);
 3232            self.language_server_paths_watched_for_rename
 3233                .remove(server_id_to_remove);
 3234            self.last_workspace_edits_by_language_server
 3235                .remove(server_id_to_remove);
 3236            self.language_servers.remove(server_id_to_remove);
 3237            self.buffer_pull_diagnostics_result_ids
 3238                .remove(server_id_to_remove);
 3239            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3240                buffer_servers.remove(server_id_to_remove);
 3241            }
 3242            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3243        }
 3244        servers_to_remove.into_iter().collect()
 3245    }
 3246
 3247    fn rebuild_watched_paths_inner<'a>(
 3248        &'a self,
 3249        language_server_id: LanguageServerId,
 3250        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3251        cx: &mut Context<LspStore>,
 3252    ) -> LanguageServerWatchedPathsBuilder {
 3253        let worktrees = self
 3254            .worktree_store
 3255            .read(cx)
 3256            .worktrees()
 3257            .filter_map(|worktree| {
 3258                self.language_servers_for_worktree(worktree.read(cx).id())
 3259                    .find(|server| server.server_id() == language_server_id)
 3260                    .map(|_| worktree)
 3261            })
 3262            .collect::<Vec<_>>();
 3263
 3264        let mut worktree_globs = HashMap::default();
 3265        let mut abs_globs = HashMap::default();
 3266        log::trace!(
 3267            "Processing new watcher paths for language server with id {}",
 3268            language_server_id
 3269        );
 3270
 3271        for watcher in watchers {
 3272            if let Some((worktree, literal_prefix, pattern)) =
 3273                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3274            {
 3275                worktree.update(cx, |worktree, _| {
 3276                    if let Some((tree, glob)) =
 3277                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3278                    {
 3279                        tree.add_path_prefix_to_scan(literal_prefix);
 3280                        worktree_globs
 3281                            .entry(tree.id())
 3282                            .or_insert_with(GlobSetBuilder::new)
 3283                            .add(glob);
 3284                    }
 3285                });
 3286            } else {
 3287                let (path, pattern) = match &watcher.glob_pattern {
 3288                    lsp::GlobPattern::String(s) => {
 3289                        let watcher_path = SanitizedPath::new(s);
 3290                        let path = glob_literal_prefix(watcher_path.as_path());
 3291                        let pattern = watcher_path
 3292                            .as_path()
 3293                            .strip_prefix(&path)
 3294                            .map(|p| p.to_string_lossy().into_owned())
 3295                            .unwrap_or_else(|e| {
 3296                                debug_panic!(
 3297                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3298                                    s,
 3299                                    path.display(),
 3300                                    e
 3301                                );
 3302                                watcher_path.as_path().to_string_lossy().into_owned()
 3303                            });
 3304                        (path, pattern)
 3305                    }
 3306                    lsp::GlobPattern::Relative(rp) => {
 3307                        let Ok(mut base_uri) = match &rp.base_uri {
 3308                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3309                            lsp::OneOf::Right(base_uri) => base_uri,
 3310                        }
 3311                        .to_file_path() else {
 3312                            continue;
 3313                        };
 3314
 3315                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3316                        let pattern = Path::new(&rp.pattern)
 3317                            .strip_prefix(&path)
 3318                            .map(|p| p.to_string_lossy().into_owned())
 3319                            .unwrap_or_else(|e| {
 3320                                debug_panic!(
 3321                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3322                                    rp.pattern,
 3323                                    path.display(),
 3324                                    e
 3325                                );
 3326                                rp.pattern.clone()
 3327                            });
 3328                        base_uri.push(path);
 3329                        (base_uri, pattern)
 3330                    }
 3331                };
 3332
 3333                if let Some(glob) = Glob::new(&pattern).log_err() {
 3334                    if !path
 3335                        .components()
 3336                        .any(|c| matches!(c, path::Component::Normal(_)))
 3337                    {
 3338                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3339                        // rather than adding a new watcher for `/`.
 3340                        for worktree in &worktrees {
 3341                            worktree_globs
 3342                                .entry(worktree.read(cx).id())
 3343                                .or_insert_with(GlobSetBuilder::new)
 3344                                .add(glob.clone());
 3345                        }
 3346                    } else {
 3347                        abs_globs
 3348                            .entry(path.into())
 3349                            .or_insert_with(GlobSetBuilder::new)
 3350                            .add(glob);
 3351                    }
 3352                }
 3353            }
 3354        }
 3355
 3356        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3357        for (worktree_id, builder) in worktree_globs {
 3358            if let Ok(globset) = builder.build() {
 3359                watch_builder.watch_worktree(worktree_id, globset);
 3360            }
 3361        }
 3362        for (abs_path, builder) in abs_globs {
 3363            if let Ok(globset) = builder.build() {
 3364                watch_builder.watch_abs_path(abs_path, globset);
 3365            }
 3366        }
 3367        watch_builder
 3368    }
 3369
 3370    fn worktree_and_path_for_file_watcher(
 3371        worktrees: &[Entity<Worktree>],
 3372        watcher: &FileSystemWatcher,
 3373        cx: &App,
 3374    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3375        worktrees.iter().find_map(|worktree| {
 3376            let tree = worktree.read(cx);
 3377            let worktree_root_path = tree.abs_path();
 3378            let path_style = tree.path_style();
 3379            match &watcher.glob_pattern {
 3380                lsp::GlobPattern::String(s) => {
 3381                    let watcher_path = SanitizedPath::new(s);
 3382                    let relative = watcher_path
 3383                        .as_path()
 3384                        .strip_prefix(&worktree_root_path)
 3385                        .ok()?;
 3386                    let literal_prefix = glob_literal_prefix(relative);
 3387                    Some((
 3388                        worktree.clone(),
 3389                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3390                        relative.to_string_lossy().into_owned(),
 3391                    ))
 3392                }
 3393                lsp::GlobPattern::Relative(rp) => {
 3394                    let base_uri = match &rp.base_uri {
 3395                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3396                        lsp::OneOf::Right(base_uri) => base_uri,
 3397                    }
 3398                    .to_file_path()
 3399                    .ok()?;
 3400                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3401                    let mut literal_prefix = relative.to_owned();
 3402                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3403                    Some((
 3404                        worktree.clone(),
 3405                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3406                        rp.pattern.clone(),
 3407                    ))
 3408                }
 3409            }
 3410        })
 3411    }
 3412
 3413    fn rebuild_watched_paths(
 3414        &mut self,
 3415        language_server_id: LanguageServerId,
 3416        cx: &mut Context<LspStore>,
 3417    ) {
 3418        let Some(registrations) = self
 3419            .language_server_dynamic_registrations
 3420            .get(&language_server_id)
 3421        else {
 3422            return;
 3423        };
 3424
 3425        let watch_builder = self.rebuild_watched_paths_inner(
 3426            language_server_id,
 3427            registrations.did_change_watched_files.values().flatten(),
 3428            cx,
 3429        );
 3430        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3431        self.language_server_watched_paths
 3432            .insert(language_server_id, watcher);
 3433
 3434        cx.notify();
 3435    }
 3436
 3437    fn on_lsp_did_change_watched_files(
 3438        &mut self,
 3439        language_server_id: LanguageServerId,
 3440        registration_id: &str,
 3441        params: DidChangeWatchedFilesRegistrationOptions,
 3442        cx: &mut Context<LspStore>,
 3443    ) {
 3444        let registrations = self
 3445            .language_server_dynamic_registrations
 3446            .entry(language_server_id)
 3447            .or_default();
 3448
 3449        registrations
 3450            .did_change_watched_files
 3451            .insert(registration_id.to_string(), params.watchers);
 3452
 3453        self.rebuild_watched_paths(language_server_id, cx);
 3454    }
 3455
 3456    fn on_lsp_unregister_did_change_watched_files(
 3457        &mut self,
 3458        language_server_id: LanguageServerId,
 3459        registration_id: &str,
 3460        cx: &mut Context<LspStore>,
 3461    ) {
 3462        let registrations = self
 3463            .language_server_dynamic_registrations
 3464            .entry(language_server_id)
 3465            .or_default();
 3466
 3467        if registrations
 3468            .did_change_watched_files
 3469            .remove(registration_id)
 3470            .is_some()
 3471        {
 3472            log::info!(
 3473                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3474                language_server_id,
 3475                registration_id
 3476            );
 3477        } else {
 3478            log::warn!(
 3479                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3480                language_server_id,
 3481                registration_id
 3482            );
 3483        }
 3484
 3485        self.rebuild_watched_paths(language_server_id, cx);
 3486    }
 3487
 3488    async fn initialization_options_for_adapter(
 3489        adapter: Arc<dyn LspAdapter>,
 3490        delegate: &Arc<dyn LspAdapterDelegate>,
 3491    ) -> Result<Option<serde_json::Value>> {
 3492        let Some(mut initialization_config) =
 3493            adapter.clone().initialization_options(delegate).await?
 3494        else {
 3495            return Ok(None);
 3496        };
 3497
 3498        for other_adapter in delegate.registered_lsp_adapters() {
 3499            if other_adapter.name() == adapter.name() {
 3500                continue;
 3501            }
 3502            if let Ok(Some(target_config)) = other_adapter
 3503                .clone()
 3504                .additional_initialization_options(adapter.name(), delegate)
 3505                .await
 3506            {
 3507                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3508            }
 3509        }
 3510
 3511        Ok(Some(initialization_config))
 3512    }
 3513
 3514    async fn workspace_configuration_for_adapter(
 3515        adapter: Arc<dyn LspAdapter>,
 3516        delegate: &Arc<dyn LspAdapterDelegate>,
 3517        toolchain: Option<Toolchain>,
 3518        cx: &mut AsyncApp,
 3519    ) -> Result<serde_json::Value> {
 3520        let mut workspace_config = adapter
 3521            .clone()
 3522            .workspace_configuration(delegate, toolchain, cx)
 3523            .await?;
 3524
 3525        for other_adapter in delegate.registered_lsp_adapters() {
 3526            if other_adapter.name() == adapter.name() {
 3527                continue;
 3528            }
 3529            if let Ok(Some(target_config)) = other_adapter
 3530                .clone()
 3531                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3532                .await
 3533            {
 3534                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3535            }
 3536        }
 3537
 3538        Ok(workspace_config)
 3539    }
 3540
 3541    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3542        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3543            Some(server.clone())
 3544        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3545            Some(Arc::clone(server))
 3546        } else {
 3547            None
 3548        }
 3549    }
 3550}
 3551
 3552fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3553    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3554        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3555            language_server_id: server.server_id(),
 3556            name: Some(server.name()),
 3557            message: proto::update_language_server::Variant::MetadataUpdated(
 3558                proto::ServerMetadataUpdated {
 3559                    capabilities: Some(capabilities),
 3560                },
 3561            ),
 3562        });
 3563    }
 3564}
 3565
 3566#[derive(Debug)]
 3567pub struct FormattableBuffer {
 3568    handle: Entity<Buffer>,
 3569    abs_path: Option<PathBuf>,
 3570    env: Option<HashMap<String, String>>,
 3571    ranges: Option<Vec<Range<Anchor>>>,
 3572}
 3573
 3574pub struct RemoteLspStore {
 3575    upstream_client: Option<AnyProtoClient>,
 3576    upstream_project_id: u64,
 3577}
 3578
 3579pub(crate) enum LspStoreMode {
 3580    Local(LocalLspStore),   // ssh host and collab host
 3581    Remote(RemoteLspStore), // collab guest
 3582}
 3583
 3584impl LspStoreMode {
 3585    fn is_local(&self) -> bool {
 3586        matches!(self, LspStoreMode::Local(_))
 3587    }
 3588}
 3589
 3590pub struct LspStore {
 3591    mode: LspStoreMode,
 3592    last_formatting_failure: Option<String>,
 3593    downstream_client: Option<(AnyProtoClient, u64)>,
 3594    nonce: u128,
 3595    buffer_store: Entity<BufferStore>,
 3596    worktree_store: Entity<WorktreeStore>,
 3597    pub languages: Arc<LanguageRegistry>,
 3598    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3599    active_entry: Option<ProjectEntryId>,
 3600    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3601    _maintain_buffer_languages: Task<()>,
 3602    diagnostic_summaries:
 3603        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3604    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3605    lsp_data: HashMap<BufferId, BufferLspData>,
 3606    next_hint_id: Arc<AtomicUsize>,
 3607}
 3608
 3609#[derive(Debug)]
 3610pub struct BufferLspData {
 3611    buffer_version: Global,
 3612    document_colors: Option<DocumentColorData>,
 3613    code_lens: Option<CodeLensData>,
 3614    inlay_hints: BufferInlayHints,
 3615    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3616    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3617}
 3618
 3619#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3620struct LspKey {
 3621    request_type: TypeId,
 3622    server_queried: Option<LanguageServerId>,
 3623}
 3624
 3625impl BufferLspData {
 3626    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3627        Self {
 3628            buffer_version: buffer.read(cx).version(),
 3629            document_colors: None,
 3630            code_lens: None,
 3631            inlay_hints: BufferInlayHints::new(buffer, cx),
 3632            lsp_requests: HashMap::default(),
 3633            chunk_lsp_requests: HashMap::default(),
 3634        }
 3635    }
 3636
 3637    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3638        if let Some(document_colors) = &mut self.document_colors {
 3639            document_colors.colors.remove(&for_server);
 3640            document_colors.cache_version += 1;
 3641        }
 3642
 3643        if let Some(code_lens) = &mut self.code_lens {
 3644            code_lens.lens.remove(&for_server);
 3645        }
 3646
 3647        self.inlay_hints.remove_server_data(for_server);
 3648    }
 3649
 3650    #[cfg(any(test, feature = "test-support"))]
 3651    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3652        &self.inlay_hints
 3653    }
 3654}
 3655
 3656#[derive(Debug, Default, Clone)]
 3657pub struct DocumentColors {
 3658    pub colors: HashSet<DocumentColor>,
 3659    pub cache_version: Option<usize>,
 3660}
 3661
 3662type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3663type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3664
 3665#[derive(Debug, Default)]
 3666struct DocumentColorData {
 3667    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3668    cache_version: usize,
 3669    colors_update: Option<(Global, DocumentColorTask)>,
 3670}
 3671
 3672#[derive(Debug, Default)]
 3673struct CodeLensData {
 3674    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3675    update: Option<(Global, CodeLensTask)>,
 3676}
 3677
 3678#[derive(Debug)]
 3679pub enum LspStoreEvent {
 3680    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3681    LanguageServerRemoved(LanguageServerId),
 3682    LanguageServerUpdate {
 3683        language_server_id: LanguageServerId,
 3684        name: Option<LanguageServerName>,
 3685        message: proto::update_language_server::Variant,
 3686    },
 3687    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3688    LanguageServerPrompt(LanguageServerPromptRequest),
 3689    LanguageDetected {
 3690        buffer: Entity<Buffer>,
 3691        new_language: Option<Arc<Language>>,
 3692    },
 3693    Notification(String),
 3694    RefreshInlayHints {
 3695        server_id: LanguageServerId,
 3696        request_id: Option<usize>,
 3697    },
 3698    RefreshCodeLens,
 3699    DiagnosticsUpdated {
 3700        server_id: LanguageServerId,
 3701        paths: Vec<ProjectPath>,
 3702    },
 3703    DiskBasedDiagnosticsStarted {
 3704        language_server_id: LanguageServerId,
 3705    },
 3706    DiskBasedDiagnosticsFinished {
 3707        language_server_id: LanguageServerId,
 3708    },
 3709    SnippetEdit {
 3710        buffer_id: BufferId,
 3711        edits: Vec<(lsp::Range, Snippet)>,
 3712        most_recent_edit: clock::Lamport,
 3713    },
 3714}
 3715
 3716#[derive(Clone, Debug, Serialize)]
 3717pub struct LanguageServerStatus {
 3718    pub name: LanguageServerName,
 3719    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 3720    pub has_pending_diagnostic_updates: bool,
 3721    progress_tokens: HashSet<ProgressToken>,
 3722    pub worktree: Option<WorktreeId>,
 3723}
 3724
 3725#[derive(Clone, Debug)]
 3726struct CoreSymbol {
 3727    pub language_server_name: LanguageServerName,
 3728    pub source_worktree_id: WorktreeId,
 3729    pub source_language_server_id: LanguageServerId,
 3730    pub path: SymbolLocation,
 3731    pub name: String,
 3732    pub kind: lsp::SymbolKind,
 3733    pub range: Range<Unclipped<PointUtf16>>,
 3734}
 3735
 3736#[derive(Clone, Debug, PartialEq, Eq)]
 3737pub enum SymbolLocation {
 3738    InProject(ProjectPath),
 3739    OutsideProject {
 3740        abs_path: Arc<Path>,
 3741        signature: [u8; 32],
 3742    },
 3743}
 3744
 3745impl SymbolLocation {
 3746    fn file_name(&self) -> Option<&str> {
 3747        match self {
 3748            Self::InProject(path) => path.path.file_name(),
 3749            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3750        }
 3751    }
 3752}
 3753
 3754impl LspStore {
 3755    pub fn init(client: &AnyProtoClient) {
 3756        client.add_entity_request_handler(Self::handle_lsp_query);
 3757        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3758        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3759        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3760        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3761        client.add_entity_message_handler(Self::handle_start_language_server);
 3762        client.add_entity_message_handler(Self::handle_update_language_server);
 3763        client.add_entity_message_handler(Self::handle_language_server_log);
 3764        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3765        client.add_entity_request_handler(Self::handle_format_buffers);
 3766        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3767        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3768        client.add_entity_request_handler(Self::handle_apply_code_action);
 3769        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3770        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3771        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3772        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3773        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3774        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3775        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3776        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3777        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3778        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3779        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3780        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 3781        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3782        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3783        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3784        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3785        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3786
 3787        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3788        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3789        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3790        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3791        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3792        client.add_entity_request_handler(
 3793            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3794        );
 3795        client.add_entity_request_handler(
 3796            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3797        );
 3798        client.add_entity_request_handler(
 3799            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3800        );
 3801    }
 3802
 3803    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3804        match &self.mode {
 3805            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3806            _ => None,
 3807        }
 3808    }
 3809
 3810    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3811        match &self.mode {
 3812            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3813            _ => None,
 3814        }
 3815    }
 3816
 3817    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3818        match &mut self.mode {
 3819            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3820            _ => None,
 3821        }
 3822    }
 3823
 3824    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3825        match &self.mode {
 3826            LspStoreMode::Remote(RemoteLspStore {
 3827                upstream_client: Some(upstream_client),
 3828                upstream_project_id,
 3829                ..
 3830            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3831
 3832            LspStoreMode::Remote(RemoteLspStore {
 3833                upstream_client: None,
 3834                ..
 3835            }) => None,
 3836            LspStoreMode::Local(_) => None,
 3837        }
 3838    }
 3839
 3840    pub fn new_local(
 3841        buffer_store: Entity<BufferStore>,
 3842        worktree_store: Entity<WorktreeStore>,
 3843        prettier_store: Entity<PrettierStore>,
 3844        toolchain_store: Entity<LocalToolchainStore>,
 3845        environment: Entity<ProjectEnvironment>,
 3846        manifest_tree: Entity<ManifestTree>,
 3847        languages: Arc<LanguageRegistry>,
 3848        http_client: Arc<dyn HttpClient>,
 3849        fs: Arc<dyn Fs>,
 3850        cx: &mut Context<Self>,
 3851    ) -> Self {
 3852        let yarn = YarnPathStore::new(fs.clone(), cx);
 3853        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3854            .detach();
 3855        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3856            .detach();
 3857        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 3858            .detach();
 3859        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 3860            .detach();
 3861        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 3862            .detach();
 3863        subscribe_to_binary_statuses(&languages, cx).detach();
 3864
 3865        let _maintain_workspace_config = {
 3866            let (sender, receiver) = watch::channel();
 3867            (Self::maintain_workspace_config(receiver, cx), sender)
 3868        };
 3869
 3870        Self {
 3871            mode: LspStoreMode::Local(LocalLspStore {
 3872                weak: cx.weak_entity(),
 3873                worktree_store: worktree_store.clone(),
 3874
 3875                supplementary_language_servers: Default::default(),
 3876                languages: languages.clone(),
 3877                language_server_ids: Default::default(),
 3878                language_servers: Default::default(),
 3879                last_workspace_edits_by_language_server: Default::default(),
 3880                language_server_watched_paths: Default::default(),
 3881                language_server_paths_watched_for_rename: Default::default(),
 3882                language_server_dynamic_registrations: Default::default(),
 3883                buffers_being_formatted: Default::default(),
 3884                buffer_snapshots: Default::default(),
 3885                prettier_store,
 3886                environment,
 3887                http_client,
 3888                fs,
 3889                yarn,
 3890                next_diagnostic_group_id: Default::default(),
 3891                diagnostics: Default::default(),
 3892                _subscription: cx.on_app_quit(|this, cx| {
 3893                    this.as_local_mut()
 3894                        .unwrap()
 3895                        .shutdown_language_servers_on_quit(cx)
 3896                }),
 3897                lsp_tree: LanguageServerTree::new(
 3898                    manifest_tree,
 3899                    languages.clone(),
 3900                    toolchain_store.clone(),
 3901                ),
 3902                toolchain_store,
 3903                registered_buffers: HashMap::default(),
 3904                buffers_opened_in_servers: HashMap::default(),
 3905                buffer_pull_diagnostics_result_ids: HashMap::default(),
 3906                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 3907                    .manifest_file_names(),
 3908            }),
 3909            last_formatting_failure: None,
 3910            downstream_client: None,
 3911            buffer_store,
 3912            worktree_store,
 3913            languages: languages.clone(),
 3914            language_server_statuses: Default::default(),
 3915            nonce: StdRng::from_os_rng().random(),
 3916            diagnostic_summaries: HashMap::default(),
 3917            lsp_server_capabilities: HashMap::default(),
 3918            lsp_data: HashMap::default(),
 3919            next_hint_id: Arc::default(),
 3920            active_entry: None,
 3921            _maintain_workspace_config,
 3922            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 3923        }
 3924    }
 3925
 3926    fn send_lsp_proto_request<R: LspCommand>(
 3927        &self,
 3928        buffer: Entity<Buffer>,
 3929        client: AnyProtoClient,
 3930        upstream_project_id: u64,
 3931        request: R,
 3932        cx: &mut Context<LspStore>,
 3933    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 3934        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 3935            return Task::ready(Ok(R::Response::default()));
 3936        }
 3937        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 3938        cx.spawn(async move |this, cx| {
 3939            let response = client.request(message).await?;
 3940            let this = this.upgrade().context("project dropped")?;
 3941            request
 3942                .response_from_proto(response, this, buffer, cx.clone())
 3943                .await
 3944        })
 3945    }
 3946
 3947    pub(super) fn new_remote(
 3948        buffer_store: Entity<BufferStore>,
 3949        worktree_store: Entity<WorktreeStore>,
 3950        languages: Arc<LanguageRegistry>,
 3951        upstream_client: AnyProtoClient,
 3952        project_id: u64,
 3953        cx: &mut Context<Self>,
 3954    ) -> Self {
 3955        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3956            .detach();
 3957        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3958            .detach();
 3959        subscribe_to_binary_statuses(&languages, cx).detach();
 3960        let _maintain_workspace_config = {
 3961            let (sender, receiver) = watch::channel();
 3962            (Self::maintain_workspace_config(receiver, cx), sender)
 3963        };
 3964        Self {
 3965            mode: LspStoreMode::Remote(RemoteLspStore {
 3966                upstream_client: Some(upstream_client),
 3967                upstream_project_id: project_id,
 3968            }),
 3969            downstream_client: None,
 3970            last_formatting_failure: None,
 3971            buffer_store,
 3972            worktree_store,
 3973            languages: languages.clone(),
 3974            language_server_statuses: Default::default(),
 3975            nonce: StdRng::from_os_rng().random(),
 3976            diagnostic_summaries: HashMap::default(),
 3977            lsp_server_capabilities: HashMap::default(),
 3978            next_hint_id: Arc::default(),
 3979            lsp_data: HashMap::default(),
 3980            active_entry: None,
 3981
 3982            _maintain_workspace_config,
 3983            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 3984        }
 3985    }
 3986
 3987    fn on_buffer_store_event(
 3988        &mut self,
 3989        _: Entity<BufferStore>,
 3990        event: &BufferStoreEvent,
 3991        cx: &mut Context<Self>,
 3992    ) {
 3993        match event {
 3994            BufferStoreEvent::BufferAdded(buffer) => {
 3995                self.on_buffer_added(buffer, cx).log_err();
 3996            }
 3997            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 3998                let buffer_id = buffer.read(cx).remote_id();
 3999                if let Some(local) = self.as_local_mut()
 4000                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4001                {
 4002                    local.reset_buffer(buffer, old_file, cx);
 4003
 4004                    if local.registered_buffers.contains_key(&buffer_id) {
 4005                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4006                    }
 4007                }
 4008
 4009                self.detect_language_for_buffer(buffer, cx);
 4010                if let Some(local) = self.as_local_mut() {
 4011                    local.initialize_buffer(buffer, cx);
 4012                    if local.registered_buffers.contains_key(&buffer_id) {
 4013                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4014                    }
 4015                }
 4016            }
 4017            _ => {}
 4018        }
 4019    }
 4020
 4021    fn on_worktree_store_event(
 4022        &mut self,
 4023        _: Entity<WorktreeStore>,
 4024        event: &WorktreeStoreEvent,
 4025        cx: &mut Context<Self>,
 4026    ) {
 4027        match event {
 4028            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4029                if !worktree.read(cx).is_local() {
 4030                    return;
 4031                }
 4032                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4033                    worktree::Event::UpdatedEntries(changes) => {
 4034                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4035                    }
 4036                    worktree::Event::UpdatedGitRepositories(_)
 4037                    | worktree::Event::DeletedEntry(_) => {}
 4038                })
 4039                .detach()
 4040            }
 4041            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4042            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4043                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4044            }
 4045            WorktreeStoreEvent::WorktreeReleased(..)
 4046            | WorktreeStoreEvent::WorktreeOrderChanged
 4047            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4048            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4049            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4050        }
 4051    }
 4052
 4053    fn on_prettier_store_event(
 4054        &mut self,
 4055        _: Entity<PrettierStore>,
 4056        event: &PrettierStoreEvent,
 4057        cx: &mut Context<Self>,
 4058    ) {
 4059        match event {
 4060            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4061                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4062            }
 4063            PrettierStoreEvent::LanguageServerAdded {
 4064                new_server_id,
 4065                name,
 4066                prettier_server,
 4067            } => {
 4068                self.register_supplementary_language_server(
 4069                    *new_server_id,
 4070                    name.clone(),
 4071                    prettier_server.clone(),
 4072                    cx,
 4073                );
 4074            }
 4075        }
 4076    }
 4077
 4078    fn on_toolchain_store_event(
 4079        &mut self,
 4080        _: Entity<LocalToolchainStore>,
 4081        event: &ToolchainStoreEvent,
 4082        _: &mut Context<Self>,
 4083    ) {
 4084        if let ToolchainStoreEvent::ToolchainActivated = event {
 4085            self.request_workspace_config_refresh()
 4086        }
 4087    }
 4088
 4089    fn request_workspace_config_refresh(&mut self) {
 4090        *self._maintain_workspace_config.1.borrow_mut() = ();
 4091    }
 4092
 4093    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4094        self.as_local().map(|local| local.prettier_store.clone())
 4095    }
 4096
 4097    fn on_buffer_event(
 4098        &mut self,
 4099        buffer: Entity<Buffer>,
 4100        event: &language::BufferEvent,
 4101        cx: &mut Context<Self>,
 4102    ) {
 4103        match event {
 4104            language::BufferEvent::Edited => {
 4105                self.on_buffer_edited(buffer, cx);
 4106            }
 4107
 4108            language::BufferEvent::Saved => {
 4109                self.on_buffer_saved(buffer, cx);
 4110            }
 4111
 4112            _ => {}
 4113        }
 4114    }
 4115
 4116    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4117        buffer
 4118            .read(cx)
 4119            .set_language_registry(self.languages.clone());
 4120
 4121        cx.subscribe(buffer, |this, buffer, event, cx| {
 4122            this.on_buffer_event(buffer, event, cx);
 4123        })
 4124        .detach();
 4125
 4126        self.detect_language_for_buffer(buffer, cx);
 4127        if let Some(local) = self.as_local_mut() {
 4128            local.initialize_buffer(buffer, cx);
 4129        }
 4130
 4131        Ok(())
 4132    }
 4133
 4134    pub(crate) fn register_buffer_with_language_servers(
 4135        &mut self,
 4136        buffer: &Entity<Buffer>,
 4137        only_register_servers: HashSet<LanguageServerSelector>,
 4138        ignore_refcounts: bool,
 4139        cx: &mut Context<Self>,
 4140    ) -> OpenLspBufferHandle {
 4141        let buffer_id = buffer.read(cx).remote_id();
 4142        let handle = cx.new(|_| buffer.clone());
 4143        if let Some(local) = self.as_local_mut() {
 4144            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4145            if !ignore_refcounts {
 4146                *refcount += 1;
 4147            }
 4148
 4149            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4150            // 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
 4151            // 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
 4152            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4153            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4154                return handle;
 4155            };
 4156            if !file.is_local() {
 4157                return handle;
 4158            }
 4159
 4160            if ignore_refcounts || *refcount == 1 {
 4161                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4162            }
 4163            if !ignore_refcounts {
 4164                cx.observe_release(&handle, move |lsp_store, buffer, cx| {
 4165                    let refcount = {
 4166                        let local = lsp_store.as_local_mut().unwrap();
 4167                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4168                            debug_panic!("bad refcounting");
 4169                            return;
 4170                        };
 4171
 4172                        *refcount -= 1;
 4173                        *refcount
 4174                    };
 4175                    if refcount == 0 {
 4176                        lsp_store.lsp_data.remove(&buffer_id);
 4177                        let local = lsp_store.as_local_mut().unwrap();
 4178                        local.registered_buffers.remove(&buffer_id);
 4179                        local.buffers_opened_in_servers.remove(&buffer_id);
 4180                        if let Some(file) = File::from_dyn(buffer.read(cx).file()).cloned() {
 4181                            local.unregister_old_buffer_from_language_servers(buffer, &file, cx);
 4182                        }
 4183                    }
 4184                })
 4185                .detach();
 4186            }
 4187        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4188            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4189            cx.background_spawn(async move {
 4190                upstream_client
 4191                    .request(proto::RegisterBufferWithLanguageServers {
 4192                        project_id: upstream_project_id,
 4193                        buffer_id,
 4194                        only_servers: only_register_servers
 4195                            .into_iter()
 4196                            .map(|selector| {
 4197                                let selector = match selector {
 4198                                    LanguageServerSelector::Id(language_server_id) => {
 4199                                        proto::language_server_selector::Selector::ServerId(
 4200                                            language_server_id.to_proto(),
 4201                                        )
 4202                                    }
 4203                                    LanguageServerSelector::Name(language_server_name) => {
 4204                                        proto::language_server_selector::Selector::Name(
 4205                                            language_server_name.to_string(),
 4206                                        )
 4207                                    }
 4208                                };
 4209                                proto::LanguageServerSelector {
 4210                                    selector: Some(selector),
 4211                                }
 4212                            })
 4213                            .collect(),
 4214                    })
 4215                    .await
 4216            })
 4217            .detach();
 4218        } else {
 4219            // Our remote connection got closed
 4220        }
 4221        handle
 4222    }
 4223
 4224    fn maintain_buffer_languages(
 4225        languages: Arc<LanguageRegistry>,
 4226        cx: &mut Context<Self>,
 4227    ) -> Task<()> {
 4228        let mut subscription = languages.subscribe();
 4229        let mut prev_reload_count = languages.reload_count();
 4230        cx.spawn(async move |this, cx| {
 4231            while let Some(()) = subscription.next().await {
 4232                if let Some(this) = this.upgrade() {
 4233                    // If the language registry has been reloaded, then remove and
 4234                    // re-assign the languages on all open buffers.
 4235                    let reload_count = languages.reload_count();
 4236                    if reload_count > prev_reload_count {
 4237                        prev_reload_count = reload_count;
 4238                        this.update(cx, |this, cx| {
 4239                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4240                                for buffer in buffer_store.buffers() {
 4241                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4242                                    {
 4243                                        buffer
 4244                                            .update(cx, |buffer, cx| buffer.set_language(None, cx));
 4245                                        if let Some(local) = this.as_local_mut() {
 4246                                            local.reset_buffer(&buffer, &f, cx);
 4247
 4248                                            if local
 4249                                                .registered_buffers
 4250                                                .contains_key(&buffer.read(cx).remote_id())
 4251                                                && let Some(file_url) =
 4252                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4253                                            {
 4254                                                local.unregister_buffer_from_language_servers(
 4255                                                    &buffer, &file_url, cx,
 4256                                                );
 4257                                            }
 4258                                        }
 4259                                    }
 4260                                }
 4261                            });
 4262                        })
 4263                        .ok();
 4264                    }
 4265
 4266                    this.update(cx, |this, cx| {
 4267                        let mut plain_text_buffers = Vec::new();
 4268                        let mut buffers_with_unknown_injections = Vec::new();
 4269                        for handle in this.buffer_store.read(cx).buffers() {
 4270                            let buffer = handle.read(cx);
 4271                            if buffer.language().is_none()
 4272                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4273                            {
 4274                                plain_text_buffers.push(handle);
 4275                            } else if buffer.contains_unknown_injections() {
 4276                                buffers_with_unknown_injections.push(handle);
 4277                            }
 4278                        }
 4279
 4280                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4281                        // and reused later in the invisible worktrees.
 4282                        plain_text_buffers.sort_by_key(|buffer| {
 4283                            Reverse(
 4284                                File::from_dyn(buffer.read(cx).file())
 4285                                    .map(|file| file.worktree.read(cx).is_visible()),
 4286                            )
 4287                        });
 4288
 4289                        for buffer in plain_text_buffers {
 4290                            this.detect_language_for_buffer(&buffer, cx);
 4291                            if let Some(local) = this.as_local_mut() {
 4292                                local.initialize_buffer(&buffer, cx);
 4293                                if local
 4294                                    .registered_buffers
 4295                                    .contains_key(&buffer.read(cx).remote_id())
 4296                                {
 4297                                    local.register_buffer_with_language_servers(
 4298                                        &buffer,
 4299                                        HashSet::default(),
 4300                                        cx,
 4301                                    );
 4302                                }
 4303                            }
 4304                        }
 4305
 4306                        for buffer in buffers_with_unknown_injections {
 4307                            buffer.update(cx, |buffer, cx| buffer.reparse(cx));
 4308                        }
 4309                    })
 4310                    .ok();
 4311                }
 4312            }
 4313        })
 4314    }
 4315
 4316    fn detect_language_for_buffer(
 4317        &mut self,
 4318        buffer_handle: &Entity<Buffer>,
 4319        cx: &mut Context<Self>,
 4320    ) -> Option<language::AvailableLanguage> {
 4321        // If the buffer has a language, set it and start the language server if we haven't already.
 4322        let buffer = buffer_handle.read(cx);
 4323        let file = buffer.file()?;
 4324
 4325        let content = buffer.as_rope();
 4326        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4327        if let Some(available_language) = &available_language {
 4328            if let Some(Ok(Ok(new_language))) = self
 4329                .languages
 4330                .load_language(available_language)
 4331                .now_or_never()
 4332            {
 4333                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4334            }
 4335        } else {
 4336            cx.emit(LspStoreEvent::LanguageDetected {
 4337                buffer: buffer_handle.clone(),
 4338                new_language: None,
 4339            });
 4340        }
 4341
 4342        available_language
 4343    }
 4344
 4345    pub(crate) fn set_language_for_buffer(
 4346        &mut self,
 4347        buffer_entity: &Entity<Buffer>,
 4348        new_language: Arc<Language>,
 4349        cx: &mut Context<Self>,
 4350    ) {
 4351        let buffer = buffer_entity.read(cx);
 4352        let buffer_file = buffer.file().cloned();
 4353        let buffer_id = buffer.remote_id();
 4354        if let Some(local_store) = self.as_local_mut()
 4355            && local_store.registered_buffers.contains_key(&buffer_id)
 4356            && let Some(abs_path) =
 4357                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4358            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4359        {
 4360            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4361        }
 4362        buffer_entity.update(cx, |buffer, cx| {
 4363            if buffer
 4364                .language()
 4365                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4366            {
 4367                buffer.set_language(Some(new_language.clone()), cx);
 4368            }
 4369        });
 4370
 4371        let settings =
 4372            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4373        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4374
 4375        let worktree_id = if let Some(file) = buffer_file {
 4376            let worktree = file.worktree.clone();
 4377
 4378            if let Some(local) = self.as_local_mut()
 4379                && local.registered_buffers.contains_key(&buffer_id)
 4380            {
 4381                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4382            }
 4383            Some(worktree.read(cx).id())
 4384        } else {
 4385            None
 4386        };
 4387
 4388        if settings.prettier.allowed
 4389            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4390        {
 4391            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4392            if let Some(prettier_store) = prettier_store {
 4393                prettier_store.update(cx, |prettier_store, cx| {
 4394                    prettier_store.install_default_prettier(
 4395                        worktree_id,
 4396                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4397                        cx,
 4398                    )
 4399                })
 4400            }
 4401        }
 4402
 4403        cx.emit(LspStoreEvent::LanguageDetected {
 4404            buffer: buffer_entity.clone(),
 4405            new_language: Some(new_language),
 4406        })
 4407    }
 4408
 4409    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4410        self.buffer_store.clone()
 4411    }
 4412
 4413    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4414        self.active_entry = active_entry;
 4415    }
 4416
 4417    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4418        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4419            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4420        {
 4421            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4422                summaries
 4423                    .iter()
 4424                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4425            });
 4426            if let Some(summary) = summaries.next() {
 4427                client
 4428                    .send(proto::UpdateDiagnosticSummary {
 4429                        project_id: downstream_project_id,
 4430                        worktree_id: worktree.id().to_proto(),
 4431                        summary: Some(summary),
 4432                        more_summaries: summaries.collect(),
 4433                    })
 4434                    .log_err();
 4435            }
 4436        }
 4437    }
 4438
 4439    fn is_capable_for_proto_request<R>(
 4440        &self,
 4441        buffer: &Entity<Buffer>,
 4442        request: &R,
 4443        cx: &App,
 4444    ) -> bool
 4445    where
 4446        R: LspCommand,
 4447    {
 4448        self.check_if_capable_for_proto_request(
 4449            buffer,
 4450            |capabilities| {
 4451                request.check_capabilities(AdapterServerCapabilities {
 4452                    server_capabilities: capabilities.clone(),
 4453                    code_action_kinds: None,
 4454                })
 4455            },
 4456            cx,
 4457        )
 4458    }
 4459
 4460    fn check_if_capable_for_proto_request<F>(
 4461        &self,
 4462        buffer: &Entity<Buffer>,
 4463        check: F,
 4464        cx: &App,
 4465    ) -> bool
 4466    where
 4467        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4468    {
 4469        let Some(language) = buffer.read(cx).language().cloned() else {
 4470            return false;
 4471        };
 4472        let relevant_language_servers = self
 4473            .languages
 4474            .lsp_adapters(&language.name())
 4475            .into_iter()
 4476            .map(|lsp_adapter| lsp_adapter.name())
 4477            .collect::<HashSet<_>>();
 4478        self.language_server_statuses
 4479            .iter()
 4480            .filter_map(|(server_id, server_status)| {
 4481                relevant_language_servers
 4482                    .contains(&server_status.name)
 4483                    .then_some(server_id)
 4484            })
 4485            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4486            .any(check)
 4487    }
 4488
 4489    fn all_capable_for_proto_request<F>(
 4490        &self,
 4491        buffer: &Entity<Buffer>,
 4492        mut check: F,
 4493        cx: &App,
 4494    ) -> Vec<lsp::LanguageServerId>
 4495    where
 4496        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4497    {
 4498        let Some(language) = buffer.read(cx).language().cloned() else {
 4499            return Vec::default();
 4500        };
 4501        let relevant_language_servers = self
 4502            .languages
 4503            .lsp_adapters(&language.name())
 4504            .into_iter()
 4505            .map(|lsp_adapter| lsp_adapter.name())
 4506            .collect::<HashSet<_>>();
 4507        self.language_server_statuses
 4508            .iter()
 4509            .filter_map(|(server_id, server_status)| {
 4510                relevant_language_servers
 4511                    .contains(&server_status.name)
 4512                    .then_some((server_id, &server_status.name))
 4513            })
 4514            .filter_map(|(server_id, server_name)| {
 4515                self.lsp_server_capabilities
 4516                    .get(server_id)
 4517                    .map(|c| (server_id, server_name, c))
 4518            })
 4519            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4520            .map(|(server_id, _, _)| *server_id)
 4521            .collect()
 4522    }
 4523
 4524    pub fn request_lsp<R>(
 4525        &mut self,
 4526        buffer: Entity<Buffer>,
 4527        server: LanguageServerToQuery,
 4528        request: R,
 4529        cx: &mut Context<Self>,
 4530    ) -> Task<Result<R::Response>>
 4531    where
 4532        R: LspCommand,
 4533        <R::LspRequest as lsp::request::Request>::Result: Send,
 4534        <R::LspRequest as lsp::request::Request>::Params: Send,
 4535    {
 4536        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4537            return self.send_lsp_proto_request(
 4538                buffer,
 4539                upstream_client,
 4540                upstream_project_id,
 4541                request,
 4542                cx,
 4543            );
 4544        }
 4545
 4546        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4547            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4548                local
 4549                    .language_servers_for_buffer(buffer, cx)
 4550                    .find(|(_, server)| {
 4551                        request.check_capabilities(server.adapter_server_capabilities())
 4552                    })
 4553                    .map(|(_, server)| server.clone())
 4554            }),
 4555            LanguageServerToQuery::Other(id) => self
 4556                .language_server_for_local_buffer(buffer, id, cx)
 4557                .and_then(|(_, server)| {
 4558                    request
 4559                        .check_capabilities(server.adapter_server_capabilities())
 4560                        .then(|| Arc::clone(server))
 4561                }),
 4562        }) else {
 4563            return Task::ready(Ok(Default::default()));
 4564        };
 4565
 4566        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4567
 4568        let Some(file) = file else {
 4569            return Task::ready(Ok(Default::default()));
 4570        };
 4571
 4572        let lsp_params = match request.to_lsp_params_or_response(
 4573            &file.abs_path(cx),
 4574            buffer.read(cx),
 4575            &language_server,
 4576            cx,
 4577        ) {
 4578            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4579            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4580            Err(err) => {
 4581                let message = format!(
 4582                    "{} via {} failed: {}",
 4583                    request.display_name(),
 4584                    language_server.name(),
 4585                    err
 4586                );
 4587                // rust-analyzer likes to error with this when its still loading up
 4588                if !message.ends_with("content modified") {
 4589                    log::warn!("{message}");
 4590                }
 4591                return Task::ready(Err(anyhow!(message)));
 4592            }
 4593        };
 4594
 4595        let status = request.status();
 4596        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4597            return Task::ready(Ok(Default::default()));
 4598        }
 4599        cx.spawn(async move |this, cx| {
 4600            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4601
 4602            let id = lsp_request.id();
 4603            let _cleanup = if status.is_some() {
 4604                cx.update(|cx| {
 4605                    this.update(cx, |this, cx| {
 4606                        this.on_lsp_work_start(
 4607                            language_server.server_id(),
 4608                            ProgressToken::Number(id),
 4609                            LanguageServerProgress {
 4610                                is_disk_based_diagnostics_progress: false,
 4611                                is_cancellable: false,
 4612                                title: None,
 4613                                message: status.clone(),
 4614                                percentage: None,
 4615                                last_update_at: cx.background_executor().now(),
 4616                            },
 4617                            cx,
 4618                        );
 4619                    })
 4620                })
 4621                .log_err();
 4622
 4623                Some(defer(|| {
 4624                    cx.update(|cx| {
 4625                        this.update(cx, |this, cx| {
 4626                            this.on_lsp_work_end(
 4627                                language_server.server_id(),
 4628                                ProgressToken::Number(id),
 4629                                cx,
 4630                            );
 4631                        })
 4632                    })
 4633                    .log_err();
 4634                }))
 4635            } else {
 4636                None
 4637            };
 4638
 4639            let result = lsp_request.await.into_response();
 4640
 4641            let response = result.map_err(|err| {
 4642                let message = format!(
 4643                    "{} via {} failed: {}",
 4644                    request.display_name(),
 4645                    language_server.name(),
 4646                    err
 4647                );
 4648                // rust-analyzer likes to error with this when its still loading up
 4649                if !message.ends_with("content modified") {
 4650                    log::warn!("{message}");
 4651                }
 4652                anyhow::anyhow!(message)
 4653            })?;
 4654
 4655            request
 4656                .response_from_lsp(
 4657                    response,
 4658                    this.upgrade().context("no app context")?,
 4659                    buffer,
 4660                    language_server.server_id(),
 4661                    cx.clone(),
 4662                )
 4663                .await
 4664        })
 4665    }
 4666
 4667    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4668        let mut language_formatters_to_check = Vec::new();
 4669        for buffer in self.buffer_store.read(cx).buffers() {
 4670            let buffer = buffer.read(cx);
 4671            let buffer_file = File::from_dyn(buffer.file());
 4672            let buffer_language = buffer.language();
 4673            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4674            if buffer_language.is_some() {
 4675                language_formatters_to_check.push((
 4676                    buffer_file.map(|f| f.worktree_id(cx)),
 4677                    settings.into_owned(),
 4678                ));
 4679            }
 4680        }
 4681
 4682        self.request_workspace_config_refresh();
 4683
 4684        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4685            prettier_store.update(cx, |prettier_store, cx| {
 4686                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4687            })
 4688        }
 4689
 4690        cx.notify();
 4691    }
 4692
 4693    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4694        let buffer_store = self.buffer_store.clone();
 4695        let Some(local) = self.as_local_mut() else {
 4696            return;
 4697        };
 4698        let mut adapters = BTreeMap::default();
 4699        let get_adapter = {
 4700            let languages = local.languages.clone();
 4701            let environment = local.environment.clone();
 4702            let weak = local.weak.clone();
 4703            let worktree_store = local.worktree_store.clone();
 4704            let http_client = local.http_client.clone();
 4705            let fs = local.fs.clone();
 4706            move |worktree_id, cx: &mut App| {
 4707                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4708                Some(LocalLspAdapterDelegate::new(
 4709                    languages.clone(),
 4710                    &environment,
 4711                    weak.clone(),
 4712                    &worktree,
 4713                    http_client.clone(),
 4714                    fs.clone(),
 4715                    cx,
 4716                ))
 4717            }
 4718        };
 4719
 4720        let mut messages_to_report = Vec::new();
 4721        let (new_tree, to_stop) = {
 4722            let mut rebase = local.lsp_tree.rebase();
 4723            let buffers = buffer_store
 4724                .read(cx)
 4725                .buffers()
 4726                .filter_map(|buffer| {
 4727                    let raw_buffer = buffer.read(cx);
 4728                    if !local
 4729                        .registered_buffers
 4730                        .contains_key(&raw_buffer.remote_id())
 4731                    {
 4732                        return None;
 4733                    }
 4734                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4735                    let language = raw_buffer.language().cloned()?;
 4736                    Some((file, language, raw_buffer.remote_id()))
 4737                })
 4738                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4739            for (file, language, buffer_id) in buffers {
 4740                let worktree_id = file.worktree_id(cx);
 4741                let Some(worktree) = local
 4742                    .worktree_store
 4743                    .read(cx)
 4744                    .worktree_for_id(worktree_id, cx)
 4745                else {
 4746                    continue;
 4747                };
 4748
 4749                if let Some((_, apply)) = local.reuse_existing_language_server(
 4750                    rebase.server_tree(),
 4751                    &worktree,
 4752                    &language.name(),
 4753                    cx,
 4754                ) {
 4755                    (apply)(rebase.server_tree());
 4756                } else if let Some(lsp_delegate) = adapters
 4757                    .entry(worktree_id)
 4758                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4759                    .clone()
 4760                {
 4761                    let delegate =
 4762                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4763                    let path = file
 4764                        .path()
 4765                        .parent()
 4766                        .map(Arc::from)
 4767                        .unwrap_or_else(|| file.path().clone());
 4768                    let worktree_path = ProjectPath { worktree_id, path };
 4769                    let abs_path = file.abs_path(cx);
 4770                    let nodes = rebase
 4771                        .walk(
 4772                            worktree_path,
 4773                            language.name(),
 4774                            language.manifest(),
 4775                            delegate.clone(),
 4776                            cx,
 4777                        )
 4778                        .collect::<Vec<_>>();
 4779                    for node in nodes {
 4780                        let server_id = node.server_id_or_init(|disposition| {
 4781                            let path = &disposition.path;
 4782                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 4783                            let key = LanguageServerSeed {
 4784                                worktree_id,
 4785                                name: disposition.server_name.clone(),
 4786                                settings: disposition.settings.clone(),
 4787                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4788                                    path.worktree_id,
 4789                                    &path.path,
 4790                                    language.name(),
 4791                                ),
 4792                            };
 4793                            local.language_server_ids.remove(&key);
 4794
 4795                            let server_id = local.get_or_insert_language_server(
 4796                                &worktree,
 4797                                lsp_delegate.clone(),
 4798                                disposition,
 4799                                &language.name(),
 4800                                cx,
 4801                            );
 4802                            if let Some(state) = local.language_servers.get(&server_id)
 4803                                && let Ok(uri) = uri
 4804                            {
 4805                                state.add_workspace_folder(uri);
 4806                            };
 4807                            server_id
 4808                        });
 4809
 4810                        if let Some(language_server_id) = server_id {
 4811                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 4812                                language_server_id,
 4813                                name: node.name(),
 4814                                message:
 4815                                    proto::update_language_server::Variant::RegisteredForBuffer(
 4816                                        proto::RegisteredForBuffer {
 4817                                            buffer_abs_path: abs_path
 4818                                                .to_string_lossy()
 4819                                                .into_owned(),
 4820                                            buffer_id: buffer_id.to_proto(),
 4821                                        },
 4822                                    ),
 4823                            });
 4824                        }
 4825                    }
 4826                } else {
 4827                    continue;
 4828                }
 4829            }
 4830            rebase.finish()
 4831        };
 4832        for message in messages_to_report {
 4833            cx.emit(message);
 4834        }
 4835        local.lsp_tree = new_tree;
 4836        for (id, _) in to_stop {
 4837            self.stop_local_language_server(id, cx).detach();
 4838        }
 4839    }
 4840
 4841    pub fn apply_code_action(
 4842        &self,
 4843        buffer_handle: Entity<Buffer>,
 4844        mut action: CodeAction,
 4845        push_to_history: bool,
 4846        cx: &mut Context<Self>,
 4847    ) -> Task<Result<ProjectTransaction>> {
 4848        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4849            let request = proto::ApplyCodeAction {
 4850                project_id,
 4851                buffer_id: buffer_handle.read(cx).remote_id().into(),
 4852                action: Some(Self::serialize_code_action(&action)),
 4853            };
 4854            let buffer_store = self.buffer_store();
 4855            cx.spawn(async move |_, cx| {
 4856                let response = upstream_client
 4857                    .request(request)
 4858                    .await?
 4859                    .transaction
 4860                    .context("missing transaction")?;
 4861
 4862                buffer_store
 4863                    .update(cx, |buffer_store, cx| {
 4864                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 4865                    })?
 4866                    .await
 4867            })
 4868        } else if self.mode.is_local() {
 4869            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 4870                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 4871                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 4872            }) else {
 4873                return Task::ready(Ok(ProjectTransaction::default()));
 4874            };
 4875            cx.spawn(async move |this,  cx| {
 4876                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 4877                    .await
 4878                    .context("resolving a code action")?;
 4879                if let Some(edit) = action.lsp_action.edit()
 4880                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 4881                        return LocalLspStore::deserialize_workspace_edit(
 4882                            this.upgrade().context("no app present")?,
 4883                            edit.clone(),
 4884                            push_to_history,
 4885
 4886                            lang_server.clone(),
 4887                            cx,
 4888                        )
 4889                        .await;
 4890                    }
 4891
 4892                if let Some(command) = action.lsp_action.command() {
 4893                    let server_capabilities = lang_server.capabilities();
 4894                    let available_commands = server_capabilities
 4895                        .execute_command_provider
 4896                        .as_ref()
 4897                        .map(|options| options.commands.as_slice())
 4898                        .unwrap_or_default();
 4899                    if available_commands.contains(&command.command) {
 4900                        this.update(cx, |this, _| {
 4901                            this.as_local_mut()
 4902                                .unwrap()
 4903                                .last_workspace_edits_by_language_server
 4904                                .remove(&lang_server.server_id());
 4905                        })?;
 4906
 4907                        let _result = lang_server
 4908                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 4909                                command: command.command.clone(),
 4910                                arguments: command.arguments.clone().unwrap_or_default(),
 4911                                ..lsp::ExecuteCommandParams::default()
 4912                            })
 4913                            .await.into_response()
 4914                            .context("execute command")?;
 4915
 4916                        return this.update(cx, |this, _| {
 4917                            this.as_local_mut()
 4918                                .unwrap()
 4919                                .last_workspace_edits_by_language_server
 4920                                .remove(&lang_server.server_id())
 4921                                .unwrap_or_default()
 4922                        });
 4923                    } else {
 4924                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 4925                    }
 4926                }
 4927
 4928                Ok(ProjectTransaction::default())
 4929            })
 4930        } else {
 4931            Task::ready(Err(anyhow!("no upstream client and not local")))
 4932        }
 4933    }
 4934
 4935    pub fn apply_code_action_kind(
 4936        &mut self,
 4937        buffers: HashSet<Entity<Buffer>>,
 4938        kind: CodeActionKind,
 4939        push_to_history: bool,
 4940        cx: &mut Context<Self>,
 4941    ) -> Task<anyhow::Result<ProjectTransaction>> {
 4942        if self.as_local().is_some() {
 4943            cx.spawn(async move |lsp_store, cx| {
 4944                let buffers = buffers.into_iter().collect::<Vec<_>>();
 4945                let result = LocalLspStore::execute_code_action_kind_locally(
 4946                    lsp_store.clone(),
 4947                    buffers,
 4948                    kind,
 4949                    push_to_history,
 4950                    cx,
 4951                )
 4952                .await;
 4953                lsp_store.update(cx, |lsp_store, _| {
 4954                    lsp_store.update_last_formatting_failure(&result);
 4955                })?;
 4956                result
 4957            })
 4958        } else if let Some((client, project_id)) = self.upstream_client() {
 4959            let buffer_store = self.buffer_store();
 4960            cx.spawn(async move |lsp_store, cx| {
 4961                let result = client
 4962                    .request(proto::ApplyCodeActionKind {
 4963                        project_id,
 4964                        kind: kind.as_str().to_owned(),
 4965                        buffer_ids: buffers
 4966                            .iter()
 4967                            .map(|buffer| {
 4968                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 4969                            })
 4970                            .collect::<Result<_>>()?,
 4971                    })
 4972                    .await
 4973                    .and_then(|result| result.transaction.context("missing transaction"));
 4974                lsp_store.update(cx, |lsp_store, _| {
 4975                    lsp_store.update_last_formatting_failure(&result);
 4976                })?;
 4977
 4978                let transaction_response = result?;
 4979                buffer_store
 4980                    .update(cx, |buffer_store, cx| {
 4981                        buffer_store.deserialize_project_transaction(
 4982                            transaction_response,
 4983                            push_to_history,
 4984                            cx,
 4985                        )
 4986                    })?
 4987                    .await
 4988            })
 4989        } else {
 4990            Task::ready(Ok(ProjectTransaction::default()))
 4991        }
 4992    }
 4993
 4994    pub fn resolved_hint(
 4995        &mut self,
 4996        buffer_id: BufferId,
 4997        id: InlayId,
 4998        cx: &mut Context<Self>,
 4999    ) -> Option<ResolvedHint> {
 5000        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5001
 5002        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5003        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5004        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5005        let (server_id, resolve_data) = match &hint.resolve_state {
 5006            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5007            ResolveState::Resolving => {
 5008                return Some(ResolvedHint::Resolving(
 5009                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5010                ));
 5011            }
 5012            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5013        };
 5014
 5015        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5016        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5017        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5018            id,
 5019            cx.spawn(async move |lsp_store, cx| {
 5020                let resolved_hint = resolve_task.await;
 5021                lsp_store
 5022                    .update(cx, |lsp_store, _| {
 5023                        if let Some(old_inlay_hint) = lsp_store
 5024                            .lsp_data
 5025                            .get_mut(&buffer_id)
 5026                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5027                        {
 5028                            match resolved_hint {
 5029                                Ok(resolved_hint) => {
 5030                                    *old_inlay_hint = resolved_hint;
 5031                                }
 5032                                Err(e) => {
 5033                                    old_inlay_hint.resolve_state =
 5034                                        ResolveState::CanResolve(server_id, resolve_data);
 5035                                    log::error!("Inlay hint resolve failed: {e:#}");
 5036                                }
 5037                            }
 5038                        }
 5039                    })
 5040                    .ok();
 5041            })
 5042            .shared(),
 5043        );
 5044        debug_assert!(
 5045            previous_task.is_none(),
 5046            "Did not change hint's resolve state after spawning its resolve"
 5047        );
 5048        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5049        None
 5050    }
 5051
 5052    fn resolve_inlay_hint(
 5053        &self,
 5054        mut hint: InlayHint,
 5055        buffer: Entity<Buffer>,
 5056        server_id: LanguageServerId,
 5057        cx: &mut Context<Self>,
 5058    ) -> Task<anyhow::Result<InlayHint>> {
 5059        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5060            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 5061            {
 5062                hint.resolve_state = ResolveState::Resolved;
 5063                return Task::ready(Ok(hint));
 5064            }
 5065            let request = proto::ResolveInlayHint {
 5066                project_id,
 5067                buffer_id: buffer.read(cx).remote_id().into(),
 5068                language_server_id: server_id.0 as u64,
 5069                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 5070            };
 5071            cx.background_spawn(async move {
 5072                let response = upstream_client
 5073                    .request(request)
 5074                    .await
 5075                    .context("inlay hints proto request")?;
 5076                match response.hint {
 5077                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5078                        .context("inlay hints proto resolve response conversion"),
 5079                    None => Ok(hint),
 5080                }
 5081            })
 5082        } else {
 5083            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5084                self.language_server_for_local_buffer(buffer, server_id, cx)
 5085                    .map(|(_, server)| server.clone())
 5086            }) else {
 5087                return Task::ready(Ok(hint));
 5088            };
 5089            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5090                return Task::ready(Ok(hint));
 5091            }
 5092            let buffer_snapshot = buffer.read(cx).snapshot();
 5093            cx.spawn(async move |_, cx| {
 5094                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5095                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5096                );
 5097                let resolved_hint = resolve_task
 5098                    .await
 5099                    .into_response()
 5100                    .context("inlay hint resolve LSP request")?;
 5101                let resolved_hint = InlayHints::lsp_to_project_hint(
 5102                    resolved_hint,
 5103                    &buffer,
 5104                    server_id,
 5105                    ResolveState::Resolved,
 5106                    false,
 5107                    cx,
 5108                )
 5109                .await?;
 5110                Ok(resolved_hint)
 5111            })
 5112        }
 5113    }
 5114
 5115    pub fn resolve_color_presentation(
 5116        &mut self,
 5117        mut color: DocumentColor,
 5118        buffer: Entity<Buffer>,
 5119        server_id: LanguageServerId,
 5120        cx: &mut Context<Self>,
 5121    ) -> Task<Result<DocumentColor>> {
 5122        if color.resolved {
 5123            return Task::ready(Ok(color));
 5124        }
 5125
 5126        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5127            let start = color.lsp_range.start;
 5128            let end = color.lsp_range.end;
 5129            let request = proto::GetColorPresentation {
 5130                project_id,
 5131                server_id: server_id.to_proto(),
 5132                buffer_id: buffer.read(cx).remote_id().into(),
 5133                color: Some(proto::ColorInformation {
 5134                    red: color.color.red,
 5135                    green: color.color.green,
 5136                    blue: color.color.blue,
 5137                    alpha: color.color.alpha,
 5138                    lsp_range_start: Some(proto::PointUtf16 {
 5139                        row: start.line,
 5140                        column: start.character,
 5141                    }),
 5142                    lsp_range_end: Some(proto::PointUtf16 {
 5143                        row: end.line,
 5144                        column: end.character,
 5145                    }),
 5146                }),
 5147            };
 5148            cx.background_spawn(async move {
 5149                let response = upstream_client
 5150                    .request(request)
 5151                    .await
 5152                    .context("color presentation proto request")?;
 5153                color.resolved = true;
 5154                color.color_presentations = response
 5155                    .presentations
 5156                    .into_iter()
 5157                    .map(|presentation| ColorPresentation {
 5158                        label: SharedString::from(presentation.label),
 5159                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5160                        additional_text_edits: presentation
 5161                            .additional_text_edits
 5162                            .into_iter()
 5163                            .filter_map(deserialize_lsp_edit)
 5164                            .collect(),
 5165                    })
 5166                    .collect();
 5167                Ok(color)
 5168            })
 5169        } else {
 5170            let path = match buffer
 5171                .update(cx, |buffer, cx| {
 5172                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5173                })
 5174                .context("buffer with the missing path")
 5175            {
 5176                Ok(path) => path,
 5177                Err(e) => return Task::ready(Err(e)),
 5178            };
 5179            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5180                self.language_server_for_local_buffer(buffer, server_id, cx)
 5181                    .map(|(_, server)| server.clone())
 5182            }) else {
 5183                return Task::ready(Ok(color));
 5184            };
 5185            cx.background_spawn(async move {
 5186                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5187                    lsp::ColorPresentationParams {
 5188                        text_document: make_text_document_identifier(&path)?,
 5189                        color: color.color,
 5190                        range: color.lsp_range,
 5191                        work_done_progress_params: Default::default(),
 5192                        partial_result_params: Default::default(),
 5193                    },
 5194                );
 5195                color.color_presentations = resolve_task
 5196                    .await
 5197                    .into_response()
 5198                    .context("color presentation resolve LSP request")?
 5199                    .into_iter()
 5200                    .map(|presentation| ColorPresentation {
 5201                        label: SharedString::from(presentation.label),
 5202                        text_edit: presentation.text_edit,
 5203                        additional_text_edits: presentation
 5204                            .additional_text_edits
 5205                            .unwrap_or_default(),
 5206                    })
 5207                    .collect();
 5208                color.resolved = true;
 5209                Ok(color)
 5210            })
 5211        }
 5212    }
 5213
 5214    pub(crate) fn linked_edits(
 5215        &mut self,
 5216        buffer: &Entity<Buffer>,
 5217        position: Anchor,
 5218        cx: &mut Context<Self>,
 5219    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5220        let snapshot = buffer.read(cx).snapshot();
 5221        let scope = snapshot.language_scope_at(position);
 5222        let Some(server_id) = self
 5223            .as_local()
 5224            .and_then(|local| {
 5225                buffer.update(cx, |buffer, cx| {
 5226                    local
 5227                        .language_servers_for_buffer(buffer, cx)
 5228                        .filter(|(_, server)| {
 5229                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5230                        })
 5231                        .filter(|(adapter, _)| {
 5232                            scope
 5233                                .as_ref()
 5234                                .map(|scope| scope.language_allowed(&adapter.name))
 5235                                .unwrap_or(true)
 5236                        })
 5237                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5238                        .next()
 5239                })
 5240            })
 5241            .or_else(|| {
 5242                self.upstream_client()
 5243                    .is_some()
 5244                    .then_some(LanguageServerToQuery::FirstCapable)
 5245            })
 5246            .filter(|_| {
 5247                maybe!({
 5248                    let language = buffer.read(cx).language_at(position)?;
 5249                    Some(
 5250                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5251                            .linked_edits,
 5252                    )
 5253                }) == Some(true)
 5254            })
 5255        else {
 5256            return Task::ready(Ok(Vec::new()));
 5257        };
 5258
 5259        self.request_lsp(
 5260            buffer.clone(),
 5261            server_id,
 5262            LinkedEditingRange { position },
 5263            cx,
 5264        )
 5265    }
 5266
 5267    fn apply_on_type_formatting(
 5268        &mut self,
 5269        buffer: Entity<Buffer>,
 5270        position: Anchor,
 5271        trigger: String,
 5272        cx: &mut Context<Self>,
 5273    ) -> Task<Result<Option<Transaction>>> {
 5274        if let Some((client, project_id)) = self.upstream_client() {
 5275            if !self.check_if_capable_for_proto_request(
 5276                &buffer,
 5277                |capabilities| {
 5278                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5279                },
 5280                cx,
 5281            ) {
 5282                return Task::ready(Ok(None));
 5283            }
 5284            let request = proto::OnTypeFormatting {
 5285                project_id,
 5286                buffer_id: buffer.read(cx).remote_id().into(),
 5287                position: Some(serialize_anchor(&position)),
 5288                trigger,
 5289                version: serialize_version(&buffer.read(cx).version()),
 5290            };
 5291            cx.background_spawn(async move {
 5292                client
 5293                    .request(request)
 5294                    .await?
 5295                    .transaction
 5296                    .map(language::proto::deserialize_transaction)
 5297                    .transpose()
 5298            })
 5299        } else if let Some(local) = self.as_local_mut() {
 5300            let buffer_id = buffer.read(cx).remote_id();
 5301            local.buffers_being_formatted.insert(buffer_id);
 5302            cx.spawn(async move |this, cx| {
 5303                let _cleanup = defer({
 5304                    let this = this.clone();
 5305                    let mut cx = cx.clone();
 5306                    move || {
 5307                        this.update(&mut cx, |this, _| {
 5308                            if let Some(local) = this.as_local_mut() {
 5309                                local.buffers_being_formatted.remove(&buffer_id);
 5310                            }
 5311                        })
 5312                        .ok();
 5313                    }
 5314                });
 5315
 5316                buffer
 5317                    .update(cx, |buffer, _| {
 5318                        buffer.wait_for_edits(Some(position.timestamp))
 5319                    })?
 5320                    .await?;
 5321                this.update(cx, |this, cx| {
 5322                    let position = position.to_point_utf16(buffer.read(cx));
 5323                    this.on_type_format(buffer, position, trigger, false, cx)
 5324                })?
 5325                .await
 5326            })
 5327        } else {
 5328            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5329        }
 5330    }
 5331
 5332    pub fn on_type_format<T: ToPointUtf16>(
 5333        &mut self,
 5334        buffer: Entity<Buffer>,
 5335        position: T,
 5336        trigger: String,
 5337        push_to_history: bool,
 5338        cx: &mut Context<Self>,
 5339    ) -> Task<Result<Option<Transaction>>> {
 5340        let position = position.to_point_utf16(buffer.read(cx));
 5341        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5342    }
 5343
 5344    fn on_type_format_impl(
 5345        &mut self,
 5346        buffer: Entity<Buffer>,
 5347        position: PointUtf16,
 5348        trigger: String,
 5349        push_to_history: bool,
 5350        cx: &mut Context<Self>,
 5351    ) -> Task<Result<Option<Transaction>>> {
 5352        let options = buffer.update(cx, |buffer, cx| {
 5353            lsp_command::lsp_formatting_options(
 5354                language_settings(
 5355                    buffer.language_at(position).map(|l| l.name()),
 5356                    buffer.file(),
 5357                    cx,
 5358                )
 5359                .as_ref(),
 5360            )
 5361        });
 5362
 5363        cx.spawn(async move |this, cx| {
 5364            if let Some(waiter) =
 5365                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5366            {
 5367                waiter.await?;
 5368            }
 5369            cx.update(|cx| {
 5370                this.update(cx, |this, cx| {
 5371                    this.request_lsp(
 5372                        buffer.clone(),
 5373                        LanguageServerToQuery::FirstCapable,
 5374                        OnTypeFormatting {
 5375                            position,
 5376                            trigger,
 5377                            options,
 5378                            push_to_history,
 5379                        },
 5380                        cx,
 5381                    )
 5382                })
 5383            })??
 5384            .await
 5385        })
 5386    }
 5387
 5388    pub fn definitions(
 5389        &mut self,
 5390        buffer: &Entity<Buffer>,
 5391        position: PointUtf16,
 5392        cx: &mut Context<Self>,
 5393    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5394        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5395            let request = GetDefinitions { position };
 5396            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5397                return Task::ready(Ok(None));
 5398            }
 5399            let request_task = upstream_client.request_lsp(
 5400                project_id,
 5401                None,
 5402                LSP_REQUEST_TIMEOUT,
 5403                cx.background_executor().clone(),
 5404                request.to_proto(project_id, buffer.read(cx)),
 5405            );
 5406            let buffer = buffer.clone();
 5407            cx.spawn(async move |weak_lsp_store, cx| {
 5408                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5409                    return Ok(None);
 5410                };
 5411                let Some(responses) = request_task.await? else {
 5412                    return Ok(None);
 5413                };
 5414                let actions = join_all(responses.payload.into_iter().map(|response| {
 5415                    GetDefinitions { position }.response_from_proto(
 5416                        response.response,
 5417                        lsp_store.clone(),
 5418                        buffer.clone(),
 5419                        cx.clone(),
 5420                    )
 5421                }))
 5422                .await;
 5423
 5424                Ok(Some(
 5425                    actions
 5426                        .into_iter()
 5427                        .collect::<Result<Vec<Vec<_>>>>()?
 5428                        .into_iter()
 5429                        .flatten()
 5430                        .dedup()
 5431                        .collect(),
 5432                ))
 5433            })
 5434        } else {
 5435            let definitions_task = self.request_multiple_lsp_locally(
 5436                buffer,
 5437                Some(position),
 5438                GetDefinitions { position },
 5439                cx,
 5440            );
 5441            cx.background_spawn(async move {
 5442                Ok(Some(
 5443                    definitions_task
 5444                        .await
 5445                        .into_iter()
 5446                        .flat_map(|(_, definitions)| definitions)
 5447                        .dedup()
 5448                        .collect(),
 5449                ))
 5450            })
 5451        }
 5452    }
 5453
 5454    pub fn declarations(
 5455        &mut self,
 5456        buffer: &Entity<Buffer>,
 5457        position: PointUtf16,
 5458        cx: &mut Context<Self>,
 5459    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5460        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5461            let request = GetDeclarations { position };
 5462            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5463                return Task::ready(Ok(None));
 5464            }
 5465            let request_task = upstream_client.request_lsp(
 5466                project_id,
 5467                None,
 5468                LSP_REQUEST_TIMEOUT,
 5469                cx.background_executor().clone(),
 5470                request.to_proto(project_id, buffer.read(cx)),
 5471            );
 5472            let buffer = buffer.clone();
 5473            cx.spawn(async move |weak_lsp_store, cx| {
 5474                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5475                    return Ok(None);
 5476                };
 5477                let Some(responses) = request_task.await? else {
 5478                    return Ok(None);
 5479                };
 5480                let actions = join_all(responses.payload.into_iter().map(|response| {
 5481                    GetDeclarations { position }.response_from_proto(
 5482                        response.response,
 5483                        lsp_store.clone(),
 5484                        buffer.clone(),
 5485                        cx.clone(),
 5486                    )
 5487                }))
 5488                .await;
 5489
 5490                Ok(Some(
 5491                    actions
 5492                        .into_iter()
 5493                        .collect::<Result<Vec<Vec<_>>>>()?
 5494                        .into_iter()
 5495                        .flatten()
 5496                        .dedup()
 5497                        .collect(),
 5498                ))
 5499            })
 5500        } else {
 5501            let declarations_task = self.request_multiple_lsp_locally(
 5502                buffer,
 5503                Some(position),
 5504                GetDeclarations { position },
 5505                cx,
 5506            );
 5507            cx.background_spawn(async move {
 5508                Ok(Some(
 5509                    declarations_task
 5510                        .await
 5511                        .into_iter()
 5512                        .flat_map(|(_, declarations)| declarations)
 5513                        .dedup()
 5514                        .collect(),
 5515                ))
 5516            })
 5517        }
 5518    }
 5519
 5520    pub fn type_definitions(
 5521        &mut self,
 5522        buffer: &Entity<Buffer>,
 5523        position: PointUtf16,
 5524        cx: &mut Context<Self>,
 5525    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5526        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5527            let request = GetTypeDefinitions { position };
 5528            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5529                return Task::ready(Ok(None));
 5530            }
 5531            let request_task = upstream_client.request_lsp(
 5532                project_id,
 5533                None,
 5534                LSP_REQUEST_TIMEOUT,
 5535                cx.background_executor().clone(),
 5536                request.to_proto(project_id, buffer.read(cx)),
 5537            );
 5538            let buffer = buffer.clone();
 5539            cx.spawn(async move |weak_lsp_store, cx| {
 5540                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5541                    return Ok(None);
 5542                };
 5543                let Some(responses) = request_task.await? else {
 5544                    return Ok(None);
 5545                };
 5546                let actions = join_all(responses.payload.into_iter().map(|response| {
 5547                    GetTypeDefinitions { position }.response_from_proto(
 5548                        response.response,
 5549                        lsp_store.clone(),
 5550                        buffer.clone(),
 5551                        cx.clone(),
 5552                    )
 5553                }))
 5554                .await;
 5555
 5556                Ok(Some(
 5557                    actions
 5558                        .into_iter()
 5559                        .collect::<Result<Vec<Vec<_>>>>()?
 5560                        .into_iter()
 5561                        .flatten()
 5562                        .dedup()
 5563                        .collect(),
 5564                ))
 5565            })
 5566        } else {
 5567            let type_definitions_task = self.request_multiple_lsp_locally(
 5568                buffer,
 5569                Some(position),
 5570                GetTypeDefinitions { position },
 5571                cx,
 5572            );
 5573            cx.background_spawn(async move {
 5574                Ok(Some(
 5575                    type_definitions_task
 5576                        .await
 5577                        .into_iter()
 5578                        .flat_map(|(_, type_definitions)| type_definitions)
 5579                        .dedup()
 5580                        .collect(),
 5581                ))
 5582            })
 5583        }
 5584    }
 5585
 5586    pub fn implementations(
 5587        &mut self,
 5588        buffer: &Entity<Buffer>,
 5589        position: PointUtf16,
 5590        cx: &mut Context<Self>,
 5591    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5592        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5593            let request = GetImplementations { position };
 5594            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5595                return Task::ready(Ok(None));
 5596            }
 5597            let request_task = upstream_client.request_lsp(
 5598                project_id,
 5599                None,
 5600                LSP_REQUEST_TIMEOUT,
 5601                cx.background_executor().clone(),
 5602                request.to_proto(project_id, buffer.read(cx)),
 5603            );
 5604            let buffer = buffer.clone();
 5605            cx.spawn(async move |weak_lsp_store, cx| {
 5606                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5607                    return Ok(None);
 5608                };
 5609                let Some(responses) = request_task.await? else {
 5610                    return Ok(None);
 5611                };
 5612                let actions = join_all(responses.payload.into_iter().map(|response| {
 5613                    GetImplementations { position }.response_from_proto(
 5614                        response.response,
 5615                        lsp_store.clone(),
 5616                        buffer.clone(),
 5617                        cx.clone(),
 5618                    )
 5619                }))
 5620                .await;
 5621
 5622                Ok(Some(
 5623                    actions
 5624                        .into_iter()
 5625                        .collect::<Result<Vec<Vec<_>>>>()?
 5626                        .into_iter()
 5627                        .flatten()
 5628                        .dedup()
 5629                        .collect(),
 5630                ))
 5631            })
 5632        } else {
 5633            let implementations_task = self.request_multiple_lsp_locally(
 5634                buffer,
 5635                Some(position),
 5636                GetImplementations { position },
 5637                cx,
 5638            );
 5639            cx.background_spawn(async move {
 5640                Ok(Some(
 5641                    implementations_task
 5642                        .await
 5643                        .into_iter()
 5644                        .flat_map(|(_, implementations)| implementations)
 5645                        .dedup()
 5646                        .collect(),
 5647                ))
 5648            })
 5649        }
 5650    }
 5651
 5652    pub fn references(
 5653        &mut self,
 5654        buffer: &Entity<Buffer>,
 5655        position: PointUtf16,
 5656        cx: &mut Context<Self>,
 5657    ) -> Task<Result<Option<Vec<Location>>>> {
 5658        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5659            let request = GetReferences { position };
 5660            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5661                return Task::ready(Ok(None));
 5662            }
 5663
 5664            let request_task = upstream_client.request_lsp(
 5665                project_id,
 5666                None,
 5667                LSP_REQUEST_TIMEOUT,
 5668                cx.background_executor().clone(),
 5669                request.to_proto(project_id, buffer.read(cx)),
 5670            );
 5671            let buffer = buffer.clone();
 5672            cx.spawn(async move |weak_lsp_store, cx| {
 5673                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5674                    return Ok(None);
 5675                };
 5676                let Some(responses) = request_task.await? else {
 5677                    return Ok(None);
 5678                };
 5679
 5680                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5681                    GetReferences { position }.response_from_proto(
 5682                        lsp_response.response,
 5683                        lsp_store.clone(),
 5684                        buffer.clone(),
 5685                        cx.clone(),
 5686                    )
 5687                }))
 5688                .await
 5689                .into_iter()
 5690                .collect::<Result<Vec<Vec<_>>>>()?
 5691                .into_iter()
 5692                .flatten()
 5693                .dedup()
 5694                .collect();
 5695                Ok(Some(locations))
 5696            })
 5697        } else {
 5698            let references_task = self.request_multiple_lsp_locally(
 5699                buffer,
 5700                Some(position),
 5701                GetReferences { position },
 5702                cx,
 5703            );
 5704            cx.background_spawn(async move {
 5705                Ok(Some(
 5706                    references_task
 5707                        .await
 5708                        .into_iter()
 5709                        .flat_map(|(_, references)| references)
 5710                        .dedup()
 5711                        .collect(),
 5712                ))
 5713            })
 5714        }
 5715    }
 5716
 5717    pub fn code_actions(
 5718        &mut self,
 5719        buffer: &Entity<Buffer>,
 5720        range: Range<Anchor>,
 5721        kinds: Option<Vec<CodeActionKind>>,
 5722        cx: &mut Context<Self>,
 5723    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5724        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5725            let request = GetCodeActions {
 5726                range: range.clone(),
 5727                kinds: kinds.clone(),
 5728            };
 5729            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5730                return Task::ready(Ok(None));
 5731            }
 5732            let request_task = upstream_client.request_lsp(
 5733                project_id,
 5734                None,
 5735                LSP_REQUEST_TIMEOUT,
 5736                cx.background_executor().clone(),
 5737                request.to_proto(project_id, buffer.read(cx)),
 5738            );
 5739            let buffer = buffer.clone();
 5740            cx.spawn(async move |weak_lsp_store, cx| {
 5741                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5742                    return Ok(None);
 5743                };
 5744                let Some(responses) = request_task.await? else {
 5745                    return Ok(None);
 5746                };
 5747                let actions = join_all(responses.payload.into_iter().map(|response| {
 5748                    GetCodeActions {
 5749                        range: range.clone(),
 5750                        kinds: kinds.clone(),
 5751                    }
 5752                    .response_from_proto(
 5753                        response.response,
 5754                        lsp_store.clone(),
 5755                        buffer.clone(),
 5756                        cx.clone(),
 5757                    )
 5758                }))
 5759                .await;
 5760
 5761                Ok(Some(
 5762                    actions
 5763                        .into_iter()
 5764                        .collect::<Result<Vec<Vec<_>>>>()?
 5765                        .into_iter()
 5766                        .flatten()
 5767                        .collect(),
 5768                ))
 5769            })
 5770        } else {
 5771            let all_actions_task = self.request_multiple_lsp_locally(
 5772                buffer,
 5773                Some(range.start),
 5774                GetCodeActions { range, kinds },
 5775                cx,
 5776            );
 5777            cx.background_spawn(async move {
 5778                Ok(Some(
 5779                    all_actions_task
 5780                        .await
 5781                        .into_iter()
 5782                        .flat_map(|(_, actions)| actions)
 5783                        .collect(),
 5784                ))
 5785            })
 5786        }
 5787    }
 5788
 5789    pub fn code_lens_actions(
 5790        &mut self,
 5791        buffer: &Entity<Buffer>,
 5792        cx: &mut Context<Self>,
 5793    ) -> CodeLensTask {
 5794        let version_queried_for = buffer.read(cx).version();
 5795        let buffer_id = buffer.read(cx).remote_id();
 5796        let existing_servers = self.as_local().map(|local| {
 5797            local
 5798                .buffers_opened_in_servers
 5799                .get(&buffer_id)
 5800                .cloned()
 5801                .unwrap_or_default()
 5802        });
 5803
 5804        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 5805            if let Some(cached_lens) = &lsp_data.code_lens {
 5806                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 5807                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 5808                        existing_servers != cached_lens.lens.keys().copied().collect()
 5809                    });
 5810                    if !has_different_servers {
 5811                        return Task::ready(Ok(Some(
 5812                            cached_lens.lens.values().flatten().cloned().collect(),
 5813                        )))
 5814                        .shared();
 5815                    }
 5816                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 5817                    if !version_queried_for.changed_since(updating_for) {
 5818                        return running_update.clone();
 5819                    }
 5820                }
 5821            }
 5822        }
 5823
 5824        let lens_lsp_data = self
 5825            .latest_lsp_data(buffer, cx)
 5826            .code_lens
 5827            .get_or_insert_default();
 5828        let buffer = buffer.clone();
 5829        let query_version_queried_for = version_queried_for.clone();
 5830        let new_task = cx
 5831            .spawn(async move |lsp_store, cx| {
 5832                cx.background_executor()
 5833                    .timer(Duration::from_millis(30))
 5834                    .await;
 5835                let fetched_lens = lsp_store
 5836                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 5837                    .map_err(Arc::new)?
 5838                    .await
 5839                    .context("fetching code lens")
 5840                    .map_err(Arc::new);
 5841                let fetched_lens = match fetched_lens {
 5842                    Ok(fetched_lens) => fetched_lens,
 5843                    Err(e) => {
 5844                        lsp_store
 5845                            .update(cx, |lsp_store, _| {
 5846                                if let Some(lens_lsp_data) = lsp_store
 5847                                    .lsp_data
 5848                                    .get_mut(&buffer_id)
 5849                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 5850                                {
 5851                                    lens_lsp_data.update = None;
 5852                                }
 5853                            })
 5854                            .ok();
 5855                        return Err(e);
 5856                    }
 5857                };
 5858
 5859                lsp_store
 5860                    .update(cx, |lsp_store, _| {
 5861                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 5862                        let code_lens = lsp_data.code_lens.as_mut()?;
 5863                        if let Some(fetched_lens) = fetched_lens {
 5864                            if lsp_data.buffer_version == query_version_queried_for {
 5865                                code_lens.lens.extend(fetched_lens);
 5866                            } else if !lsp_data
 5867                                .buffer_version
 5868                                .changed_since(&query_version_queried_for)
 5869                            {
 5870                                lsp_data.buffer_version = query_version_queried_for;
 5871                                code_lens.lens = fetched_lens;
 5872                            }
 5873                        }
 5874                        code_lens.update = None;
 5875                        Some(code_lens.lens.values().flatten().cloned().collect())
 5876                    })
 5877                    .map_err(Arc::new)
 5878            })
 5879            .shared();
 5880        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 5881        new_task
 5882    }
 5883
 5884    fn fetch_code_lens(
 5885        &mut self,
 5886        buffer: &Entity<Buffer>,
 5887        cx: &mut Context<Self>,
 5888    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 5889        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5890            let request = GetCodeLens;
 5891            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5892                return Task::ready(Ok(None));
 5893            }
 5894            let request_task = upstream_client.request_lsp(
 5895                project_id,
 5896                None,
 5897                LSP_REQUEST_TIMEOUT,
 5898                cx.background_executor().clone(),
 5899                request.to_proto(project_id, buffer.read(cx)),
 5900            );
 5901            let buffer = buffer.clone();
 5902            cx.spawn(async move |weak_lsp_store, cx| {
 5903                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5904                    return Ok(None);
 5905                };
 5906                let Some(responses) = request_task.await? else {
 5907                    return Ok(None);
 5908                };
 5909
 5910                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 5911                    let lsp_store = lsp_store.clone();
 5912                    let buffer = buffer.clone();
 5913                    let cx = cx.clone();
 5914                    async move {
 5915                        (
 5916                            LanguageServerId::from_proto(response.server_id),
 5917                            GetCodeLens
 5918                                .response_from_proto(response.response, lsp_store, buffer, cx)
 5919                                .await,
 5920                        )
 5921                    }
 5922                }))
 5923                .await;
 5924
 5925                let mut has_errors = false;
 5926                let code_lens_actions = code_lens_actions
 5927                    .into_iter()
 5928                    .filter_map(|(server_id, code_lens)| match code_lens {
 5929                        Ok(code_lens) => Some((server_id, code_lens)),
 5930                        Err(e) => {
 5931                            has_errors = true;
 5932                            log::error!("{e:#}");
 5933                            None
 5934                        }
 5935                    })
 5936                    .collect::<HashMap<_, _>>();
 5937                anyhow::ensure!(
 5938                    !has_errors || !code_lens_actions.is_empty(),
 5939                    "Failed to fetch code lens"
 5940                );
 5941                Ok(Some(code_lens_actions))
 5942            })
 5943        } else {
 5944            let code_lens_actions_task =
 5945                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 5946            cx.background_spawn(async move {
 5947                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 5948            })
 5949        }
 5950    }
 5951
 5952    #[inline(never)]
 5953    pub fn completions(
 5954        &self,
 5955        buffer: &Entity<Buffer>,
 5956        position: PointUtf16,
 5957        context: CompletionContext,
 5958        cx: &mut Context<Self>,
 5959    ) -> Task<Result<Vec<CompletionResponse>>> {
 5960        let language_registry = self.languages.clone();
 5961
 5962        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5963            let snapshot = buffer.read(cx).snapshot();
 5964            let offset = position.to_offset(&snapshot);
 5965            let scope = snapshot.language_scope_at(offset);
 5966            let capable_lsps = self.all_capable_for_proto_request(
 5967                buffer,
 5968                |server_name, capabilities| {
 5969                    capabilities.completion_provider.is_some()
 5970                        && scope
 5971                            .as_ref()
 5972                            .map(|scope| scope.language_allowed(server_name))
 5973                            .unwrap_or(true)
 5974                },
 5975                cx,
 5976            );
 5977            if capable_lsps.is_empty() {
 5978                return Task::ready(Ok(Vec::new()));
 5979            }
 5980
 5981            let language = buffer.read(cx).language().cloned();
 5982
 5983            // In the future, we should provide project guests with the names of LSP adapters,
 5984            // so that they can use the correct LSP adapter when computing labels. For now,
 5985            // guests just use the first LSP adapter associated with the buffer's language.
 5986            let lsp_adapter = language.as_ref().and_then(|language| {
 5987                language_registry
 5988                    .lsp_adapters(&language.name())
 5989                    .first()
 5990                    .cloned()
 5991            });
 5992
 5993            let buffer = buffer.clone();
 5994
 5995            cx.spawn(async move |this, cx| {
 5996                let requests = join_all(
 5997                    capable_lsps
 5998                        .into_iter()
 5999                        .map(|id| {
 6000                            let request = GetCompletions {
 6001                                position,
 6002                                context: context.clone(),
 6003                                server_id: Some(id),
 6004                            };
 6005                            let buffer = buffer.clone();
 6006                            let language = language.clone();
 6007                            let lsp_adapter = lsp_adapter.clone();
 6008                            let upstream_client = upstream_client.clone();
 6009                            let response = this
 6010                                .update(cx, |this, cx| {
 6011                                    this.send_lsp_proto_request(
 6012                                        buffer,
 6013                                        upstream_client,
 6014                                        project_id,
 6015                                        request,
 6016                                        cx,
 6017                                    )
 6018                                })
 6019                                .log_err();
 6020                            async move {
 6021                                let response = response?.await.log_err()?;
 6022
 6023                                let completions = populate_labels_for_completions(
 6024                                    response.completions,
 6025                                    language,
 6026                                    lsp_adapter,
 6027                                )
 6028                                .await;
 6029
 6030                                Some(CompletionResponse {
 6031                                    completions,
 6032                                    display_options: CompletionDisplayOptions::default(),
 6033                                    is_incomplete: response.is_incomplete,
 6034                                })
 6035                            }
 6036                        })
 6037                        .collect::<Vec<_>>(),
 6038                );
 6039                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6040            })
 6041        } else if let Some(local) = self.as_local() {
 6042            let snapshot = buffer.read(cx).snapshot();
 6043            let offset = position.to_offset(&snapshot);
 6044            let scope = snapshot.language_scope_at(offset);
 6045            let language = snapshot.language().cloned();
 6046            let completion_settings = language_settings(
 6047                language.as_ref().map(|language| language.name()),
 6048                buffer.read(cx).file(),
 6049                cx,
 6050            )
 6051            .completions
 6052            .clone();
 6053            if !completion_settings.lsp {
 6054                return Task::ready(Ok(Vec::new()));
 6055            }
 6056
 6057            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6058                local
 6059                    .language_servers_for_buffer(buffer, cx)
 6060                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6061                    .filter(|(adapter, _)| {
 6062                        scope
 6063                            .as_ref()
 6064                            .map(|scope| scope.language_allowed(&adapter.name))
 6065                            .unwrap_or(true)
 6066                    })
 6067                    .map(|(_, server)| server.server_id())
 6068                    .collect()
 6069            });
 6070
 6071            let buffer = buffer.clone();
 6072            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6073            let lsp_timeout = if lsp_timeout > 0 {
 6074                Some(Duration::from_millis(lsp_timeout))
 6075            } else {
 6076                None
 6077            };
 6078            cx.spawn(async move |this,  cx| {
 6079                let mut tasks = Vec::with_capacity(server_ids.len());
 6080                this.update(cx, |lsp_store, cx| {
 6081                    for server_id in server_ids {
 6082                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6083                        let lsp_timeout = lsp_timeout
 6084                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6085                        let mut timeout = cx.background_spawn(async move {
 6086                            match lsp_timeout {
 6087                                Some(lsp_timeout) => {
 6088                                    lsp_timeout.await;
 6089                                    true
 6090                                },
 6091                                None => false,
 6092                            }
 6093                        }).fuse();
 6094                        let mut lsp_request = lsp_store.request_lsp(
 6095                            buffer.clone(),
 6096                            LanguageServerToQuery::Other(server_id),
 6097                            GetCompletions {
 6098                                position,
 6099                                context: context.clone(),
 6100                                server_id: Some(server_id),
 6101                            },
 6102                            cx,
 6103                        ).fuse();
 6104                        let new_task = cx.background_spawn(async move {
 6105                            select_biased! {
 6106                                response = lsp_request => anyhow::Ok(Some(response?)),
 6107                                timeout_happened = timeout => {
 6108                                    if timeout_happened {
 6109                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6110                                        Ok(None)
 6111                                    } else {
 6112                                        let completions = lsp_request.await?;
 6113                                        Ok(Some(completions))
 6114                                    }
 6115                                },
 6116                            }
 6117                        });
 6118                        tasks.push((lsp_adapter, new_task));
 6119                    }
 6120                })?;
 6121
 6122                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6123                    let completion_response = task.await.ok()??;
 6124                    let completions = populate_labels_for_completions(
 6125                            completion_response.completions,
 6126                            language.clone(),
 6127                            lsp_adapter,
 6128                        )
 6129                        .await;
 6130                    Some(CompletionResponse {
 6131                        completions,
 6132                        display_options: CompletionDisplayOptions::default(),
 6133                        is_incomplete: completion_response.is_incomplete,
 6134                    })
 6135                });
 6136
 6137                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6138
 6139                Ok(responses.into_iter().flatten().collect())
 6140            })
 6141        } else {
 6142            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6143        }
 6144    }
 6145
 6146    pub fn resolve_completions(
 6147        &self,
 6148        buffer: Entity<Buffer>,
 6149        completion_indices: Vec<usize>,
 6150        completions: Rc<RefCell<Box<[Completion]>>>,
 6151        cx: &mut Context<Self>,
 6152    ) -> Task<Result<bool>> {
 6153        let client = self.upstream_client();
 6154        let buffer_id = buffer.read(cx).remote_id();
 6155        let buffer_snapshot = buffer.read(cx).snapshot();
 6156
 6157        if !self.check_if_capable_for_proto_request(
 6158            &buffer,
 6159            GetCompletions::can_resolve_completions,
 6160            cx,
 6161        ) {
 6162            return Task::ready(Ok(false));
 6163        }
 6164        cx.spawn(async move |lsp_store, cx| {
 6165            let mut did_resolve = false;
 6166            if let Some((client, project_id)) = client {
 6167                for completion_index in completion_indices {
 6168                    let server_id = {
 6169                        let completion = &completions.borrow()[completion_index];
 6170                        completion.source.server_id()
 6171                    };
 6172                    if let Some(server_id) = server_id {
 6173                        if Self::resolve_completion_remote(
 6174                            project_id,
 6175                            server_id,
 6176                            buffer_id,
 6177                            completions.clone(),
 6178                            completion_index,
 6179                            client.clone(),
 6180                        )
 6181                        .await
 6182                        .log_err()
 6183                        .is_some()
 6184                        {
 6185                            did_resolve = true;
 6186                        }
 6187                    } else {
 6188                        resolve_word_completion(
 6189                            &buffer_snapshot,
 6190                            &mut completions.borrow_mut()[completion_index],
 6191                        );
 6192                    }
 6193                }
 6194            } else {
 6195                for completion_index in completion_indices {
 6196                    let server_id = {
 6197                        let completion = &completions.borrow()[completion_index];
 6198                        completion.source.server_id()
 6199                    };
 6200                    if let Some(server_id) = server_id {
 6201                        let server_and_adapter = lsp_store
 6202                            .read_with(cx, |lsp_store, _| {
 6203                                let server = lsp_store.language_server_for_id(server_id)?;
 6204                                let adapter =
 6205                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6206                                Some((server, adapter))
 6207                            })
 6208                            .ok()
 6209                            .flatten();
 6210                        let Some((server, adapter)) = server_and_adapter else {
 6211                            continue;
 6212                        };
 6213
 6214                        let resolved = Self::resolve_completion_local(
 6215                            server,
 6216                            completions.clone(),
 6217                            completion_index,
 6218                        )
 6219                        .await
 6220                        .log_err()
 6221                        .is_some();
 6222                        if resolved {
 6223                            Self::regenerate_completion_labels(
 6224                                adapter,
 6225                                &buffer_snapshot,
 6226                                completions.clone(),
 6227                                completion_index,
 6228                            )
 6229                            .await
 6230                            .log_err();
 6231                            did_resolve = true;
 6232                        }
 6233                    } else {
 6234                        resolve_word_completion(
 6235                            &buffer_snapshot,
 6236                            &mut completions.borrow_mut()[completion_index],
 6237                        );
 6238                    }
 6239                }
 6240            }
 6241
 6242            Ok(did_resolve)
 6243        })
 6244    }
 6245
 6246    async fn resolve_completion_local(
 6247        server: Arc<lsp::LanguageServer>,
 6248        completions: Rc<RefCell<Box<[Completion]>>>,
 6249        completion_index: usize,
 6250    ) -> Result<()> {
 6251        let server_id = server.server_id();
 6252        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6253            return Ok(());
 6254        }
 6255
 6256        let request = {
 6257            let completion = &completions.borrow()[completion_index];
 6258            match &completion.source {
 6259                CompletionSource::Lsp {
 6260                    lsp_completion,
 6261                    resolved,
 6262                    server_id: completion_server_id,
 6263                    ..
 6264                } => {
 6265                    if *resolved {
 6266                        return Ok(());
 6267                    }
 6268                    anyhow::ensure!(
 6269                        server_id == *completion_server_id,
 6270                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6271                    );
 6272                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6273                }
 6274                CompletionSource::BufferWord { .. }
 6275                | CompletionSource::Dap { .. }
 6276                | CompletionSource::Custom => {
 6277                    return Ok(());
 6278                }
 6279            }
 6280        };
 6281        let resolved_completion = request
 6282            .await
 6283            .into_response()
 6284            .context("resolve completion")?;
 6285
 6286        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6287        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6288
 6289        let mut completions = completions.borrow_mut();
 6290        let completion = &mut completions[completion_index];
 6291        if let CompletionSource::Lsp {
 6292            lsp_completion,
 6293            resolved,
 6294            server_id: completion_server_id,
 6295            ..
 6296        } = &mut completion.source
 6297        {
 6298            if *resolved {
 6299                return Ok(());
 6300            }
 6301            anyhow::ensure!(
 6302                server_id == *completion_server_id,
 6303                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6304            );
 6305            *lsp_completion = Box::new(resolved_completion);
 6306            *resolved = true;
 6307        }
 6308        Ok(())
 6309    }
 6310
 6311    async fn regenerate_completion_labels(
 6312        adapter: Arc<CachedLspAdapter>,
 6313        snapshot: &BufferSnapshot,
 6314        completions: Rc<RefCell<Box<[Completion]>>>,
 6315        completion_index: usize,
 6316    ) -> Result<()> {
 6317        let completion_item = completions.borrow()[completion_index]
 6318            .source
 6319            .lsp_completion(true)
 6320            .map(Cow::into_owned);
 6321        if let Some(lsp_documentation) = completion_item
 6322            .as_ref()
 6323            .and_then(|completion_item| completion_item.documentation.clone())
 6324        {
 6325            let mut completions = completions.borrow_mut();
 6326            let completion = &mut completions[completion_index];
 6327            completion.documentation = Some(lsp_documentation.into());
 6328        } else {
 6329            let mut completions = completions.borrow_mut();
 6330            let completion = &mut completions[completion_index];
 6331            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6332        }
 6333
 6334        let mut new_label = match completion_item {
 6335            Some(completion_item) => {
 6336                // 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
 6337                // So we have to update the label here anyway...
 6338                let language = snapshot.language();
 6339                match language {
 6340                    Some(language) => {
 6341                        adapter
 6342                            .labels_for_completions(
 6343                                std::slice::from_ref(&completion_item),
 6344                                language,
 6345                            )
 6346                            .await?
 6347                    }
 6348                    None => Vec::new(),
 6349                }
 6350                .pop()
 6351                .flatten()
 6352                .unwrap_or_else(|| {
 6353                    CodeLabel::fallback_for_completion(
 6354                        &completion_item,
 6355                        language.map(|language| language.as_ref()),
 6356                    )
 6357                })
 6358            }
 6359            None => CodeLabel::plain(
 6360                completions.borrow()[completion_index].new_text.clone(),
 6361                None,
 6362            ),
 6363        };
 6364        ensure_uniform_list_compatible_label(&mut new_label);
 6365
 6366        let mut completions = completions.borrow_mut();
 6367        let completion = &mut completions[completion_index];
 6368        if completion.label.filter_text() == new_label.filter_text() {
 6369            completion.label = new_label;
 6370        } else {
 6371            log::error!(
 6372                "Resolved completion changed display label from {} to {}. \
 6373                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6374                completion.label.text(),
 6375                new_label.text(),
 6376                completion.label.filter_text(),
 6377                new_label.filter_text()
 6378            );
 6379        }
 6380
 6381        Ok(())
 6382    }
 6383
 6384    async fn resolve_completion_remote(
 6385        project_id: u64,
 6386        server_id: LanguageServerId,
 6387        buffer_id: BufferId,
 6388        completions: Rc<RefCell<Box<[Completion]>>>,
 6389        completion_index: usize,
 6390        client: AnyProtoClient,
 6391    ) -> Result<()> {
 6392        let lsp_completion = {
 6393            let completion = &completions.borrow()[completion_index];
 6394            match &completion.source {
 6395                CompletionSource::Lsp {
 6396                    lsp_completion,
 6397                    resolved,
 6398                    server_id: completion_server_id,
 6399                    ..
 6400                } => {
 6401                    anyhow::ensure!(
 6402                        server_id == *completion_server_id,
 6403                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6404                    );
 6405                    if *resolved {
 6406                        return Ok(());
 6407                    }
 6408                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6409                }
 6410                CompletionSource::Custom
 6411                | CompletionSource::Dap { .. }
 6412                | CompletionSource::BufferWord { .. } => {
 6413                    return Ok(());
 6414                }
 6415            }
 6416        };
 6417        let request = proto::ResolveCompletionDocumentation {
 6418            project_id,
 6419            language_server_id: server_id.0 as u64,
 6420            lsp_completion,
 6421            buffer_id: buffer_id.into(),
 6422        };
 6423
 6424        let response = client
 6425            .request(request)
 6426            .await
 6427            .context("completion documentation resolve proto request")?;
 6428        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6429
 6430        let documentation = if response.documentation.is_empty() {
 6431            CompletionDocumentation::Undocumented
 6432        } else if response.documentation_is_markdown {
 6433            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6434        } else if response.documentation.lines().count() <= 1 {
 6435            CompletionDocumentation::SingleLine(response.documentation.into())
 6436        } else {
 6437            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6438        };
 6439
 6440        let mut completions = completions.borrow_mut();
 6441        let completion = &mut completions[completion_index];
 6442        completion.documentation = Some(documentation);
 6443        if let CompletionSource::Lsp {
 6444            insert_range,
 6445            lsp_completion,
 6446            resolved,
 6447            server_id: completion_server_id,
 6448            lsp_defaults: _,
 6449        } = &mut completion.source
 6450        {
 6451            let completion_insert_range = response
 6452                .old_insert_start
 6453                .and_then(deserialize_anchor)
 6454                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6455            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6456
 6457            if *resolved {
 6458                return Ok(());
 6459            }
 6460            anyhow::ensure!(
 6461                server_id == *completion_server_id,
 6462                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6463            );
 6464            *lsp_completion = Box::new(resolved_lsp_completion);
 6465            *resolved = true;
 6466        }
 6467
 6468        let replace_range = response
 6469            .old_replace_start
 6470            .and_then(deserialize_anchor)
 6471            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6472        if let Some((old_replace_start, old_replace_end)) = replace_range
 6473            && !response.new_text.is_empty()
 6474        {
 6475            completion.new_text = response.new_text;
 6476            completion.replace_range = old_replace_start..old_replace_end;
 6477        }
 6478
 6479        Ok(())
 6480    }
 6481
 6482    pub fn apply_additional_edits_for_completion(
 6483        &self,
 6484        buffer_handle: Entity<Buffer>,
 6485        completions: Rc<RefCell<Box<[Completion]>>>,
 6486        completion_index: usize,
 6487        push_to_history: bool,
 6488        cx: &mut Context<Self>,
 6489    ) -> Task<Result<Option<Transaction>>> {
 6490        if let Some((client, project_id)) = self.upstream_client() {
 6491            let buffer = buffer_handle.read(cx);
 6492            let buffer_id = buffer.remote_id();
 6493            cx.spawn(async move |_, cx| {
 6494                let request = {
 6495                    let completion = completions.borrow()[completion_index].clone();
 6496                    proto::ApplyCompletionAdditionalEdits {
 6497                        project_id,
 6498                        buffer_id: buffer_id.into(),
 6499                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6500                            replace_range: completion.replace_range,
 6501                            new_text: completion.new_text,
 6502                            source: completion.source,
 6503                        })),
 6504                    }
 6505                };
 6506
 6507                if let Some(transaction) = client.request(request).await?.transaction {
 6508                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6509                    buffer_handle
 6510                        .update(cx, |buffer, _| {
 6511                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6512                        })?
 6513                        .await?;
 6514                    if push_to_history {
 6515                        buffer_handle.update(cx, |buffer, _| {
 6516                            buffer.push_transaction(transaction.clone(), Instant::now());
 6517                            buffer.finalize_last_transaction();
 6518                        })?;
 6519                    }
 6520                    Ok(Some(transaction))
 6521                } else {
 6522                    Ok(None)
 6523                }
 6524            })
 6525        } else {
 6526            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6527                let completion = &completions.borrow()[completion_index];
 6528                let server_id = completion.source.server_id()?;
 6529                Some(
 6530                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6531                        .1
 6532                        .clone(),
 6533                )
 6534            }) else {
 6535                return Task::ready(Ok(None));
 6536            };
 6537
 6538            cx.spawn(async move |this, cx| {
 6539                Self::resolve_completion_local(
 6540                    server.clone(),
 6541                    completions.clone(),
 6542                    completion_index,
 6543                )
 6544                .await
 6545                .context("resolving completion")?;
 6546                let completion = completions.borrow()[completion_index].clone();
 6547                let additional_text_edits = completion
 6548                    .source
 6549                    .lsp_completion(true)
 6550                    .as_ref()
 6551                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6552                if let Some(edits) = additional_text_edits {
 6553                    let edits = this
 6554                        .update(cx, |this, cx| {
 6555                            this.as_local_mut().unwrap().edits_from_lsp(
 6556                                &buffer_handle,
 6557                                edits,
 6558                                server.server_id(),
 6559                                None,
 6560                                cx,
 6561                            )
 6562                        })?
 6563                        .await?;
 6564
 6565                    buffer_handle.update(cx, |buffer, cx| {
 6566                        buffer.finalize_last_transaction();
 6567                        buffer.start_transaction();
 6568
 6569                        for (range, text) in edits {
 6570                            let primary = &completion.replace_range;
 6571
 6572                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6573                            // and the primary completion is just an insertion (empty range), then this is likely
 6574                            // an auto-import scenario and should not be considered overlapping
 6575                            // https://github.com/zed-industries/zed/issues/26136
 6576                            let is_file_start_auto_import = {
 6577                                let snapshot = buffer.snapshot();
 6578                                let primary_start_point = primary.start.to_point(&snapshot);
 6579                                let range_start_point = range.start.to_point(&snapshot);
 6580
 6581                                let result = primary_start_point.row == 0
 6582                                    && primary_start_point.column == 0
 6583                                    && range_start_point.row == 0
 6584                                    && range_start_point.column == 0;
 6585
 6586                                result
 6587                            };
 6588
 6589                            let has_overlap = if is_file_start_auto_import {
 6590                                false
 6591                            } else {
 6592                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6593                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6594                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6595                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6596                                let result = start_within || end_within;
 6597                                result
 6598                            };
 6599
 6600                            //Skip additional edits which overlap with the primary completion edit
 6601                            //https://github.com/zed-industries/zed/pull/1871
 6602                            if !has_overlap {
 6603                                buffer.edit([(range, text)], None, cx);
 6604                            }
 6605                        }
 6606
 6607                        let transaction = if buffer.end_transaction(cx).is_some() {
 6608                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6609                            if !push_to_history {
 6610                                buffer.forget_transaction(transaction.id);
 6611                            }
 6612                            Some(transaction)
 6613                        } else {
 6614                            None
 6615                        };
 6616                        Ok(transaction)
 6617                    })?
 6618                } else {
 6619                    Ok(None)
 6620                }
 6621            })
 6622        }
 6623    }
 6624
 6625    pub fn pull_diagnostics(
 6626        &mut self,
 6627        buffer: Entity<Buffer>,
 6628        cx: &mut Context<Self>,
 6629    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6630        let buffer_id = buffer.read(cx).remote_id();
 6631
 6632        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6633            let mut suitable_capabilities = None;
 6634            // Are we capable for proto request?
 6635            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6636                &buffer,
 6637                |capabilities| {
 6638                    if let Some(caps) = &capabilities.diagnostic_provider {
 6639                        suitable_capabilities = Some(caps.clone());
 6640                        true
 6641                    } else {
 6642                        false
 6643                    }
 6644                },
 6645                cx,
 6646            );
 6647            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6648            let Some(dynamic_caps) = suitable_capabilities else {
 6649                return Task::ready(Ok(None));
 6650            };
 6651            assert!(any_server_has_diagnostics_provider);
 6652
 6653            let request = GetDocumentDiagnostics {
 6654                previous_result_id: None,
 6655                dynamic_caps,
 6656            };
 6657            let request_task = client.request_lsp(
 6658                upstream_project_id,
 6659                None,
 6660                LSP_REQUEST_TIMEOUT,
 6661                cx.background_executor().clone(),
 6662                request.to_proto(upstream_project_id, buffer.read(cx)),
 6663            );
 6664            cx.background_spawn(async move {
 6665                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6666                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6667                // Do not attempt to further process the dummy responses here.
 6668                let _response = request_task.await?;
 6669                Ok(None)
 6670            })
 6671        } else {
 6672            let servers = buffer.update(cx, |buffer, cx| {
 6673                self.language_servers_for_local_buffer(buffer, cx)
 6674                    .map(|(_, server)| server.clone())
 6675                    .collect::<Vec<_>>()
 6676            });
 6677
 6678            let pull_diagnostics = servers
 6679                .into_iter()
 6680                .flat_map(|server| {
 6681                    let result = maybe!({
 6682                        let local = self.as_local()?;
 6683                        let server_id = server.server_id();
 6684                        let providers_with_identifiers = local
 6685                            .language_server_dynamic_registrations
 6686                            .get(&server_id)
 6687                            .into_iter()
 6688                            .flat_map(|registrations| registrations.diagnostics.values().cloned())
 6689                            .collect::<Vec<_>>();
 6690                        Some(
 6691                            providers_with_identifiers
 6692                                .into_iter()
 6693                                .map(|dynamic_caps| {
 6694                                    let result_id = self.result_id(server_id, buffer_id, cx);
 6695                                    self.request_lsp(
 6696                                        buffer.clone(),
 6697                                        LanguageServerToQuery::Other(server_id),
 6698                                        GetDocumentDiagnostics {
 6699                                            previous_result_id: result_id,
 6700                                            dynamic_caps,
 6701                                        },
 6702                                        cx,
 6703                                    )
 6704                                })
 6705                                .collect::<Vec<_>>(),
 6706                        )
 6707                    });
 6708
 6709                    result.unwrap_or_default()
 6710                })
 6711                .collect::<Vec<_>>();
 6712
 6713            cx.background_spawn(async move {
 6714                let mut responses = Vec::new();
 6715                for diagnostics in join_all(pull_diagnostics).await {
 6716                    responses.extend(diagnostics?);
 6717                }
 6718                Ok(Some(responses))
 6719            })
 6720        }
 6721    }
 6722
 6723    pub fn applicable_inlay_chunks(
 6724        &mut self,
 6725        buffer: &Entity<Buffer>,
 6726        ranges: &[Range<text::Anchor>],
 6727        cx: &mut Context<Self>,
 6728    ) -> Vec<Range<BufferRow>> {
 6729        self.latest_lsp_data(buffer, cx)
 6730            .inlay_hints
 6731            .applicable_chunks(ranges)
 6732            .map(|chunk| chunk.row_range())
 6733            .collect()
 6734    }
 6735
 6736    pub fn invalidate_inlay_hints<'a>(
 6737        &'a mut self,
 6738        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6739    ) {
 6740        for buffer_id in for_buffers {
 6741            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6742                lsp_data.inlay_hints.clear();
 6743            }
 6744        }
 6745    }
 6746
 6747    pub fn inlay_hints(
 6748        &mut self,
 6749        invalidate: InvalidationStrategy,
 6750        buffer: Entity<Buffer>,
 6751        ranges: Vec<Range<text::Anchor>>,
 6752        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6753        cx: &mut Context<Self>,
 6754    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6755        let next_hint_id = self.next_hint_id.clone();
 6756        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6757        let query_version = lsp_data.buffer_version.clone();
 6758        let mut lsp_refresh_requested = false;
 6759        let for_server = if let InvalidationStrategy::RefreshRequested {
 6760            server_id,
 6761            request_id,
 6762        } = invalidate
 6763        {
 6764            let invalidated = lsp_data
 6765                .inlay_hints
 6766                .invalidate_for_server_refresh(server_id, request_id);
 6767            lsp_refresh_requested = invalidated;
 6768            Some(server_id)
 6769        } else {
 6770            None
 6771        };
 6772        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6773        let known_chunks = known_chunks
 6774            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6775            .map(|(_, known_chunks)| known_chunks)
 6776            .unwrap_or_default();
 6777
 6778        let mut hint_fetch_tasks = Vec::new();
 6779        let mut cached_inlay_hints = None;
 6780        let mut ranges_to_query = None;
 6781        let applicable_chunks = existing_inlay_hints
 6782            .applicable_chunks(ranges.as_slice())
 6783            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 6784            .collect::<Vec<_>>();
 6785        if applicable_chunks.is_empty() {
 6786            return HashMap::default();
 6787        }
 6788
 6789        for row_chunk in applicable_chunks {
 6790            match (
 6791                existing_inlay_hints
 6792                    .cached_hints(&row_chunk)
 6793                    .filter(|_| !lsp_refresh_requested)
 6794                    .cloned(),
 6795                existing_inlay_hints
 6796                    .fetched_hints(&row_chunk)
 6797                    .as_ref()
 6798                    .filter(|_| !lsp_refresh_requested)
 6799                    .cloned(),
 6800            ) {
 6801                (None, None) => {
 6802                    let Some(chunk_range) = existing_inlay_hints.chunk_range(row_chunk) else {
 6803                        continue;
 6804                    };
 6805                    ranges_to_query
 6806                        .get_or_insert_with(Vec::new)
 6807                        .push((row_chunk, chunk_range));
 6808                }
 6809                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 6810                (Some(cached_hints), None) => {
 6811                    for (server_id, cached_hints) in cached_hints {
 6812                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6813                            cached_inlay_hints
 6814                                .get_or_insert_with(HashMap::default)
 6815                                .entry(row_chunk.row_range())
 6816                                .or_insert_with(HashMap::default)
 6817                                .entry(server_id)
 6818                                .or_insert_with(Vec::new)
 6819                                .extend(cached_hints);
 6820                        }
 6821                    }
 6822                }
 6823                (Some(cached_hints), Some(fetched_hints)) => {
 6824                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 6825                    for (server_id, cached_hints) in cached_hints {
 6826                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6827                            cached_inlay_hints
 6828                                .get_or_insert_with(HashMap::default)
 6829                                .entry(row_chunk.row_range())
 6830                                .or_insert_with(HashMap::default)
 6831                                .entry(server_id)
 6832                                .or_insert_with(Vec::new)
 6833                                .extend(cached_hints);
 6834                        }
 6835                    }
 6836                }
 6837            }
 6838        }
 6839
 6840        if hint_fetch_tasks.is_empty()
 6841            && ranges_to_query
 6842                .as_ref()
 6843                .is_none_or(|ranges| ranges.is_empty())
 6844            && let Some(cached_inlay_hints) = cached_inlay_hints
 6845        {
 6846            cached_inlay_hints
 6847                .into_iter()
 6848                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 6849                .collect()
 6850        } else {
 6851            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 6852                let next_hint_id = next_hint_id.clone();
 6853                let buffer = buffer.clone();
 6854                let query_version = query_version.clone();
 6855                let new_inlay_hints = cx
 6856                    .spawn(async move |lsp_store, cx| {
 6857                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 6858                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 6859                        })?;
 6860                        new_fetch_task
 6861                            .await
 6862                            .and_then(|new_hints_by_server| {
 6863                                lsp_store.update(cx, |lsp_store, cx| {
 6864                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 6865                                    let update_cache = lsp_data.buffer_version == query_version;
 6866                                    if new_hints_by_server.is_empty() {
 6867                                        if update_cache {
 6868                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 6869                                        }
 6870                                        HashMap::default()
 6871                                    } else {
 6872                                        new_hints_by_server
 6873                                            .into_iter()
 6874                                            .map(|(server_id, new_hints)| {
 6875                                                let new_hints = new_hints
 6876                                                    .into_iter()
 6877                                                    .map(|new_hint| {
 6878                                                        (
 6879                                                            InlayId::Hint(next_hint_id.fetch_add(
 6880                                                                1,
 6881                                                                atomic::Ordering::AcqRel,
 6882                                                            )),
 6883                                                            new_hint,
 6884                                                        )
 6885                                                    })
 6886                                                    .collect::<Vec<_>>();
 6887                                                if update_cache {
 6888                                                    lsp_data.inlay_hints.insert_new_hints(
 6889                                                        chunk,
 6890                                                        server_id,
 6891                                                        new_hints.clone(),
 6892                                                    );
 6893                                                }
 6894                                                (server_id, new_hints)
 6895                                            })
 6896                                            .collect()
 6897                                    }
 6898                                })
 6899                            })
 6900                            .map_err(Arc::new)
 6901                    })
 6902                    .shared();
 6903
 6904                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 6905                *fetch_task = Some(new_inlay_hints.clone());
 6906                hint_fetch_tasks.push((chunk, new_inlay_hints));
 6907            }
 6908
 6909            cached_inlay_hints
 6910                .unwrap_or_default()
 6911                .into_iter()
 6912                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 6913                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 6914                    (
 6915                        chunk.row_range(),
 6916                        cx.spawn(async move |_, _| {
 6917                            hints_fetch.await.map_err(|e| {
 6918                                if e.error_code() != ErrorCode::Internal {
 6919                                    anyhow!(e.error_code())
 6920                                } else {
 6921                                    anyhow!("{e:#}")
 6922                                }
 6923                            })
 6924                        }),
 6925                    )
 6926                }))
 6927                .collect()
 6928        }
 6929    }
 6930
 6931    fn fetch_inlay_hints(
 6932        &mut self,
 6933        for_server: Option<LanguageServerId>,
 6934        buffer: &Entity<Buffer>,
 6935        range: Range<Anchor>,
 6936        cx: &mut Context<Self>,
 6937    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 6938        let request = InlayHints {
 6939            range: range.clone(),
 6940        };
 6941        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6942            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6943                return Task::ready(Ok(HashMap::default()));
 6944            }
 6945            let request_task = upstream_client.request_lsp(
 6946                project_id,
 6947                for_server.map(|id| id.to_proto()),
 6948                LSP_REQUEST_TIMEOUT,
 6949                cx.background_executor().clone(),
 6950                request.to_proto(project_id, buffer.read(cx)),
 6951            );
 6952            let buffer = buffer.clone();
 6953            cx.spawn(async move |weak_lsp_store, cx| {
 6954                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6955                    return Ok(HashMap::default());
 6956                };
 6957                let Some(responses) = request_task.await? else {
 6958                    return Ok(HashMap::default());
 6959                };
 6960
 6961                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 6962                    let lsp_store = lsp_store.clone();
 6963                    let buffer = buffer.clone();
 6964                    let cx = cx.clone();
 6965                    let request = request.clone();
 6966                    async move {
 6967                        (
 6968                            LanguageServerId::from_proto(response.server_id),
 6969                            request
 6970                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6971                                .await,
 6972                        )
 6973                    }
 6974                }))
 6975                .await;
 6976
 6977                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot())?;
 6978                let mut has_errors = false;
 6979                let inlay_hints = inlay_hints
 6980                    .into_iter()
 6981                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 6982                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 6983                        Err(e) => {
 6984                            has_errors = true;
 6985                            log::error!("{e:#}");
 6986                            None
 6987                        }
 6988                    })
 6989                    .map(|(server_id, mut new_hints)| {
 6990                        new_hints.retain(|hint| {
 6991                            hint.position.is_valid(&buffer_snapshot)
 6992                                && range.start.is_valid(&buffer_snapshot)
 6993                                && range.end.is_valid(&buffer_snapshot)
 6994                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 6995                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 6996                        });
 6997                        (server_id, new_hints)
 6998                    })
 6999                    .collect::<HashMap<_, _>>();
 7000                anyhow::ensure!(
 7001                    !has_errors || !inlay_hints.is_empty(),
 7002                    "Failed to fetch inlay hints"
 7003                );
 7004                Ok(inlay_hints)
 7005            })
 7006        } else {
 7007            let inlay_hints_task = match for_server {
 7008                Some(server_id) => {
 7009                    let server_task = self.request_lsp(
 7010                        buffer.clone(),
 7011                        LanguageServerToQuery::Other(server_id),
 7012                        request,
 7013                        cx,
 7014                    );
 7015                    cx.background_spawn(async move {
 7016                        let mut responses = Vec::new();
 7017                        match server_task.await {
 7018                            Ok(response) => responses.push((server_id, response)),
 7019                            // rust-analyzer likes to error with this when its still loading up
 7020                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7021                            Err(e) => log::error!(
 7022                                "Error handling response for inlay hints request: {e:#}"
 7023                            ),
 7024                        }
 7025                        responses
 7026                    })
 7027                }
 7028                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7029            };
 7030            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7031            cx.background_spawn(async move {
 7032                Ok(inlay_hints_task
 7033                    .await
 7034                    .into_iter()
 7035                    .map(|(server_id, mut new_hints)| {
 7036                        new_hints.retain(|hint| {
 7037                            hint.position.is_valid(&buffer_snapshot)
 7038                                && range.start.is_valid(&buffer_snapshot)
 7039                                && range.end.is_valid(&buffer_snapshot)
 7040                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7041                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7042                        });
 7043                        (server_id, new_hints)
 7044                    })
 7045                    .collect())
 7046            })
 7047        }
 7048    }
 7049
 7050    pub fn pull_diagnostics_for_buffer(
 7051        &mut self,
 7052        buffer: Entity<Buffer>,
 7053        cx: &mut Context<Self>,
 7054    ) -> Task<anyhow::Result<()>> {
 7055        let diagnostics = self.pull_diagnostics(buffer, cx);
 7056        cx.spawn(async move |lsp_store, cx| {
 7057            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7058                return Ok(());
 7059            };
 7060            lsp_store.update(cx, |lsp_store, cx| {
 7061                if lsp_store.as_local().is_none() {
 7062                    return;
 7063                }
 7064
 7065                let mut unchanged_buffers = HashSet::default();
 7066                let mut changed_buffers = HashSet::default();
 7067                let server_diagnostics_updates = diagnostics
 7068                    .into_iter()
 7069                    .filter_map(|diagnostics_set| match diagnostics_set {
 7070                        LspPullDiagnostics::Response {
 7071                            server_id,
 7072                            uri,
 7073                            diagnostics,
 7074                        } => Some((server_id, uri, diagnostics)),
 7075                        LspPullDiagnostics::Default => None,
 7076                    })
 7077                    .fold(
 7078                        HashMap::default(),
 7079                        |mut acc, (server_id, uri, diagnostics)| {
 7080                            let (result_id, diagnostics) = match diagnostics {
 7081                                PulledDiagnostics::Unchanged { result_id } => {
 7082                                    unchanged_buffers.insert(uri.clone());
 7083                                    (Some(result_id), Vec::new())
 7084                                }
 7085                                PulledDiagnostics::Changed {
 7086                                    result_id,
 7087                                    diagnostics,
 7088                                } => {
 7089                                    changed_buffers.insert(uri.clone());
 7090                                    (result_id, diagnostics)
 7091                                }
 7092                            };
 7093                            let disk_based_sources = Cow::Owned(
 7094                                lsp_store
 7095                                    .language_server_adapter_for_id(server_id)
 7096                                    .as_ref()
 7097                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7098                                    .unwrap_or(&[])
 7099                                    .to_vec(),
 7100                            );
 7101                            acc.entry(server_id).or_insert_with(Vec::new).push(
 7102                                DocumentDiagnosticsUpdate {
 7103                                    server_id,
 7104                                    diagnostics: lsp::PublishDiagnosticsParams {
 7105                                        uri,
 7106                                        diagnostics,
 7107                                        version: None,
 7108                                    },
 7109                                    result_id,
 7110                                    disk_based_sources,
 7111                                },
 7112                            );
 7113                            acc
 7114                        },
 7115                    );
 7116
 7117                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7118                    lsp_store
 7119                        .merge_lsp_diagnostics(
 7120                            DiagnosticSourceKind::Pulled,
 7121                            diagnostic_updates,
 7122                            |buffer, old_diagnostic, cx| {
 7123                                File::from_dyn(buffer.file())
 7124                                    .and_then(|file| {
 7125                                        let abs_path = file.as_local()?.abs_path(cx);
 7126                                        lsp::Uri::from_file_path(abs_path).ok()
 7127                                    })
 7128                                    .is_none_or(|buffer_uri| {
 7129                                        unchanged_buffers.contains(&buffer_uri)
 7130                                            || match old_diagnostic.source_kind {
 7131                                                DiagnosticSourceKind::Pulled => {
 7132                                                    !changed_buffers.contains(&buffer_uri)
 7133                                                }
 7134                                                DiagnosticSourceKind::Other
 7135                                                | DiagnosticSourceKind::Pushed => true,
 7136                                            }
 7137                                    })
 7138                            },
 7139                            cx,
 7140                        )
 7141                        .log_err();
 7142                }
 7143            })
 7144        })
 7145    }
 7146
 7147    pub fn document_colors(
 7148        &mut self,
 7149        known_cache_version: Option<usize>,
 7150        buffer: Entity<Buffer>,
 7151        cx: &mut Context<Self>,
 7152    ) -> Option<DocumentColorTask> {
 7153        let version_queried_for = buffer.read(cx).version();
 7154        let buffer_id = buffer.read(cx).remote_id();
 7155
 7156        let current_language_servers = self.as_local().map(|local| {
 7157            local
 7158                .buffers_opened_in_servers
 7159                .get(&buffer_id)
 7160                .cloned()
 7161                .unwrap_or_default()
 7162        });
 7163
 7164        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7165            if let Some(cached_colors) = &lsp_data.document_colors {
 7166                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7167                    let has_different_servers =
 7168                        current_language_servers.is_some_and(|current_language_servers| {
 7169                            current_language_servers
 7170                                != cached_colors.colors.keys().copied().collect()
 7171                        });
 7172                    if !has_different_servers {
 7173                        let cache_version = cached_colors.cache_version;
 7174                        if Some(cache_version) == known_cache_version {
 7175                            return None;
 7176                        } else {
 7177                            return Some(
 7178                                Task::ready(Ok(DocumentColors {
 7179                                    colors: cached_colors
 7180                                        .colors
 7181                                        .values()
 7182                                        .flatten()
 7183                                        .cloned()
 7184                                        .collect(),
 7185                                    cache_version: Some(cache_version),
 7186                                }))
 7187                                .shared(),
 7188                            );
 7189                        }
 7190                    }
 7191                }
 7192            }
 7193        }
 7194
 7195        let color_lsp_data = self
 7196            .latest_lsp_data(&buffer, cx)
 7197            .document_colors
 7198            .get_or_insert_default();
 7199        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7200            && !version_queried_for.changed_since(updating_for)
 7201        {
 7202            return Some(running_update.clone());
 7203        }
 7204        let buffer_version_queried_for = version_queried_for.clone();
 7205        let new_task = cx
 7206            .spawn(async move |lsp_store, cx| {
 7207                cx.background_executor()
 7208                    .timer(Duration::from_millis(30))
 7209                    .await;
 7210                let fetched_colors = lsp_store
 7211                    .update(cx, |lsp_store, cx| {
 7212                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7213                    })?
 7214                    .await
 7215                    .context("fetching document colors")
 7216                    .map_err(Arc::new);
 7217                let fetched_colors = match fetched_colors {
 7218                    Ok(fetched_colors) => {
 7219                        if Some(true)
 7220                            == buffer
 7221                                .update(cx, |buffer, _| {
 7222                                    buffer.version() != buffer_version_queried_for
 7223                                })
 7224                                .ok()
 7225                        {
 7226                            return Ok(DocumentColors::default());
 7227                        }
 7228                        fetched_colors
 7229                    }
 7230                    Err(e) => {
 7231                        lsp_store
 7232                            .update(cx, |lsp_store, _| {
 7233                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7234                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7235                                        document_colors.colors_update = None;
 7236                                    }
 7237                                }
 7238                            })
 7239                            .ok();
 7240                        return Err(e);
 7241                    }
 7242                };
 7243
 7244                lsp_store
 7245                    .update(cx, |lsp_store, cx| {
 7246                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7247                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7248
 7249                        if let Some(fetched_colors) = fetched_colors {
 7250                            if lsp_data.buffer_version == buffer_version_queried_for {
 7251                                lsp_colors.colors.extend(fetched_colors);
 7252                                lsp_colors.cache_version += 1;
 7253                            } else if !lsp_data
 7254                                .buffer_version
 7255                                .changed_since(&buffer_version_queried_for)
 7256                            {
 7257                                lsp_data.buffer_version = buffer_version_queried_for;
 7258                                lsp_colors.colors = fetched_colors;
 7259                                lsp_colors.cache_version += 1;
 7260                            }
 7261                        }
 7262                        lsp_colors.colors_update = None;
 7263                        let colors = lsp_colors
 7264                            .colors
 7265                            .values()
 7266                            .flatten()
 7267                            .cloned()
 7268                            .collect::<HashSet<_>>();
 7269                        DocumentColors {
 7270                            colors,
 7271                            cache_version: Some(lsp_colors.cache_version),
 7272                        }
 7273                    })
 7274                    .map_err(Arc::new)
 7275            })
 7276            .shared();
 7277        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7278        Some(new_task)
 7279    }
 7280
 7281    fn fetch_document_colors_for_buffer(
 7282        &mut self,
 7283        buffer: &Entity<Buffer>,
 7284        cx: &mut Context<Self>,
 7285    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7286        if let Some((client, project_id)) = self.upstream_client() {
 7287            let request = GetDocumentColor {};
 7288            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7289                return Task::ready(Ok(None));
 7290            }
 7291
 7292            let request_task = client.request_lsp(
 7293                project_id,
 7294                None,
 7295                LSP_REQUEST_TIMEOUT,
 7296                cx.background_executor().clone(),
 7297                request.to_proto(project_id, buffer.read(cx)),
 7298            );
 7299            let buffer = buffer.clone();
 7300            cx.spawn(async move |lsp_store, cx| {
 7301                let Some(lsp_store) = lsp_store.upgrade() else {
 7302                    return Ok(None);
 7303                };
 7304                let colors = join_all(
 7305                    request_task
 7306                        .await
 7307                        .log_err()
 7308                        .flatten()
 7309                        .map(|response| response.payload)
 7310                        .unwrap_or_default()
 7311                        .into_iter()
 7312                        .map(|color_response| {
 7313                            let response = request.response_from_proto(
 7314                                color_response.response,
 7315                                lsp_store.clone(),
 7316                                buffer.clone(),
 7317                                cx.clone(),
 7318                            );
 7319                            async move {
 7320                                (
 7321                                    LanguageServerId::from_proto(color_response.server_id),
 7322                                    response.await.log_err().unwrap_or_default(),
 7323                                )
 7324                            }
 7325                        }),
 7326                )
 7327                .await
 7328                .into_iter()
 7329                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7330                    acc.entry(server_id)
 7331                        .or_insert_with(HashSet::default)
 7332                        .extend(colors);
 7333                    acc
 7334                });
 7335                Ok(Some(colors))
 7336            })
 7337        } else {
 7338            let document_colors_task =
 7339                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7340            cx.background_spawn(async move {
 7341                Ok(Some(
 7342                    document_colors_task
 7343                        .await
 7344                        .into_iter()
 7345                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7346                            acc.entry(server_id)
 7347                                .or_insert_with(HashSet::default)
 7348                                .extend(colors);
 7349                            acc
 7350                        })
 7351                        .into_iter()
 7352                        .collect(),
 7353                ))
 7354            })
 7355        }
 7356    }
 7357
 7358    pub fn signature_help<T: ToPointUtf16>(
 7359        &mut self,
 7360        buffer: &Entity<Buffer>,
 7361        position: T,
 7362        cx: &mut Context<Self>,
 7363    ) -> Task<Option<Vec<SignatureHelp>>> {
 7364        let position = position.to_point_utf16(buffer.read(cx));
 7365
 7366        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7367            let request = GetSignatureHelp { position };
 7368            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7369                return Task::ready(None);
 7370            }
 7371            let request_task = client.request_lsp(
 7372                upstream_project_id,
 7373                None,
 7374                LSP_REQUEST_TIMEOUT,
 7375                cx.background_executor().clone(),
 7376                request.to_proto(upstream_project_id, buffer.read(cx)),
 7377            );
 7378            let buffer = buffer.clone();
 7379            cx.spawn(async move |weak_lsp_store, cx| {
 7380                let lsp_store = weak_lsp_store.upgrade()?;
 7381                let signatures = join_all(
 7382                    request_task
 7383                        .await
 7384                        .log_err()
 7385                        .flatten()
 7386                        .map(|response| response.payload)
 7387                        .unwrap_or_default()
 7388                        .into_iter()
 7389                        .map(|response| {
 7390                            let response = GetSignatureHelp { position }.response_from_proto(
 7391                                response.response,
 7392                                lsp_store.clone(),
 7393                                buffer.clone(),
 7394                                cx.clone(),
 7395                            );
 7396                            async move { response.await.log_err().flatten() }
 7397                        }),
 7398                )
 7399                .await
 7400                .into_iter()
 7401                .flatten()
 7402                .collect();
 7403                Some(signatures)
 7404            })
 7405        } else {
 7406            let all_actions_task = self.request_multiple_lsp_locally(
 7407                buffer,
 7408                Some(position),
 7409                GetSignatureHelp { position },
 7410                cx,
 7411            );
 7412            cx.background_spawn(async move {
 7413                Some(
 7414                    all_actions_task
 7415                        .await
 7416                        .into_iter()
 7417                        .flat_map(|(_, actions)| actions)
 7418                        .collect::<Vec<_>>(),
 7419                )
 7420            })
 7421        }
 7422    }
 7423
 7424    pub fn hover(
 7425        &mut self,
 7426        buffer: &Entity<Buffer>,
 7427        position: PointUtf16,
 7428        cx: &mut Context<Self>,
 7429    ) -> Task<Option<Vec<Hover>>> {
 7430        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7431            let request = GetHover { position };
 7432            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7433                return Task::ready(None);
 7434            }
 7435            let request_task = client.request_lsp(
 7436                upstream_project_id,
 7437                None,
 7438                LSP_REQUEST_TIMEOUT,
 7439                cx.background_executor().clone(),
 7440                request.to_proto(upstream_project_id, buffer.read(cx)),
 7441            );
 7442            let buffer = buffer.clone();
 7443            cx.spawn(async move |weak_lsp_store, cx| {
 7444                let lsp_store = weak_lsp_store.upgrade()?;
 7445                let hovers = join_all(
 7446                    request_task
 7447                        .await
 7448                        .log_err()
 7449                        .flatten()
 7450                        .map(|response| response.payload)
 7451                        .unwrap_or_default()
 7452                        .into_iter()
 7453                        .map(|response| {
 7454                            let response = GetHover { position }.response_from_proto(
 7455                                response.response,
 7456                                lsp_store.clone(),
 7457                                buffer.clone(),
 7458                                cx.clone(),
 7459                            );
 7460                            async move {
 7461                                response
 7462                                    .await
 7463                                    .log_err()
 7464                                    .flatten()
 7465                                    .and_then(remove_empty_hover_blocks)
 7466                            }
 7467                        }),
 7468                )
 7469                .await
 7470                .into_iter()
 7471                .flatten()
 7472                .collect();
 7473                Some(hovers)
 7474            })
 7475        } else {
 7476            let all_actions_task = self.request_multiple_lsp_locally(
 7477                buffer,
 7478                Some(position),
 7479                GetHover { position },
 7480                cx,
 7481            );
 7482            cx.background_spawn(async move {
 7483                Some(
 7484                    all_actions_task
 7485                        .await
 7486                        .into_iter()
 7487                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7488                        .collect::<Vec<Hover>>(),
 7489                )
 7490            })
 7491        }
 7492    }
 7493
 7494    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7495        let language_registry = self.languages.clone();
 7496
 7497        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7498            let request = upstream_client.request(proto::GetProjectSymbols {
 7499                project_id: *project_id,
 7500                query: query.to_string(),
 7501            });
 7502            cx.foreground_executor().spawn(async move {
 7503                let response = request.await?;
 7504                let mut symbols = Vec::new();
 7505                let core_symbols = response
 7506                    .symbols
 7507                    .into_iter()
 7508                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7509                    .collect::<Vec<_>>();
 7510                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7511                    .await;
 7512                Ok(symbols)
 7513            })
 7514        } else if let Some(local) = self.as_local() {
 7515            struct WorkspaceSymbolsResult {
 7516                server_id: LanguageServerId,
 7517                lsp_adapter: Arc<CachedLspAdapter>,
 7518                worktree: WeakEntity<Worktree>,
 7519                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7520            }
 7521
 7522            let mut requests = Vec::new();
 7523            let mut requested_servers = BTreeSet::new();
 7524            for (seed, state) in local.language_server_ids.iter() {
 7525                let Some(worktree_handle) = self
 7526                    .worktree_store
 7527                    .read(cx)
 7528                    .worktree_for_id(seed.worktree_id, cx)
 7529                else {
 7530                    continue;
 7531                };
 7532                let worktree = worktree_handle.read(cx);
 7533                if !worktree.is_visible() {
 7534                    continue;
 7535                }
 7536
 7537                if !requested_servers.insert(state.id) {
 7538                    continue;
 7539                }
 7540
 7541                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7542                    Some(LanguageServerState::Running {
 7543                        adapter, server, ..
 7544                    }) => (adapter.clone(), server),
 7545
 7546                    _ => continue,
 7547                };
 7548                let supports_workspace_symbol_request =
 7549                    match server.capabilities().workspace_symbol_provider {
 7550                        Some(OneOf::Left(supported)) => supported,
 7551                        Some(OneOf::Right(_)) => true,
 7552                        None => false,
 7553                    };
 7554                if !supports_workspace_symbol_request {
 7555                    continue;
 7556                }
 7557                let worktree_handle = worktree_handle.clone();
 7558                let server_id = server.server_id();
 7559                requests.push(
 7560                        server
 7561                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7562                                lsp::WorkspaceSymbolParams {
 7563                                    query: query.to_string(),
 7564                                    ..Default::default()
 7565                                },
 7566                            )
 7567                            .map(move |response| {
 7568                                let lsp_symbols = response.into_response()
 7569                                    .context("workspace symbols request")
 7570                                    .log_err()
 7571                                    .flatten()
 7572                                    .map(|symbol_response| match symbol_response {
 7573                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7574                                            flat_responses.into_iter().map(|lsp_symbol| {
 7575                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7576                                            }).collect::<Vec<_>>()
 7577                                        }
 7578                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7579                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7580                                                let location = match lsp_symbol.location {
 7581                                                    OneOf::Left(location) => location,
 7582                                                    OneOf::Right(_) => {
 7583                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7584                                                        return None
 7585                                                    }
 7586                                                };
 7587                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7588                                            }).collect::<Vec<_>>()
 7589                                        }
 7590                                    }).unwrap_or_default();
 7591
 7592                                WorkspaceSymbolsResult {
 7593                                    server_id,
 7594                                    lsp_adapter,
 7595                                    worktree: worktree_handle.downgrade(),
 7596                                    lsp_symbols,
 7597                                }
 7598                            }),
 7599                    );
 7600            }
 7601
 7602            cx.spawn(async move |this, cx| {
 7603                let responses = futures::future::join_all(requests).await;
 7604                let this = match this.upgrade() {
 7605                    Some(this) => this,
 7606                    None => return Ok(Vec::new()),
 7607                };
 7608
 7609                let mut symbols = Vec::new();
 7610                for result in responses {
 7611                    let core_symbols = this.update(cx, |this, cx| {
 7612                        result
 7613                            .lsp_symbols
 7614                            .into_iter()
 7615                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7616                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7617                                let source_worktree = result.worktree.upgrade()?;
 7618                                let source_worktree_id = source_worktree.read(cx).id();
 7619
 7620                                let path = if let Some((tree, rel_path)) =
 7621                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7622                                {
 7623                                    let worktree_id = tree.read(cx).id();
 7624                                    SymbolLocation::InProject(ProjectPath {
 7625                                        worktree_id,
 7626                                        path: rel_path,
 7627                                    })
 7628                                } else {
 7629                                    SymbolLocation::OutsideProject {
 7630                                        signature: this.symbol_signature(&abs_path),
 7631                                        abs_path: abs_path.into(),
 7632                                    }
 7633                                };
 7634
 7635                                Some(CoreSymbol {
 7636                                    source_language_server_id: result.server_id,
 7637                                    language_server_name: result.lsp_adapter.name.clone(),
 7638                                    source_worktree_id,
 7639                                    path,
 7640                                    kind: symbol_kind,
 7641                                    name: symbol_name,
 7642                                    range: range_from_lsp(symbol_location.range),
 7643                                })
 7644                            })
 7645                            .collect()
 7646                    })?;
 7647
 7648                    populate_labels_for_symbols(
 7649                        core_symbols,
 7650                        &language_registry,
 7651                        Some(result.lsp_adapter),
 7652                        &mut symbols,
 7653                    )
 7654                    .await;
 7655                }
 7656
 7657                Ok(symbols)
 7658            })
 7659        } else {
 7660            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7661        }
 7662    }
 7663
 7664    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7665        let mut summary = DiagnosticSummary::default();
 7666        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7667            summary.error_count += path_summary.error_count;
 7668            summary.warning_count += path_summary.warning_count;
 7669        }
 7670        summary
 7671    }
 7672
 7673    /// Returns the diagnostic summary for a specific project path.
 7674    pub fn diagnostic_summary_for_path(
 7675        &self,
 7676        project_path: &ProjectPath,
 7677        _: &App,
 7678    ) -> DiagnosticSummary {
 7679        if let Some(summaries) = self
 7680            .diagnostic_summaries
 7681            .get(&project_path.worktree_id)
 7682            .and_then(|map| map.get(&project_path.path))
 7683        {
 7684            let (error_count, warning_count) = summaries.iter().fold(
 7685                (0, 0),
 7686                |(error_count, warning_count), (_language_server_id, summary)| {
 7687                    (
 7688                        error_count + summary.error_count,
 7689                        warning_count + summary.warning_count,
 7690                    )
 7691                },
 7692            );
 7693
 7694            DiagnosticSummary {
 7695                error_count,
 7696                warning_count,
 7697            }
 7698        } else {
 7699            DiagnosticSummary::default()
 7700        }
 7701    }
 7702
 7703    pub fn diagnostic_summaries<'a>(
 7704        &'a self,
 7705        include_ignored: bool,
 7706        cx: &'a App,
 7707    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7708        self.worktree_store
 7709            .read(cx)
 7710            .visible_worktrees(cx)
 7711            .filter_map(|worktree| {
 7712                let worktree = worktree.read(cx);
 7713                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7714            })
 7715            .flat_map(move |(worktree, summaries)| {
 7716                let worktree_id = worktree.id();
 7717                summaries
 7718                    .iter()
 7719                    .filter(move |(path, _)| {
 7720                        include_ignored
 7721                            || worktree
 7722                                .entry_for_path(path.as_ref())
 7723                                .is_some_and(|entry| !entry.is_ignored)
 7724                    })
 7725                    .flat_map(move |(path, summaries)| {
 7726                        summaries.iter().map(move |(server_id, summary)| {
 7727                            (
 7728                                ProjectPath {
 7729                                    worktree_id,
 7730                                    path: path.clone(),
 7731                                },
 7732                                *server_id,
 7733                                *summary,
 7734                            )
 7735                        })
 7736                    })
 7737            })
 7738    }
 7739
 7740    pub fn on_buffer_edited(
 7741        &mut self,
 7742        buffer: Entity<Buffer>,
 7743        cx: &mut Context<Self>,
 7744    ) -> Option<()> {
 7745        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7746            Some(
 7747                self.as_local()?
 7748                    .language_servers_for_buffer(buffer, cx)
 7749                    .map(|i| i.1.clone())
 7750                    .collect(),
 7751            )
 7752        })?;
 7753
 7754        let buffer = buffer.read(cx);
 7755        let file = File::from_dyn(buffer.file())?;
 7756        let abs_path = file.as_local()?.abs_path(cx);
 7757        let uri = lsp::Uri::from_file_path(&abs_path)
 7758            .ok()
 7759            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7760            .log_err()?;
 7761        let next_snapshot = buffer.text_snapshot();
 7762        for language_server in language_servers {
 7763            let language_server = language_server.clone();
 7764
 7765            let buffer_snapshots = self
 7766                .as_local_mut()?
 7767                .buffer_snapshots
 7768                .get_mut(&buffer.remote_id())
 7769                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7770            let previous_snapshot = buffer_snapshots.last()?;
 7771
 7772            let build_incremental_change = || {
 7773                buffer
 7774                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7775                        previous_snapshot.snapshot.version(),
 7776                    )
 7777                    .map(|edit| {
 7778                        let edit_start = edit.new.start.0;
 7779                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7780                        let new_text = next_snapshot
 7781                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7782                            .collect();
 7783                        lsp::TextDocumentContentChangeEvent {
 7784                            range: Some(lsp::Range::new(
 7785                                point_to_lsp(edit_start),
 7786                                point_to_lsp(edit_end),
 7787                            )),
 7788                            range_length: None,
 7789                            text: new_text,
 7790                        }
 7791                    })
 7792                    .collect()
 7793            };
 7794
 7795            let document_sync_kind = language_server
 7796                .capabilities()
 7797                .text_document_sync
 7798                .as_ref()
 7799                .and_then(|sync| match sync {
 7800                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7801                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7802                });
 7803
 7804            let content_changes: Vec<_> = match document_sync_kind {
 7805                Some(lsp::TextDocumentSyncKind::FULL) => {
 7806                    vec![lsp::TextDocumentContentChangeEvent {
 7807                        range: None,
 7808                        range_length: None,
 7809                        text: next_snapshot.text(),
 7810                    }]
 7811                }
 7812                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7813                _ => {
 7814                    #[cfg(any(test, feature = "test-support"))]
 7815                    {
 7816                        build_incremental_change()
 7817                    }
 7818
 7819                    #[cfg(not(any(test, feature = "test-support")))]
 7820                    {
 7821                        continue;
 7822                    }
 7823                }
 7824            };
 7825
 7826            let next_version = previous_snapshot.version + 1;
 7827            buffer_snapshots.push(LspBufferSnapshot {
 7828                version: next_version,
 7829                snapshot: next_snapshot.clone(),
 7830            });
 7831
 7832            language_server
 7833                .notify::<lsp::notification::DidChangeTextDocument>(
 7834                    lsp::DidChangeTextDocumentParams {
 7835                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7836                            uri.clone(),
 7837                            next_version,
 7838                        ),
 7839                        content_changes,
 7840                    },
 7841                )
 7842                .ok();
 7843            self.pull_workspace_diagnostics(language_server.server_id());
 7844        }
 7845
 7846        None
 7847    }
 7848
 7849    pub fn on_buffer_saved(
 7850        &mut self,
 7851        buffer: Entity<Buffer>,
 7852        cx: &mut Context<Self>,
 7853    ) -> Option<()> {
 7854        let file = File::from_dyn(buffer.read(cx).file())?;
 7855        let worktree_id = file.worktree_id(cx);
 7856        let abs_path = file.as_local()?.abs_path(cx);
 7857        let text_document = lsp::TextDocumentIdentifier {
 7858            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7859        };
 7860        let local = self.as_local()?;
 7861
 7862        for server in local.language_servers_for_worktree(worktree_id) {
 7863            if let Some(include_text) = include_text(server.as_ref()) {
 7864                let text = if include_text {
 7865                    Some(buffer.read(cx).text())
 7866                } else {
 7867                    None
 7868                };
 7869                server
 7870                    .notify::<lsp::notification::DidSaveTextDocument>(
 7871                        lsp::DidSaveTextDocumentParams {
 7872                            text_document: text_document.clone(),
 7873                            text,
 7874                        },
 7875                    )
 7876                    .ok();
 7877            }
 7878        }
 7879
 7880        let language_servers = buffer.update(cx, |buffer, cx| {
 7881            local.language_server_ids_for_buffer(buffer, cx)
 7882        });
 7883        for language_server_id in language_servers {
 7884            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7885        }
 7886
 7887        None
 7888    }
 7889
 7890    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 7891        maybe!(async move {
 7892            let mut refreshed_servers = HashSet::default();
 7893            let servers = lsp_store
 7894                .update(cx, |lsp_store, cx| {
 7895                    let local = lsp_store.as_local()?;
 7896
 7897                    let servers = local
 7898                        .language_server_ids
 7899                        .iter()
 7900                        .filter_map(|(seed, state)| {
 7901                            let worktree = lsp_store
 7902                                .worktree_store
 7903                                .read(cx)
 7904                                .worktree_for_id(seed.worktree_id, cx);
 7905                            let delegate: Arc<dyn LspAdapterDelegate> =
 7906                                worktree.map(|worktree| {
 7907                                    LocalLspAdapterDelegate::new(
 7908                                        local.languages.clone(),
 7909                                        &local.environment,
 7910                                        cx.weak_entity(),
 7911                                        &worktree,
 7912                                        local.http_client.clone(),
 7913                                        local.fs.clone(),
 7914                                        cx,
 7915                                    )
 7916                                })?;
 7917                            let server_id = state.id;
 7918
 7919                            let states = local.language_servers.get(&server_id)?;
 7920
 7921                            match states {
 7922                                LanguageServerState::Starting { .. } => None,
 7923                                LanguageServerState::Running {
 7924                                    adapter, server, ..
 7925                                } => {
 7926                                    let adapter = adapter.clone();
 7927                                    let server = server.clone();
 7928                                    refreshed_servers.insert(server.name());
 7929                                    let toolchain = seed.toolchain.clone();
 7930                                    Some(cx.spawn(async move |_, cx| {
 7931                                        let settings =
 7932                                            LocalLspStore::workspace_configuration_for_adapter(
 7933                                                adapter.adapter.clone(),
 7934                                                &delegate,
 7935                                                toolchain,
 7936                                                cx,
 7937                                            )
 7938                                            .await
 7939                                            .ok()?;
 7940                                        server
 7941                                            .notify::<lsp::notification::DidChangeConfiguration>(
 7942                                                lsp::DidChangeConfigurationParams { settings },
 7943                                            )
 7944                                            .ok()?;
 7945                                        Some(())
 7946                                    }))
 7947                                }
 7948                            }
 7949                        })
 7950                        .collect::<Vec<_>>();
 7951
 7952                    Some(servers)
 7953                })
 7954                .ok()
 7955                .flatten()?;
 7956
 7957            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 7958            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 7959            // to stop and unregister its language server wrapper.
 7960            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 7961            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 7962            let _: Vec<Option<()>> = join_all(servers).await;
 7963
 7964            Some(())
 7965        })
 7966        .await;
 7967    }
 7968
 7969    fn maintain_workspace_config(
 7970        external_refresh_requests: watch::Receiver<()>,
 7971        cx: &mut Context<Self>,
 7972    ) -> Task<Result<()>> {
 7973        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 7974        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 7975
 7976        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 7977            *settings_changed_tx.borrow_mut() = ();
 7978        });
 7979
 7980        let mut joint_future =
 7981            futures::stream::select(settings_changed_rx, external_refresh_requests);
 7982        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 7983        // - 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).
 7984        // - 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.
 7985        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 7986        // - 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,
 7987        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 7988        cx.spawn(async move |this, cx| {
 7989            while let Some(()) = joint_future.next().await {
 7990                this.update(cx, |this, cx| {
 7991                    this.refresh_server_tree(cx);
 7992                })
 7993                .ok();
 7994
 7995                Self::refresh_workspace_configurations(&this, cx).await;
 7996            }
 7997
 7998            drop(settings_observation);
 7999            anyhow::Ok(())
 8000        })
 8001    }
 8002
 8003    pub fn language_servers_for_local_buffer<'a>(
 8004        &'a self,
 8005        buffer: &Buffer,
 8006        cx: &mut App,
 8007    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8008        let local = self.as_local();
 8009        let language_server_ids = local
 8010            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8011            .unwrap_or_default();
 8012
 8013        language_server_ids
 8014            .into_iter()
 8015            .filter_map(
 8016                move |server_id| match local?.language_servers.get(&server_id)? {
 8017                    LanguageServerState::Running {
 8018                        adapter, server, ..
 8019                    } => Some((adapter, server)),
 8020                    _ => None,
 8021                },
 8022            )
 8023    }
 8024
 8025    pub fn language_server_for_local_buffer<'a>(
 8026        &'a self,
 8027        buffer: &'a Buffer,
 8028        server_id: LanguageServerId,
 8029        cx: &'a mut App,
 8030    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8031        self.as_local()?
 8032            .language_servers_for_buffer(buffer, cx)
 8033            .find(|(_, s)| s.server_id() == server_id)
 8034    }
 8035
 8036    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8037        self.diagnostic_summaries.remove(&id_to_remove);
 8038        if let Some(local) = self.as_local_mut() {
 8039            let to_remove = local.remove_worktree(id_to_remove, cx);
 8040            for server in to_remove {
 8041                self.language_server_statuses.remove(&server);
 8042            }
 8043        }
 8044    }
 8045
 8046    pub fn shared(
 8047        &mut self,
 8048        project_id: u64,
 8049        downstream_client: AnyProtoClient,
 8050        _: &mut Context<Self>,
 8051    ) {
 8052        self.downstream_client = Some((downstream_client.clone(), project_id));
 8053
 8054        for (server_id, status) in &self.language_server_statuses {
 8055            if let Some(server) = self.language_server_for_id(*server_id) {
 8056                downstream_client
 8057                    .send(proto::StartLanguageServer {
 8058                        project_id,
 8059                        server: Some(proto::LanguageServer {
 8060                            id: server_id.to_proto(),
 8061                            name: status.name.to_string(),
 8062                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8063                        }),
 8064                        capabilities: serde_json::to_string(&server.capabilities())
 8065                            .expect("serializing server LSP capabilities"),
 8066                    })
 8067                    .log_err();
 8068            }
 8069        }
 8070    }
 8071
 8072    pub fn disconnected_from_host(&mut self) {
 8073        self.downstream_client.take();
 8074    }
 8075
 8076    pub fn disconnected_from_ssh_remote(&mut self) {
 8077        if let LspStoreMode::Remote(RemoteLspStore {
 8078            upstream_client, ..
 8079        }) = &mut self.mode
 8080        {
 8081            upstream_client.take();
 8082        }
 8083    }
 8084
 8085    pub(crate) fn set_language_server_statuses_from_proto(
 8086        &mut self,
 8087        project: WeakEntity<Project>,
 8088        language_servers: Vec<proto::LanguageServer>,
 8089        server_capabilities: Vec<String>,
 8090        cx: &mut Context<Self>,
 8091    ) {
 8092        let lsp_logs = cx
 8093            .try_global::<GlobalLogStore>()
 8094            .map(|lsp_store| lsp_store.0.clone());
 8095
 8096        self.language_server_statuses = language_servers
 8097            .into_iter()
 8098            .zip(server_capabilities)
 8099            .map(|(server, server_capabilities)| {
 8100                let server_id = LanguageServerId(server.id as usize);
 8101                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8102                    self.lsp_server_capabilities
 8103                        .insert(server_id, server_capabilities);
 8104                }
 8105
 8106                let name = LanguageServerName::from_proto(server.name);
 8107                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8108
 8109                if let Some(lsp_logs) = &lsp_logs {
 8110                    lsp_logs.update(cx, |lsp_logs, cx| {
 8111                        lsp_logs.add_language_server(
 8112                            // Only remote clients get their language servers set from proto
 8113                            LanguageServerKind::Remote {
 8114                                project: project.clone(),
 8115                            },
 8116                            server_id,
 8117                            Some(name.clone()),
 8118                            worktree,
 8119                            None,
 8120                            cx,
 8121                        );
 8122                    });
 8123                }
 8124
 8125                (
 8126                    server_id,
 8127                    LanguageServerStatus {
 8128                        name,
 8129                        pending_work: Default::default(),
 8130                        has_pending_diagnostic_updates: false,
 8131                        progress_tokens: Default::default(),
 8132                        worktree,
 8133                    },
 8134                )
 8135            })
 8136            .collect();
 8137    }
 8138
 8139    #[cfg(test)]
 8140    pub fn update_diagnostic_entries(
 8141        &mut self,
 8142        server_id: LanguageServerId,
 8143        abs_path: PathBuf,
 8144        result_id: Option<String>,
 8145        version: Option<i32>,
 8146        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8147        cx: &mut Context<Self>,
 8148    ) -> anyhow::Result<()> {
 8149        self.merge_diagnostic_entries(
 8150            vec![DocumentDiagnosticsUpdate {
 8151                diagnostics: DocumentDiagnostics {
 8152                    diagnostics,
 8153                    document_abs_path: abs_path,
 8154                    version,
 8155                },
 8156                result_id,
 8157                server_id,
 8158                disk_based_sources: Cow::Borrowed(&[]),
 8159            }],
 8160            |_, _, _| false,
 8161            cx,
 8162        )?;
 8163        Ok(())
 8164    }
 8165
 8166    pub fn merge_diagnostic_entries<'a>(
 8167        &mut self,
 8168        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8169        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
 8170        cx: &mut Context<Self>,
 8171    ) -> anyhow::Result<()> {
 8172        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8173        let mut updated_diagnostics_paths = HashMap::default();
 8174        for mut update in diagnostic_updates {
 8175            let abs_path = &update.diagnostics.document_abs_path;
 8176            let server_id = update.server_id;
 8177            let Some((worktree, relative_path)) =
 8178                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8179            else {
 8180                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8181                return Ok(());
 8182            };
 8183
 8184            let worktree_id = worktree.read(cx).id();
 8185            let project_path = ProjectPath {
 8186                worktree_id,
 8187                path: relative_path,
 8188            };
 8189
 8190            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8191                let snapshot = buffer_handle.read(cx).snapshot();
 8192                let buffer = buffer_handle.read(cx);
 8193                let reused_diagnostics = buffer
 8194                    .buffer_diagnostics(Some(server_id))
 8195                    .iter()
 8196                    .filter(|v| merge(buffer, &v.diagnostic, cx))
 8197                    .map(|v| {
 8198                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8199                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8200                        DiagnosticEntry {
 8201                            range: start..end,
 8202                            diagnostic: v.diagnostic.clone(),
 8203                        }
 8204                    })
 8205                    .collect::<Vec<_>>();
 8206
 8207                self.as_local_mut()
 8208                    .context("cannot merge diagnostics on a remote LspStore")?
 8209                    .update_buffer_diagnostics(
 8210                        &buffer_handle,
 8211                        server_id,
 8212                        update.result_id,
 8213                        update.diagnostics.version,
 8214                        update.diagnostics.diagnostics.clone(),
 8215                        reused_diagnostics.clone(),
 8216                        cx,
 8217                    )?;
 8218
 8219                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8220            }
 8221
 8222            let updated = worktree.update(cx, |worktree, cx| {
 8223                self.update_worktree_diagnostics(
 8224                    worktree.id(),
 8225                    server_id,
 8226                    project_path.path.clone(),
 8227                    update.diagnostics.diagnostics,
 8228                    cx,
 8229                )
 8230            })?;
 8231            match updated {
 8232                ControlFlow::Continue(new_summary) => {
 8233                    if let Some((project_id, new_summary)) = new_summary {
 8234                        match &mut diagnostics_summary {
 8235                            Some(diagnostics_summary) => {
 8236                                diagnostics_summary
 8237                                    .more_summaries
 8238                                    .push(proto::DiagnosticSummary {
 8239                                        path: project_path.path.as_ref().to_proto(),
 8240                                        language_server_id: server_id.0 as u64,
 8241                                        error_count: new_summary.error_count,
 8242                                        warning_count: new_summary.warning_count,
 8243                                    })
 8244                            }
 8245                            None => {
 8246                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8247                                    project_id,
 8248                                    worktree_id: worktree_id.to_proto(),
 8249                                    summary: Some(proto::DiagnosticSummary {
 8250                                        path: project_path.path.as_ref().to_proto(),
 8251                                        language_server_id: server_id.0 as u64,
 8252                                        error_count: new_summary.error_count,
 8253                                        warning_count: new_summary.warning_count,
 8254                                    }),
 8255                                    more_summaries: Vec::new(),
 8256                                })
 8257                            }
 8258                        }
 8259                    }
 8260                    updated_diagnostics_paths
 8261                        .entry(server_id)
 8262                        .or_insert_with(Vec::new)
 8263                        .push(project_path);
 8264                }
 8265                ControlFlow::Break(()) => {}
 8266            }
 8267        }
 8268
 8269        if let Some((diagnostics_summary, (downstream_client, _))) =
 8270            diagnostics_summary.zip(self.downstream_client.as_ref())
 8271        {
 8272            downstream_client.send(diagnostics_summary).log_err();
 8273        }
 8274        for (server_id, paths) in updated_diagnostics_paths {
 8275            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8276        }
 8277        Ok(())
 8278    }
 8279
 8280    fn update_worktree_diagnostics(
 8281        &mut self,
 8282        worktree_id: WorktreeId,
 8283        server_id: LanguageServerId,
 8284        path_in_worktree: Arc<RelPath>,
 8285        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8286        _: &mut Context<Worktree>,
 8287    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8288        let local = match &mut self.mode {
 8289            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8290            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8291        };
 8292
 8293        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8294        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8295        let summaries_by_server_id = summaries_for_tree
 8296            .entry(path_in_worktree.clone())
 8297            .or_default();
 8298
 8299        let old_summary = summaries_by_server_id
 8300            .remove(&server_id)
 8301            .unwrap_or_default();
 8302
 8303        let new_summary = DiagnosticSummary::new(&diagnostics);
 8304        if new_summary.is_empty() {
 8305            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8306            {
 8307                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8308                    diagnostics_by_server_id.remove(ix);
 8309                }
 8310                if diagnostics_by_server_id.is_empty() {
 8311                    diagnostics_for_tree.remove(&path_in_worktree);
 8312                }
 8313            }
 8314        } else {
 8315            summaries_by_server_id.insert(server_id, new_summary);
 8316            let diagnostics_by_server_id = diagnostics_for_tree
 8317                .entry(path_in_worktree.clone())
 8318                .or_default();
 8319            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8320                Ok(ix) => {
 8321                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8322                }
 8323                Err(ix) => {
 8324                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8325                }
 8326            }
 8327        }
 8328
 8329        if !old_summary.is_empty() || !new_summary.is_empty() {
 8330            if let Some((_, project_id)) = &self.downstream_client {
 8331                Ok(ControlFlow::Continue(Some((
 8332                    *project_id,
 8333                    proto::DiagnosticSummary {
 8334                        path: path_in_worktree.to_proto(),
 8335                        language_server_id: server_id.0 as u64,
 8336                        error_count: new_summary.error_count as u32,
 8337                        warning_count: new_summary.warning_count as u32,
 8338                    },
 8339                ))))
 8340            } else {
 8341                Ok(ControlFlow::Continue(None))
 8342            }
 8343        } else {
 8344            Ok(ControlFlow::Break(()))
 8345        }
 8346    }
 8347
 8348    pub fn open_buffer_for_symbol(
 8349        &mut self,
 8350        symbol: &Symbol,
 8351        cx: &mut Context<Self>,
 8352    ) -> Task<Result<Entity<Buffer>>> {
 8353        if let Some((client, project_id)) = self.upstream_client() {
 8354            let request = client.request(proto::OpenBufferForSymbol {
 8355                project_id,
 8356                symbol: Some(Self::serialize_symbol(symbol)),
 8357            });
 8358            cx.spawn(async move |this, cx| {
 8359                let response = request.await?;
 8360                let buffer_id = BufferId::new(response.buffer_id)?;
 8361                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8362                    .await
 8363            })
 8364        } else if let Some(local) = self.as_local() {
 8365            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8366                seed.worktree_id == symbol.source_worktree_id
 8367                    && state.id == symbol.source_language_server_id
 8368                    && symbol.language_server_name == seed.name
 8369            });
 8370            if !is_valid {
 8371                return Task::ready(Err(anyhow!(
 8372                    "language server for worktree and language not found"
 8373                )));
 8374            };
 8375
 8376            let symbol_abs_path = match &symbol.path {
 8377                SymbolLocation::InProject(project_path) => self
 8378                    .worktree_store
 8379                    .read(cx)
 8380                    .absolutize(&project_path, cx)
 8381                    .context("no such worktree"),
 8382                SymbolLocation::OutsideProject {
 8383                    abs_path,
 8384                    signature: _,
 8385                } => Ok(abs_path.to_path_buf()),
 8386            };
 8387            let symbol_abs_path = match symbol_abs_path {
 8388                Ok(abs_path) => abs_path,
 8389                Err(err) => return Task::ready(Err(err)),
 8390            };
 8391            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8392                uri
 8393            } else {
 8394                return Task::ready(Err(anyhow!("invalid symbol path")));
 8395            };
 8396
 8397            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8398        } else {
 8399            Task::ready(Err(anyhow!("no upstream client or local store")))
 8400        }
 8401    }
 8402
 8403    pub(crate) fn open_local_buffer_via_lsp(
 8404        &mut self,
 8405        abs_path: lsp::Uri,
 8406        language_server_id: LanguageServerId,
 8407        cx: &mut Context<Self>,
 8408    ) -> Task<Result<Entity<Buffer>>> {
 8409        cx.spawn(async move |lsp_store, cx| {
 8410            // Escape percent-encoded string.
 8411            let current_scheme = abs_path.scheme().to_owned();
 8412            // Uri is immutable, so we can't modify the scheme
 8413
 8414            let abs_path = abs_path
 8415                .to_file_path()
 8416                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8417            let p = abs_path.clone();
 8418            let yarn_worktree = lsp_store
 8419                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8420                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8421                        cx.spawn(async move |this, cx| {
 8422                            let t = this
 8423                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8424                                .ok()?;
 8425                            t.await
 8426                        })
 8427                    }),
 8428                    None => Task::ready(None),
 8429                })?
 8430                .await;
 8431            let (worktree_root_target, known_relative_path) =
 8432                if let Some((zip_root, relative_path)) = yarn_worktree {
 8433                    (zip_root, Some(relative_path))
 8434                } else {
 8435                    (Arc::<Path>::from(abs_path.as_path()), None)
 8436                };
 8437            let (worktree, relative_path) = if let Some(result) =
 8438                lsp_store.update(cx, |lsp_store, cx| {
 8439                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8440                        worktree_store.find_worktree(&worktree_root_target, cx)
 8441                    })
 8442                })? {
 8443                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8444                (result.0, relative_path)
 8445            } else {
 8446                let worktree = lsp_store
 8447                    .update(cx, |lsp_store, cx| {
 8448                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8449                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8450                        })
 8451                    })?
 8452                    .await?;
 8453                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8454                    lsp_store
 8455                        .update(cx, |lsp_store, cx| {
 8456                            if let Some(local) = lsp_store.as_local_mut() {
 8457                                local.register_language_server_for_invisible_worktree(
 8458                                    &worktree,
 8459                                    language_server_id,
 8460                                    cx,
 8461                                )
 8462                            }
 8463                        })
 8464                        .ok();
 8465                }
 8466                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8467                let relative_path = if let Some(known_path) = known_relative_path {
 8468                    known_path
 8469                } else {
 8470                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8471                        .into_arc()
 8472                };
 8473                (worktree, relative_path)
 8474            };
 8475            let project_path = ProjectPath {
 8476                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8477                path: relative_path,
 8478            };
 8479            lsp_store
 8480                .update(cx, |lsp_store, cx| {
 8481                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8482                        buffer_store.open_buffer(project_path, cx)
 8483                    })
 8484                })?
 8485                .await
 8486        })
 8487    }
 8488
 8489    fn request_multiple_lsp_locally<P, R>(
 8490        &mut self,
 8491        buffer: &Entity<Buffer>,
 8492        position: Option<P>,
 8493        request: R,
 8494        cx: &mut Context<Self>,
 8495    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8496    where
 8497        P: ToOffset,
 8498        R: LspCommand + Clone,
 8499        <R::LspRequest as lsp::request::Request>::Result: Send,
 8500        <R::LspRequest as lsp::request::Request>::Params: Send,
 8501    {
 8502        let Some(local) = self.as_local() else {
 8503            return Task::ready(Vec::new());
 8504        };
 8505
 8506        let snapshot = buffer.read(cx).snapshot();
 8507        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8508
 8509        let server_ids = buffer.update(cx, |buffer, cx| {
 8510            local
 8511                .language_servers_for_buffer(buffer, cx)
 8512                .filter(|(adapter, _)| {
 8513                    scope
 8514                        .as_ref()
 8515                        .map(|scope| scope.language_allowed(&adapter.name))
 8516                        .unwrap_or(true)
 8517                })
 8518                .map(|(_, server)| server.server_id())
 8519                .filter(|server_id| {
 8520                    self.as_local().is_none_or(|local| {
 8521                        local
 8522                            .buffers_opened_in_servers
 8523                            .get(&snapshot.remote_id())
 8524                            .is_some_and(|servers| servers.contains(server_id))
 8525                    })
 8526                })
 8527                .collect::<Vec<_>>()
 8528        });
 8529
 8530        let mut response_results = server_ids
 8531            .into_iter()
 8532            .map(|server_id| {
 8533                let task = self.request_lsp(
 8534                    buffer.clone(),
 8535                    LanguageServerToQuery::Other(server_id),
 8536                    request.clone(),
 8537                    cx,
 8538                );
 8539                async move { (server_id, task.await) }
 8540            })
 8541            .collect::<FuturesUnordered<_>>();
 8542
 8543        cx.background_spawn(async move {
 8544            let mut responses = Vec::with_capacity(response_results.len());
 8545            while let Some((server_id, response_result)) = response_results.next().await {
 8546                match response_result {
 8547                    Ok(response) => responses.push((server_id, response)),
 8548                    // rust-analyzer likes to error with this when its still loading up
 8549                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8550                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8551                }
 8552            }
 8553            responses
 8554        })
 8555    }
 8556
 8557    async fn handle_lsp_get_completions(
 8558        this: Entity<Self>,
 8559        envelope: TypedEnvelope<proto::GetCompletions>,
 8560        mut cx: AsyncApp,
 8561    ) -> Result<proto::GetCompletionsResponse> {
 8562        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8563
 8564        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8565        let buffer_handle = this.update(&mut cx, |this, cx| {
 8566            this.buffer_store.read(cx).get_existing(buffer_id)
 8567        })??;
 8568        let request = GetCompletions::from_proto(
 8569            envelope.payload,
 8570            this.clone(),
 8571            buffer_handle.clone(),
 8572            cx.clone(),
 8573        )
 8574        .await?;
 8575
 8576        let server_to_query = match request.server_id {
 8577            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8578            None => LanguageServerToQuery::FirstCapable,
 8579        };
 8580
 8581        let response = this
 8582            .update(&mut cx, |this, cx| {
 8583                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8584            })?
 8585            .await?;
 8586        this.update(&mut cx, |this, cx| {
 8587            Ok(GetCompletions::response_to_proto(
 8588                response,
 8589                this,
 8590                sender_id,
 8591                &buffer_handle.read(cx).version(),
 8592                cx,
 8593            ))
 8594        })?
 8595    }
 8596
 8597    async fn handle_lsp_command<T: LspCommand>(
 8598        this: Entity<Self>,
 8599        envelope: TypedEnvelope<T::ProtoRequest>,
 8600        mut cx: AsyncApp,
 8601    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8602    where
 8603        <T::LspRequest as lsp::request::Request>::Params: Send,
 8604        <T::LspRequest as lsp::request::Request>::Result: Send,
 8605    {
 8606        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8607        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8608        let buffer_handle = this.update(&mut cx, |this, cx| {
 8609            this.buffer_store.read(cx).get_existing(buffer_id)
 8610        })??;
 8611        let request = T::from_proto(
 8612            envelope.payload,
 8613            this.clone(),
 8614            buffer_handle.clone(),
 8615            cx.clone(),
 8616        )
 8617        .await?;
 8618        let response = this
 8619            .update(&mut cx, |this, cx| {
 8620                this.request_lsp(
 8621                    buffer_handle.clone(),
 8622                    LanguageServerToQuery::FirstCapable,
 8623                    request,
 8624                    cx,
 8625                )
 8626            })?
 8627            .await?;
 8628        this.update(&mut cx, |this, cx| {
 8629            Ok(T::response_to_proto(
 8630                response,
 8631                this,
 8632                sender_id,
 8633                &buffer_handle.read(cx).version(),
 8634                cx,
 8635            ))
 8636        })?
 8637    }
 8638
 8639    async fn handle_lsp_query(
 8640        lsp_store: Entity<Self>,
 8641        envelope: TypedEnvelope<proto::LspQuery>,
 8642        mut cx: AsyncApp,
 8643    ) -> Result<proto::Ack> {
 8644        use proto::lsp_query::Request;
 8645        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8646        let lsp_query = envelope.payload;
 8647        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8648        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8649        match lsp_query.request.context("invalid LSP query request")? {
 8650            Request::GetReferences(get_references) => {
 8651                let position = get_references.position.clone().and_then(deserialize_anchor);
 8652                Self::query_lsp_locally::<GetReferences>(
 8653                    lsp_store,
 8654                    server_id,
 8655                    sender_id,
 8656                    lsp_request_id,
 8657                    get_references,
 8658                    position,
 8659                    &mut cx,
 8660                )
 8661                .await?;
 8662            }
 8663            Request::GetDocumentColor(get_document_color) => {
 8664                Self::query_lsp_locally::<GetDocumentColor>(
 8665                    lsp_store,
 8666                    server_id,
 8667                    sender_id,
 8668                    lsp_request_id,
 8669                    get_document_color,
 8670                    None,
 8671                    &mut cx,
 8672                )
 8673                .await?;
 8674            }
 8675            Request::GetHover(get_hover) => {
 8676                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8677                Self::query_lsp_locally::<GetHover>(
 8678                    lsp_store,
 8679                    server_id,
 8680                    sender_id,
 8681                    lsp_request_id,
 8682                    get_hover,
 8683                    position,
 8684                    &mut cx,
 8685                )
 8686                .await?;
 8687            }
 8688            Request::GetCodeActions(get_code_actions) => {
 8689                Self::query_lsp_locally::<GetCodeActions>(
 8690                    lsp_store,
 8691                    server_id,
 8692                    sender_id,
 8693                    lsp_request_id,
 8694                    get_code_actions,
 8695                    None,
 8696                    &mut cx,
 8697                )
 8698                .await?;
 8699            }
 8700            Request::GetSignatureHelp(get_signature_help) => {
 8701                let position = get_signature_help
 8702                    .position
 8703                    .clone()
 8704                    .and_then(deserialize_anchor);
 8705                Self::query_lsp_locally::<GetSignatureHelp>(
 8706                    lsp_store,
 8707                    server_id,
 8708                    sender_id,
 8709                    lsp_request_id,
 8710                    get_signature_help,
 8711                    position,
 8712                    &mut cx,
 8713                )
 8714                .await?;
 8715            }
 8716            Request::GetCodeLens(get_code_lens) => {
 8717                Self::query_lsp_locally::<GetCodeLens>(
 8718                    lsp_store,
 8719                    server_id,
 8720                    sender_id,
 8721                    lsp_request_id,
 8722                    get_code_lens,
 8723                    None,
 8724                    &mut cx,
 8725                )
 8726                .await?;
 8727            }
 8728            Request::GetDefinition(get_definition) => {
 8729                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8730                Self::query_lsp_locally::<GetDefinitions>(
 8731                    lsp_store,
 8732                    server_id,
 8733                    sender_id,
 8734                    lsp_request_id,
 8735                    get_definition,
 8736                    position,
 8737                    &mut cx,
 8738                )
 8739                .await?;
 8740            }
 8741            Request::GetDeclaration(get_declaration) => {
 8742                let position = get_declaration
 8743                    .position
 8744                    .clone()
 8745                    .and_then(deserialize_anchor);
 8746                Self::query_lsp_locally::<GetDeclarations>(
 8747                    lsp_store,
 8748                    server_id,
 8749                    sender_id,
 8750                    lsp_request_id,
 8751                    get_declaration,
 8752                    position,
 8753                    &mut cx,
 8754                )
 8755                .await?;
 8756            }
 8757            Request::GetTypeDefinition(get_type_definition) => {
 8758                let position = get_type_definition
 8759                    .position
 8760                    .clone()
 8761                    .and_then(deserialize_anchor);
 8762                Self::query_lsp_locally::<GetTypeDefinitions>(
 8763                    lsp_store,
 8764                    server_id,
 8765                    sender_id,
 8766                    lsp_request_id,
 8767                    get_type_definition,
 8768                    position,
 8769                    &mut cx,
 8770                )
 8771                .await?;
 8772            }
 8773            Request::GetImplementation(get_implementation) => {
 8774                let position = get_implementation
 8775                    .position
 8776                    .clone()
 8777                    .and_then(deserialize_anchor);
 8778                Self::query_lsp_locally::<GetImplementations>(
 8779                    lsp_store,
 8780                    server_id,
 8781                    sender_id,
 8782                    lsp_request_id,
 8783                    get_implementation,
 8784                    position,
 8785                    &mut cx,
 8786                )
 8787                .await?;
 8788            }
 8789            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 8790                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 8791                let version = deserialize_version(get_document_diagnostics.buffer_version());
 8792                let buffer = lsp_store.update(&mut cx, |this, cx| {
 8793                    this.buffer_store.read(cx).get_existing(buffer_id)
 8794                })??;
 8795                buffer
 8796                    .update(&mut cx, |buffer, _| {
 8797                        buffer.wait_for_version(version.clone())
 8798                    })?
 8799                    .await?;
 8800                lsp_store.update(&mut cx, |lsp_store, cx| {
 8801                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 8802                    let key = LspKey {
 8803                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 8804                        server_queried: server_id,
 8805                    };
 8806                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 8807                    ) {
 8808                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 8809                            lsp_requests.clear();
 8810                        };
 8811                    }
 8812
 8813                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 8814                    existing_queries.insert(
 8815                        lsp_request_id,
 8816                        cx.spawn(async move |lsp_store, cx| {
 8817                            let diagnostics_pull = lsp_store
 8818                                .update(cx, |lsp_store, cx| {
 8819                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8820                                })
 8821                                .ok();
 8822                            if let Some(diagnostics_pull) = diagnostics_pull {
 8823                                match diagnostics_pull.await {
 8824                                    Ok(()) => {}
 8825                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 8826                                };
 8827                            }
 8828                        }),
 8829                    );
 8830                })?;
 8831            }
 8832            Request::InlayHints(inlay_hints) => {
 8833                let query_start = inlay_hints
 8834                    .start
 8835                    .clone()
 8836                    .and_then(deserialize_anchor)
 8837                    .context("invalid inlay hints range start")?;
 8838                let query_end = inlay_hints
 8839                    .end
 8840                    .clone()
 8841                    .and_then(deserialize_anchor)
 8842                    .context("invalid inlay hints range end")?;
 8843                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 8844                    &lsp_store,
 8845                    server_id,
 8846                    lsp_request_id,
 8847                    &inlay_hints,
 8848                    query_start..query_end,
 8849                    &mut cx,
 8850                )
 8851                .await
 8852                .context("preparing inlay hints request")?;
 8853                Self::query_lsp_locally::<InlayHints>(
 8854                    lsp_store,
 8855                    server_id,
 8856                    sender_id,
 8857                    lsp_request_id,
 8858                    inlay_hints,
 8859                    None,
 8860                    &mut cx,
 8861                )
 8862                .await
 8863                .context("querying for inlay hints")?
 8864            }
 8865        }
 8866        Ok(proto::Ack {})
 8867    }
 8868
 8869    async fn handle_lsp_query_response(
 8870        lsp_store: Entity<Self>,
 8871        envelope: TypedEnvelope<proto::LspQueryResponse>,
 8872        cx: AsyncApp,
 8873    ) -> Result<()> {
 8874        lsp_store.read_with(&cx, |lsp_store, _| {
 8875            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 8876                upstream_client.handle_lsp_response(envelope.clone());
 8877            }
 8878        })?;
 8879        Ok(())
 8880    }
 8881
 8882    async fn handle_apply_code_action(
 8883        this: Entity<Self>,
 8884        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 8885        mut cx: AsyncApp,
 8886    ) -> Result<proto::ApplyCodeActionResponse> {
 8887        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8888        let action =
 8889            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 8890        let apply_code_action = this.update(&mut cx, |this, cx| {
 8891            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8892            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 8893            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 8894        })??;
 8895
 8896        let project_transaction = apply_code_action.await?;
 8897        let project_transaction = this.update(&mut cx, |this, cx| {
 8898            this.buffer_store.update(cx, |buffer_store, cx| {
 8899                buffer_store.serialize_project_transaction_for_peer(
 8900                    project_transaction,
 8901                    sender_id,
 8902                    cx,
 8903                )
 8904            })
 8905        })?;
 8906        Ok(proto::ApplyCodeActionResponse {
 8907            transaction: Some(project_transaction),
 8908        })
 8909    }
 8910
 8911    async fn handle_register_buffer_with_language_servers(
 8912        this: Entity<Self>,
 8913        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 8914        mut cx: AsyncApp,
 8915    ) -> Result<proto::Ack> {
 8916        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8917        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 8918        this.update(&mut cx, |this, cx| {
 8919            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 8920                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 8921                    project_id: upstream_project_id,
 8922                    buffer_id: buffer_id.to_proto(),
 8923                    only_servers: envelope.payload.only_servers,
 8924                });
 8925            }
 8926
 8927            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 8928                anyhow::bail!("buffer is not open");
 8929            };
 8930
 8931            let handle = this.register_buffer_with_language_servers(
 8932                &buffer,
 8933                envelope
 8934                    .payload
 8935                    .only_servers
 8936                    .into_iter()
 8937                    .filter_map(|selector| {
 8938                        Some(match selector.selector? {
 8939                            proto::language_server_selector::Selector::ServerId(server_id) => {
 8940                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 8941                            }
 8942                            proto::language_server_selector::Selector::Name(name) => {
 8943                                LanguageServerSelector::Name(LanguageServerName(
 8944                                    SharedString::from(name),
 8945                                ))
 8946                            }
 8947                        })
 8948                    })
 8949                    .collect(),
 8950                false,
 8951                cx,
 8952            );
 8953            this.buffer_store().update(cx, |buffer_store, _| {
 8954                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 8955            });
 8956
 8957            Ok(())
 8958        })??;
 8959        Ok(proto::Ack {})
 8960    }
 8961
 8962    async fn handle_rename_project_entry(
 8963        this: Entity<Self>,
 8964        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 8965        mut cx: AsyncApp,
 8966    ) -> Result<proto::ProjectEntryResponse> {
 8967        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 8968        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 8969        let new_path =
 8970            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 8971
 8972        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 8973            .update(&mut cx, |this, cx| {
 8974                let (worktree, entry) = this
 8975                    .worktree_store
 8976                    .read(cx)
 8977                    .worktree_and_entry_for_id(entry_id, cx)?;
 8978                let new_worktree = this
 8979                    .worktree_store
 8980                    .read(cx)
 8981                    .worktree_for_id(new_worktree_id, cx)?;
 8982                Some((
 8983                    this.worktree_store.clone(),
 8984                    worktree,
 8985                    new_worktree,
 8986                    entry.clone(),
 8987                ))
 8988            })?
 8989            .context("worktree not found")?;
 8990        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 8991            (worktree.absolutize(&old_entry.path), worktree.id())
 8992        })?;
 8993        let new_abs_path =
 8994            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 8995
 8996        let _transaction = Self::will_rename_entry(
 8997            this.downgrade(),
 8998            old_worktree_id,
 8999            &old_abs_path,
 9000            &new_abs_path,
 9001            old_entry.is_dir(),
 9002            cx.clone(),
 9003        )
 9004        .await;
 9005        let response = WorktreeStore::handle_rename_project_entry(
 9006            worktree_store,
 9007            envelope.payload,
 9008            cx.clone(),
 9009        )
 9010        .await;
 9011        this.read_with(&cx, |this, _| {
 9012            this.did_rename_entry(
 9013                old_worktree_id,
 9014                &old_abs_path,
 9015                &new_abs_path,
 9016                old_entry.is_dir(),
 9017            );
 9018        })
 9019        .ok();
 9020        response
 9021    }
 9022
 9023    async fn handle_update_diagnostic_summary(
 9024        this: Entity<Self>,
 9025        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9026        mut cx: AsyncApp,
 9027    ) -> Result<()> {
 9028        this.update(&mut cx, |lsp_store, cx| {
 9029            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9030            let mut updated_diagnostics_paths = HashMap::default();
 9031            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9032            for message_summary in envelope
 9033                .payload
 9034                .summary
 9035                .into_iter()
 9036                .chain(envelope.payload.more_summaries)
 9037            {
 9038                let project_path = ProjectPath {
 9039                    worktree_id,
 9040                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9041                };
 9042                let path = project_path.path.clone();
 9043                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9044                let summary = DiagnosticSummary {
 9045                    error_count: message_summary.error_count as usize,
 9046                    warning_count: message_summary.warning_count as usize,
 9047                };
 9048
 9049                if summary.is_empty() {
 9050                    if let Some(worktree_summaries) =
 9051                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9052                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9053                    {
 9054                        summaries.remove(&server_id);
 9055                        if summaries.is_empty() {
 9056                            worktree_summaries.remove(&path);
 9057                        }
 9058                    }
 9059                } else {
 9060                    lsp_store
 9061                        .diagnostic_summaries
 9062                        .entry(worktree_id)
 9063                        .or_default()
 9064                        .entry(path)
 9065                        .or_default()
 9066                        .insert(server_id, summary);
 9067                }
 9068
 9069                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9070                    match &mut diagnostics_summary {
 9071                        Some(diagnostics_summary) => {
 9072                            diagnostics_summary
 9073                                .more_summaries
 9074                                .push(proto::DiagnosticSummary {
 9075                                    path: project_path.path.as_ref().to_proto(),
 9076                                    language_server_id: server_id.0 as u64,
 9077                                    error_count: summary.error_count as u32,
 9078                                    warning_count: summary.warning_count as u32,
 9079                                })
 9080                        }
 9081                        None => {
 9082                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9083                                project_id: *project_id,
 9084                                worktree_id: worktree_id.to_proto(),
 9085                                summary: Some(proto::DiagnosticSummary {
 9086                                    path: project_path.path.as_ref().to_proto(),
 9087                                    language_server_id: server_id.0 as u64,
 9088                                    error_count: summary.error_count as u32,
 9089                                    warning_count: summary.warning_count as u32,
 9090                                }),
 9091                                more_summaries: Vec::new(),
 9092                            })
 9093                        }
 9094                    }
 9095                }
 9096                updated_diagnostics_paths
 9097                    .entry(server_id)
 9098                    .or_insert_with(Vec::new)
 9099                    .push(project_path);
 9100            }
 9101
 9102            if let Some((diagnostics_summary, (downstream_client, _))) =
 9103                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9104            {
 9105                downstream_client.send(diagnostics_summary).log_err();
 9106            }
 9107            for (server_id, paths) in updated_diagnostics_paths {
 9108                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9109            }
 9110            Ok(())
 9111        })?
 9112    }
 9113
 9114    async fn handle_start_language_server(
 9115        lsp_store: Entity<Self>,
 9116        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9117        mut cx: AsyncApp,
 9118    ) -> Result<()> {
 9119        let server = envelope.payload.server.context("invalid server")?;
 9120        let server_capabilities =
 9121            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9122                .with_context(|| {
 9123                    format!(
 9124                        "incorrect server capabilities {}",
 9125                        envelope.payload.capabilities
 9126                    )
 9127                })?;
 9128        lsp_store.update(&mut cx, |lsp_store, cx| {
 9129            let server_id = LanguageServerId(server.id as usize);
 9130            let server_name = LanguageServerName::from_proto(server.name.clone());
 9131            lsp_store
 9132                .lsp_server_capabilities
 9133                .insert(server_id, server_capabilities);
 9134            lsp_store.language_server_statuses.insert(
 9135                server_id,
 9136                LanguageServerStatus {
 9137                    name: server_name.clone(),
 9138                    pending_work: Default::default(),
 9139                    has_pending_diagnostic_updates: false,
 9140                    progress_tokens: Default::default(),
 9141                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9142                },
 9143            );
 9144            cx.emit(LspStoreEvent::LanguageServerAdded(
 9145                server_id,
 9146                server_name,
 9147                server.worktree_id.map(WorktreeId::from_proto),
 9148            ));
 9149            cx.notify();
 9150        })?;
 9151        Ok(())
 9152    }
 9153
 9154    async fn handle_update_language_server(
 9155        lsp_store: Entity<Self>,
 9156        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9157        mut cx: AsyncApp,
 9158    ) -> Result<()> {
 9159        lsp_store.update(&mut cx, |lsp_store, cx| {
 9160            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9161
 9162            match envelope.payload.variant.context("invalid variant")? {
 9163                proto::update_language_server::Variant::WorkStart(payload) => {
 9164                    lsp_store.on_lsp_work_start(
 9165                        language_server_id,
 9166                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9167                            .context("invalid progress token value")?,
 9168                        LanguageServerProgress {
 9169                            title: payload.title,
 9170                            is_disk_based_diagnostics_progress: false,
 9171                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9172                            message: payload.message,
 9173                            percentage: payload.percentage.map(|p| p as usize),
 9174                            last_update_at: cx.background_executor().now(),
 9175                        },
 9176                        cx,
 9177                    );
 9178                }
 9179                proto::update_language_server::Variant::WorkProgress(payload) => {
 9180                    lsp_store.on_lsp_work_progress(
 9181                        language_server_id,
 9182                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9183                            .context("invalid progress token value")?,
 9184                        LanguageServerProgress {
 9185                            title: None,
 9186                            is_disk_based_diagnostics_progress: false,
 9187                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9188                            message: payload.message,
 9189                            percentage: payload.percentage.map(|p| p as usize),
 9190                            last_update_at: cx.background_executor().now(),
 9191                        },
 9192                        cx,
 9193                    );
 9194                }
 9195
 9196                proto::update_language_server::Variant::WorkEnd(payload) => {
 9197                    lsp_store.on_lsp_work_end(
 9198                        language_server_id,
 9199                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9200                            .context("invalid progress token value")?,
 9201                        cx,
 9202                    );
 9203                }
 9204
 9205                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9206                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9207                }
 9208
 9209                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9210                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9211                }
 9212
 9213                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9214                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9215                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9216                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9217                        language_server_id,
 9218                        name: envelope
 9219                            .payload
 9220                            .server_name
 9221                            .map(SharedString::new)
 9222                            .map(LanguageServerName),
 9223                        message: non_lsp,
 9224                    });
 9225                }
 9226            }
 9227
 9228            Ok(())
 9229        })?
 9230    }
 9231
 9232    async fn handle_language_server_log(
 9233        this: Entity<Self>,
 9234        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9235        mut cx: AsyncApp,
 9236    ) -> Result<()> {
 9237        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9238        let log_type = envelope
 9239            .payload
 9240            .log_type
 9241            .map(LanguageServerLogType::from_proto)
 9242            .context("invalid language server log type")?;
 9243
 9244        let message = envelope.payload.message;
 9245
 9246        this.update(&mut cx, |_, cx| {
 9247            cx.emit(LspStoreEvent::LanguageServerLog(
 9248                language_server_id,
 9249                log_type,
 9250                message,
 9251            ));
 9252        })
 9253    }
 9254
 9255    async fn handle_lsp_ext_cancel_flycheck(
 9256        lsp_store: Entity<Self>,
 9257        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9258        cx: AsyncApp,
 9259    ) -> Result<proto::Ack> {
 9260        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9261        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9262            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9263                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9264            } else {
 9265                None
 9266            }
 9267        })?;
 9268        if let Some(task) = task {
 9269            task.context("handling lsp ext cancel flycheck")?;
 9270        }
 9271
 9272        Ok(proto::Ack {})
 9273    }
 9274
 9275    async fn handle_lsp_ext_run_flycheck(
 9276        lsp_store: Entity<Self>,
 9277        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9278        mut cx: AsyncApp,
 9279    ) -> Result<proto::Ack> {
 9280        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9281        lsp_store.update(&mut cx, |lsp_store, cx| {
 9282            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9283                let text_document = if envelope.payload.current_file_only {
 9284                    let buffer_id = envelope
 9285                        .payload
 9286                        .buffer_id
 9287                        .map(|id| BufferId::new(id))
 9288                        .transpose()?;
 9289                    buffer_id
 9290                        .and_then(|buffer_id| {
 9291                            lsp_store
 9292                                .buffer_store()
 9293                                .read(cx)
 9294                                .get(buffer_id)
 9295                                .and_then(|buffer| {
 9296                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9297                                })
 9298                                .map(|path| make_text_document_identifier(&path))
 9299                        })
 9300                        .transpose()?
 9301                } else {
 9302                    None
 9303                };
 9304                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9305                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9306                )?;
 9307            }
 9308            anyhow::Ok(())
 9309        })??;
 9310
 9311        Ok(proto::Ack {})
 9312    }
 9313
 9314    async fn handle_lsp_ext_clear_flycheck(
 9315        lsp_store: Entity<Self>,
 9316        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9317        cx: AsyncApp,
 9318    ) -> Result<proto::Ack> {
 9319        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9320        lsp_store
 9321            .read_with(&cx, |lsp_store, _| {
 9322                if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9323                    Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9324                } else {
 9325                    None
 9326                }
 9327            })
 9328            .context("handling lsp ext clear flycheck")?;
 9329
 9330        Ok(proto::Ack {})
 9331    }
 9332
 9333    pub fn disk_based_diagnostics_started(
 9334        &mut self,
 9335        language_server_id: LanguageServerId,
 9336        cx: &mut Context<Self>,
 9337    ) {
 9338        if let Some(language_server_status) =
 9339            self.language_server_statuses.get_mut(&language_server_id)
 9340        {
 9341            language_server_status.has_pending_diagnostic_updates = true;
 9342        }
 9343
 9344        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9345        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9346            language_server_id,
 9347            name: self
 9348                .language_server_adapter_for_id(language_server_id)
 9349                .map(|adapter| adapter.name()),
 9350            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9351                Default::default(),
 9352            ),
 9353        })
 9354    }
 9355
 9356    pub fn disk_based_diagnostics_finished(
 9357        &mut self,
 9358        language_server_id: LanguageServerId,
 9359        cx: &mut Context<Self>,
 9360    ) {
 9361        if let Some(language_server_status) =
 9362            self.language_server_statuses.get_mut(&language_server_id)
 9363        {
 9364            language_server_status.has_pending_diagnostic_updates = false;
 9365        }
 9366
 9367        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9368        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9369            language_server_id,
 9370            name: self
 9371                .language_server_adapter_for_id(language_server_id)
 9372                .map(|adapter| adapter.name()),
 9373            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9374                Default::default(),
 9375            ),
 9376        })
 9377    }
 9378
 9379    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9380    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9381    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9382    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9383    // the language server might take some time to publish diagnostics.
 9384    fn simulate_disk_based_diagnostics_events_if_needed(
 9385        &mut self,
 9386        language_server_id: LanguageServerId,
 9387        cx: &mut Context<Self>,
 9388    ) {
 9389        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9390
 9391        let Some(LanguageServerState::Running {
 9392            simulate_disk_based_diagnostics_completion,
 9393            adapter,
 9394            ..
 9395        }) = self
 9396            .as_local_mut()
 9397            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9398        else {
 9399            return;
 9400        };
 9401
 9402        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9403            return;
 9404        }
 9405
 9406        let prev_task =
 9407            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9408                cx.background_executor()
 9409                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9410                    .await;
 9411
 9412                this.update(cx, |this, cx| {
 9413                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9414
 9415                    if let Some(LanguageServerState::Running {
 9416                        simulate_disk_based_diagnostics_completion,
 9417                        ..
 9418                    }) = this.as_local_mut().and_then(|local_store| {
 9419                        local_store.language_servers.get_mut(&language_server_id)
 9420                    }) {
 9421                        *simulate_disk_based_diagnostics_completion = None;
 9422                    }
 9423                })
 9424                .ok();
 9425            }));
 9426
 9427        if prev_task.is_none() {
 9428            self.disk_based_diagnostics_started(language_server_id, cx);
 9429        }
 9430    }
 9431
 9432    pub fn language_server_statuses(
 9433        &self,
 9434    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9435        self.language_server_statuses
 9436            .iter()
 9437            .map(|(key, value)| (*key, value))
 9438    }
 9439
 9440    pub(super) fn did_rename_entry(
 9441        &self,
 9442        worktree_id: WorktreeId,
 9443        old_path: &Path,
 9444        new_path: &Path,
 9445        is_dir: bool,
 9446    ) {
 9447        maybe!({
 9448            let local_store = self.as_local()?;
 9449
 9450            let old_uri = lsp::Uri::from_file_path(old_path)
 9451                .ok()
 9452                .map(|uri| uri.to_string())?;
 9453            let new_uri = lsp::Uri::from_file_path(new_path)
 9454                .ok()
 9455                .map(|uri| uri.to_string())?;
 9456
 9457            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9458                let Some(filter) = local_store
 9459                    .language_server_paths_watched_for_rename
 9460                    .get(&language_server.server_id())
 9461                else {
 9462                    continue;
 9463                };
 9464
 9465                if filter.should_send_did_rename(&old_uri, is_dir) {
 9466                    language_server
 9467                        .notify::<DidRenameFiles>(RenameFilesParams {
 9468                            files: vec![FileRename {
 9469                                old_uri: old_uri.clone(),
 9470                                new_uri: new_uri.clone(),
 9471                            }],
 9472                        })
 9473                        .ok();
 9474                }
 9475            }
 9476            Some(())
 9477        });
 9478    }
 9479
 9480    pub(super) fn will_rename_entry(
 9481        this: WeakEntity<Self>,
 9482        worktree_id: WorktreeId,
 9483        old_path: &Path,
 9484        new_path: &Path,
 9485        is_dir: bool,
 9486        cx: AsyncApp,
 9487    ) -> Task<ProjectTransaction> {
 9488        let old_uri = lsp::Uri::from_file_path(old_path)
 9489            .ok()
 9490            .map(|uri| uri.to_string());
 9491        let new_uri = lsp::Uri::from_file_path(new_path)
 9492            .ok()
 9493            .map(|uri| uri.to_string());
 9494        cx.spawn(async move |cx| {
 9495            let mut tasks = vec![];
 9496            this.update(cx, |this, cx| {
 9497                let local_store = this.as_local()?;
 9498                let old_uri = old_uri?;
 9499                let new_uri = new_uri?;
 9500                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9501                    let Some(filter) = local_store
 9502                        .language_server_paths_watched_for_rename
 9503                        .get(&language_server.server_id())
 9504                    else {
 9505                        continue;
 9506                    };
 9507
 9508                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9509                        let apply_edit = cx.spawn({
 9510                            let old_uri = old_uri.clone();
 9511                            let new_uri = new_uri.clone();
 9512                            let language_server = language_server.clone();
 9513                            async move |this, cx| {
 9514                                let edit = language_server
 9515                                    .request::<WillRenameFiles>(RenameFilesParams {
 9516                                        files: vec![FileRename { old_uri, new_uri }],
 9517                                    })
 9518                                    .await
 9519                                    .into_response()
 9520                                    .context("will rename files")
 9521                                    .log_err()
 9522                                    .flatten()?;
 9523
 9524                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9525                                    this.upgrade()?,
 9526                                    edit,
 9527                                    false,
 9528                                    language_server.clone(),
 9529                                    cx,
 9530                                )
 9531                                .await
 9532                                .ok()?;
 9533                                Some(transaction)
 9534                            }
 9535                        });
 9536                        tasks.push(apply_edit);
 9537                    }
 9538                }
 9539                Some(())
 9540            })
 9541            .ok()
 9542            .flatten();
 9543            let mut merged_transaction = ProjectTransaction::default();
 9544            for task in tasks {
 9545                // Await on tasks sequentially so that the order of application of edits is deterministic
 9546                // (at least with regards to the order of registration of language servers)
 9547                if let Some(transaction) = task.await {
 9548                    for (buffer, buffer_transaction) in transaction.0 {
 9549                        merged_transaction.0.insert(buffer, buffer_transaction);
 9550                    }
 9551                }
 9552            }
 9553            merged_transaction
 9554        })
 9555    }
 9556
 9557    fn lsp_notify_abs_paths_changed(
 9558        &mut self,
 9559        server_id: LanguageServerId,
 9560        changes: Vec<PathEvent>,
 9561    ) {
 9562        maybe!({
 9563            let server = self.language_server_for_id(server_id)?;
 9564            let changes = changes
 9565                .into_iter()
 9566                .filter_map(|event| {
 9567                    let typ = match event.kind? {
 9568                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9569                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9570                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9571                    };
 9572                    Some(lsp::FileEvent {
 9573                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9574                        typ,
 9575                    })
 9576                })
 9577                .collect::<Vec<_>>();
 9578            if !changes.is_empty() {
 9579                server
 9580                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9581                        lsp::DidChangeWatchedFilesParams { changes },
 9582                    )
 9583                    .ok();
 9584            }
 9585            Some(())
 9586        });
 9587    }
 9588
 9589    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9590        self.as_local()?.language_server_for_id(id)
 9591    }
 9592
 9593    fn on_lsp_progress(
 9594        &mut self,
 9595        progress_params: lsp::ProgressParams,
 9596        language_server_id: LanguageServerId,
 9597        disk_based_diagnostics_progress_token: Option<String>,
 9598        cx: &mut Context<Self>,
 9599    ) {
 9600        match progress_params.value {
 9601            lsp::ProgressParamsValue::WorkDone(progress) => {
 9602                self.handle_work_done_progress(
 9603                    progress,
 9604                    language_server_id,
 9605                    disk_based_diagnostics_progress_token,
 9606                    ProgressToken::from_lsp(progress_params.token),
 9607                    cx,
 9608                );
 9609            }
 9610            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9611                let identifier = match progress_params.token {
 9612                    lsp::NumberOrString::Number(_) => None,
 9613                    lsp::NumberOrString::String(token) => token
 9614                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9615                        .map(|(_, id)| id.to_owned()),
 9616                };
 9617                if let Some(LanguageServerState::Running {
 9618                    workspace_diagnostics_refresh_tasks,
 9619                    ..
 9620                }) = self
 9621                    .as_local_mut()
 9622                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9623                    && let Some(workspace_diagnostics) =
 9624                        workspace_diagnostics_refresh_tasks.get_mut(&identifier)
 9625                {
 9626                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9627                    self.apply_workspace_diagnostic_report(language_server_id, report, cx)
 9628                }
 9629            }
 9630        }
 9631    }
 9632
 9633    fn handle_work_done_progress(
 9634        &mut self,
 9635        progress: lsp::WorkDoneProgress,
 9636        language_server_id: LanguageServerId,
 9637        disk_based_diagnostics_progress_token: Option<String>,
 9638        token: ProgressToken,
 9639        cx: &mut Context<Self>,
 9640    ) {
 9641        let language_server_status =
 9642            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9643                status
 9644            } else {
 9645                return;
 9646            };
 9647
 9648        if !language_server_status.progress_tokens.contains(&token) {
 9649            return;
 9650        }
 9651
 9652        let is_disk_based_diagnostics_progress =
 9653            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9654                (&disk_based_diagnostics_progress_token, &token)
 9655            {
 9656                token.starts_with(disk_based_token)
 9657            } else {
 9658                false
 9659            };
 9660
 9661        match progress {
 9662            lsp::WorkDoneProgress::Begin(report) => {
 9663                if is_disk_based_diagnostics_progress {
 9664                    self.disk_based_diagnostics_started(language_server_id, cx);
 9665                }
 9666                self.on_lsp_work_start(
 9667                    language_server_id,
 9668                    token.clone(),
 9669                    LanguageServerProgress {
 9670                        title: Some(report.title),
 9671                        is_disk_based_diagnostics_progress,
 9672                        is_cancellable: report.cancellable.unwrap_or(false),
 9673                        message: report.message.clone(),
 9674                        percentage: report.percentage.map(|p| p as usize),
 9675                        last_update_at: cx.background_executor().now(),
 9676                    },
 9677                    cx,
 9678                );
 9679            }
 9680            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9681                language_server_id,
 9682                token,
 9683                LanguageServerProgress {
 9684                    title: None,
 9685                    is_disk_based_diagnostics_progress,
 9686                    is_cancellable: report.cancellable.unwrap_or(false),
 9687                    message: report.message,
 9688                    percentage: report.percentage.map(|p| p as usize),
 9689                    last_update_at: cx.background_executor().now(),
 9690                },
 9691                cx,
 9692            ),
 9693            lsp::WorkDoneProgress::End(_) => {
 9694                language_server_status.progress_tokens.remove(&token);
 9695                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9696                if is_disk_based_diagnostics_progress {
 9697                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9698                }
 9699            }
 9700        }
 9701    }
 9702
 9703    fn on_lsp_work_start(
 9704        &mut self,
 9705        language_server_id: LanguageServerId,
 9706        token: ProgressToken,
 9707        progress: LanguageServerProgress,
 9708        cx: &mut Context<Self>,
 9709    ) {
 9710        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9711            status.pending_work.insert(token.clone(), progress.clone());
 9712            cx.notify();
 9713        }
 9714        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9715            language_server_id,
 9716            name: self
 9717                .language_server_adapter_for_id(language_server_id)
 9718                .map(|adapter| adapter.name()),
 9719            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9720                token: Some(token.to_proto()),
 9721                title: progress.title,
 9722                message: progress.message,
 9723                percentage: progress.percentage.map(|p| p as u32),
 9724                is_cancellable: Some(progress.is_cancellable),
 9725            }),
 9726        })
 9727    }
 9728
 9729    fn on_lsp_work_progress(
 9730        &mut self,
 9731        language_server_id: LanguageServerId,
 9732        token: ProgressToken,
 9733        progress: LanguageServerProgress,
 9734        cx: &mut Context<Self>,
 9735    ) {
 9736        let mut did_update = false;
 9737        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9738            match status.pending_work.entry(token.clone()) {
 9739                btree_map::Entry::Vacant(entry) => {
 9740                    entry.insert(progress.clone());
 9741                    did_update = true;
 9742                }
 9743                btree_map::Entry::Occupied(mut entry) => {
 9744                    let entry = entry.get_mut();
 9745                    if (progress.last_update_at - entry.last_update_at)
 9746                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9747                    {
 9748                        entry.last_update_at = progress.last_update_at;
 9749                        if progress.message.is_some() {
 9750                            entry.message = progress.message.clone();
 9751                        }
 9752                        if progress.percentage.is_some() {
 9753                            entry.percentage = progress.percentage;
 9754                        }
 9755                        if progress.is_cancellable != entry.is_cancellable {
 9756                            entry.is_cancellable = progress.is_cancellable;
 9757                        }
 9758                        did_update = true;
 9759                    }
 9760                }
 9761            }
 9762        }
 9763
 9764        if did_update {
 9765            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9766                language_server_id,
 9767                name: self
 9768                    .language_server_adapter_for_id(language_server_id)
 9769                    .map(|adapter| adapter.name()),
 9770                message: proto::update_language_server::Variant::WorkProgress(
 9771                    proto::LspWorkProgress {
 9772                        token: Some(token.to_proto()),
 9773                        message: progress.message,
 9774                        percentage: progress.percentage.map(|p| p as u32),
 9775                        is_cancellable: Some(progress.is_cancellable),
 9776                    },
 9777                ),
 9778            })
 9779        }
 9780    }
 9781
 9782    fn on_lsp_work_end(
 9783        &mut self,
 9784        language_server_id: LanguageServerId,
 9785        token: ProgressToken,
 9786        cx: &mut Context<Self>,
 9787    ) {
 9788        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9789            if let Some(work) = status.pending_work.remove(&token)
 9790                && !work.is_disk_based_diagnostics_progress
 9791            {
 9792                cx.emit(LspStoreEvent::RefreshInlayHints {
 9793                    server_id: language_server_id,
 9794                    request_id: None,
 9795                });
 9796            }
 9797            cx.notify();
 9798        }
 9799
 9800        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9801            language_server_id,
 9802            name: self
 9803                .language_server_adapter_for_id(language_server_id)
 9804                .map(|adapter| adapter.name()),
 9805            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
 9806                token: Some(token.to_proto()),
 9807            }),
 9808        })
 9809    }
 9810
 9811    pub async fn handle_resolve_completion_documentation(
 9812        this: Entity<Self>,
 9813        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
 9814        mut cx: AsyncApp,
 9815    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
 9816        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
 9817
 9818        let completion = this
 9819            .read_with(&cx, |this, cx| {
 9820                let id = LanguageServerId(envelope.payload.language_server_id as usize);
 9821                let server = this
 9822                    .language_server_for_id(id)
 9823                    .with_context(|| format!("No language server {id}"))?;
 9824
 9825                anyhow::Ok(cx.background_spawn(async move {
 9826                    let can_resolve = server
 9827                        .capabilities()
 9828                        .completion_provider
 9829                        .as_ref()
 9830                        .and_then(|options| options.resolve_provider)
 9831                        .unwrap_or(false);
 9832                    if can_resolve {
 9833                        server
 9834                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
 9835                            .await
 9836                            .into_response()
 9837                            .context("resolve completion item")
 9838                    } else {
 9839                        anyhow::Ok(lsp_completion)
 9840                    }
 9841                }))
 9842            })??
 9843            .await?;
 9844
 9845        let mut documentation_is_markdown = false;
 9846        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
 9847        let documentation = match completion.documentation {
 9848            Some(lsp::Documentation::String(text)) => text,
 9849
 9850            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
 9851                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
 9852                value
 9853            }
 9854
 9855            _ => String::new(),
 9856        };
 9857
 9858        // If we have a new buffer_id, that means we're talking to a new client
 9859        // and want to check for new text_edits in the completion too.
 9860        let mut old_replace_start = None;
 9861        let mut old_replace_end = None;
 9862        let mut old_insert_start = None;
 9863        let mut old_insert_end = None;
 9864        let mut new_text = String::default();
 9865        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
 9866            let buffer_snapshot = this.update(&mut cx, |this, cx| {
 9867                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9868                anyhow::Ok(buffer.read(cx).snapshot())
 9869            })??;
 9870
 9871            if let Some(text_edit) = completion.text_edit.as_ref() {
 9872                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
 9873
 9874                if let Some(mut edit) = edit {
 9875                    LineEnding::normalize(&mut edit.new_text);
 9876
 9877                    new_text = edit.new_text;
 9878                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
 9879                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
 9880                    if let Some(insert_range) = edit.insert_range {
 9881                        old_insert_start = Some(serialize_anchor(&insert_range.start));
 9882                        old_insert_end = Some(serialize_anchor(&insert_range.end));
 9883                    }
 9884                }
 9885            }
 9886        }
 9887
 9888        Ok(proto::ResolveCompletionDocumentationResponse {
 9889            documentation,
 9890            documentation_is_markdown,
 9891            old_replace_start,
 9892            old_replace_end,
 9893            new_text,
 9894            lsp_completion,
 9895            old_insert_start,
 9896            old_insert_end,
 9897        })
 9898    }
 9899
 9900    async fn handle_on_type_formatting(
 9901        this: Entity<Self>,
 9902        envelope: TypedEnvelope<proto::OnTypeFormatting>,
 9903        mut cx: AsyncApp,
 9904    ) -> Result<proto::OnTypeFormattingResponse> {
 9905        let on_type_formatting = this.update(&mut cx, |this, cx| {
 9906            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9907            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9908            let position = envelope
 9909                .payload
 9910                .position
 9911                .and_then(deserialize_anchor)
 9912                .context("invalid position")?;
 9913            anyhow::Ok(this.apply_on_type_formatting(
 9914                buffer,
 9915                position,
 9916                envelope.payload.trigger.clone(),
 9917                cx,
 9918            ))
 9919        })??;
 9920
 9921        let transaction = on_type_formatting
 9922            .await?
 9923            .as_ref()
 9924            .map(language::proto::serialize_transaction);
 9925        Ok(proto::OnTypeFormattingResponse { transaction })
 9926    }
 9927
 9928    async fn handle_refresh_inlay_hints(
 9929        lsp_store: Entity<Self>,
 9930        envelope: TypedEnvelope<proto::RefreshInlayHints>,
 9931        mut cx: AsyncApp,
 9932    ) -> Result<proto::Ack> {
 9933        lsp_store.update(&mut cx, |_, cx| {
 9934            cx.emit(LspStoreEvent::RefreshInlayHints {
 9935                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
 9936                request_id: envelope.payload.request_id.map(|id| id as usize),
 9937            });
 9938        })?;
 9939        Ok(proto::Ack {})
 9940    }
 9941
 9942    async fn handle_pull_workspace_diagnostics(
 9943        lsp_store: Entity<Self>,
 9944        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
 9945        mut cx: AsyncApp,
 9946    ) -> Result<proto::Ack> {
 9947        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
 9948        lsp_store.update(&mut cx, |lsp_store, _| {
 9949            lsp_store.pull_workspace_diagnostics(server_id);
 9950        })?;
 9951        Ok(proto::Ack {})
 9952    }
 9953
 9954    async fn handle_get_color_presentation(
 9955        lsp_store: Entity<Self>,
 9956        envelope: TypedEnvelope<proto::GetColorPresentation>,
 9957        mut cx: AsyncApp,
 9958    ) -> Result<proto::GetColorPresentationResponse> {
 9959        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9960        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9961            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9962        })??;
 9963
 9964        let color = envelope
 9965            .payload
 9966            .color
 9967            .context("invalid color resolve request")?;
 9968        let start = color
 9969            .lsp_range_start
 9970            .context("invalid color resolve request")?;
 9971        let end = color
 9972            .lsp_range_end
 9973            .context("invalid color resolve request")?;
 9974
 9975        let color = DocumentColor {
 9976            lsp_range: lsp::Range {
 9977                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
 9978                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
 9979            },
 9980            color: lsp::Color {
 9981                red: color.red,
 9982                green: color.green,
 9983                blue: color.blue,
 9984                alpha: color.alpha,
 9985            },
 9986            resolved: false,
 9987            color_presentations: Vec::new(),
 9988        };
 9989        let resolved_color = lsp_store
 9990            .update(&mut cx, |lsp_store, cx| {
 9991                lsp_store.resolve_color_presentation(
 9992                    color,
 9993                    buffer.clone(),
 9994                    LanguageServerId(envelope.payload.server_id as usize),
 9995                    cx,
 9996                )
 9997            })?
 9998            .await
 9999            .context("resolving color presentation")?;
10000
10001        Ok(proto::GetColorPresentationResponse {
10002            presentations: resolved_color
10003                .color_presentations
10004                .into_iter()
10005                .map(|presentation| proto::ColorPresentation {
10006                    label: presentation.label.to_string(),
10007                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
10008                    additional_text_edits: presentation
10009                        .additional_text_edits
10010                        .into_iter()
10011                        .map(serialize_lsp_edit)
10012                        .collect(),
10013                })
10014                .collect(),
10015        })
10016    }
10017
10018    async fn handle_resolve_inlay_hint(
10019        lsp_store: Entity<Self>,
10020        envelope: TypedEnvelope<proto::ResolveInlayHint>,
10021        mut cx: AsyncApp,
10022    ) -> Result<proto::ResolveInlayHintResponse> {
10023        let proto_hint = envelope
10024            .payload
10025            .hint
10026            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
10027        let hint = InlayHints::proto_to_project_hint(proto_hint)
10028            .context("resolved proto inlay hint conversion")?;
10029        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10030            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10031            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10032        })??;
10033        let response_hint = lsp_store
10034            .update(&mut cx, |lsp_store, cx| {
10035                lsp_store.resolve_inlay_hint(
10036                    hint,
10037                    buffer,
10038                    LanguageServerId(envelope.payload.language_server_id as usize),
10039                    cx,
10040                )
10041            })?
10042            .await
10043            .context("inlay hints fetch")?;
10044        Ok(proto::ResolveInlayHintResponse {
10045            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
10046        })
10047    }
10048
10049    async fn handle_refresh_code_lens(
10050        this: Entity<Self>,
10051        _: TypedEnvelope<proto::RefreshCodeLens>,
10052        mut cx: AsyncApp,
10053    ) -> Result<proto::Ack> {
10054        this.update(&mut cx, |_, cx| {
10055            cx.emit(LspStoreEvent::RefreshCodeLens);
10056        })?;
10057        Ok(proto::Ack {})
10058    }
10059
10060    async fn handle_open_buffer_for_symbol(
10061        this: Entity<Self>,
10062        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10063        mut cx: AsyncApp,
10064    ) -> Result<proto::OpenBufferForSymbolResponse> {
10065        let peer_id = envelope.original_sender_id().unwrap_or_default();
10066        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10067        let symbol = Self::deserialize_symbol(symbol)?;
10068        this.read_with(&cx, |this, _| {
10069            if let SymbolLocation::OutsideProject {
10070                abs_path,
10071                signature,
10072            } = &symbol.path
10073            {
10074                let new_signature = this.symbol_signature(&abs_path);
10075                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10076            }
10077            Ok(())
10078        })??;
10079        let buffer = this
10080            .update(&mut cx, |this, cx| {
10081                this.open_buffer_for_symbol(
10082                    &Symbol {
10083                        language_server_name: symbol.language_server_name,
10084                        source_worktree_id: symbol.source_worktree_id,
10085                        source_language_server_id: symbol.source_language_server_id,
10086                        path: symbol.path,
10087                        name: symbol.name,
10088                        kind: symbol.kind,
10089                        range: symbol.range,
10090                        label: CodeLabel::default(),
10091                    },
10092                    cx,
10093                )
10094            })?
10095            .await?;
10096
10097        this.update(&mut cx, |this, cx| {
10098            let is_private = buffer
10099                .read(cx)
10100                .file()
10101                .map(|f| f.is_private())
10102                .unwrap_or_default();
10103            if is_private {
10104                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10105            } else {
10106                this.buffer_store
10107                    .update(cx, |buffer_store, cx| {
10108                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10109                    })
10110                    .detach_and_log_err(cx);
10111                let buffer_id = buffer.read(cx).remote_id().to_proto();
10112                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10113            }
10114        })?
10115    }
10116
10117    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10118        let mut hasher = Sha256::new();
10119        hasher.update(abs_path.to_string_lossy().as_bytes());
10120        hasher.update(self.nonce.to_be_bytes());
10121        hasher.finalize().as_slice().try_into().unwrap()
10122    }
10123
10124    pub async fn handle_get_project_symbols(
10125        this: Entity<Self>,
10126        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10127        mut cx: AsyncApp,
10128    ) -> Result<proto::GetProjectSymbolsResponse> {
10129        let symbols = this
10130            .update(&mut cx, |this, cx| {
10131                this.symbols(&envelope.payload.query, cx)
10132            })?
10133            .await?;
10134
10135        Ok(proto::GetProjectSymbolsResponse {
10136            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10137        })
10138    }
10139
10140    pub async fn handle_restart_language_servers(
10141        this: Entity<Self>,
10142        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10143        mut cx: AsyncApp,
10144    ) -> Result<proto::Ack> {
10145        this.update(&mut cx, |lsp_store, cx| {
10146            let buffers =
10147                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10148            lsp_store.restart_language_servers_for_buffers(
10149                buffers,
10150                envelope
10151                    .payload
10152                    .only_servers
10153                    .into_iter()
10154                    .filter_map(|selector| {
10155                        Some(match selector.selector? {
10156                            proto::language_server_selector::Selector::ServerId(server_id) => {
10157                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10158                            }
10159                            proto::language_server_selector::Selector::Name(name) => {
10160                                LanguageServerSelector::Name(LanguageServerName(
10161                                    SharedString::from(name),
10162                                ))
10163                            }
10164                        })
10165                    })
10166                    .collect(),
10167                cx,
10168            );
10169        })?;
10170
10171        Ok(proto::Ack {})
10172    }
10173
10174    pub async fn handle_stop_language_servers(
10175        lsp_store: Entity<Self>,
10176        envelope: TypedEnvelope<proto::StopLanguageServers>,
10177        mut cx: AsyncApp,
10178    ) -> Result<proto::Ack> {
10179        lsp_store.update(&mut cx, |lsp_store, cx| {
10180            if envelope.payload.all
10181                && envelope.payload.also_servers.is_empty()
10182                && envelope.payload.buffer_ids.is_empty()
10183            {
10184                lsp_store.stop_all_language_servers(cx);
10185            } else {
10186                let buffers =
10187                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10188                lsp_store
10189                    .stop_language_servers_for_buffers(
10190                        buffers,
10191                        envelope
10192                            .payload
10193                            .also_servers
10194                            .into_iter()
10195                            .filter_map(|selector| {
10196                                Some(match selector.selector? {
10197                                    proto::language_server_selector::Selector::ServerId(
10198                                        server_id,
10199                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10200                                        server_id,
10201                                    )),
10202                                    proto::language_server_selector::Selector::Name(name) => {
10203                                        LanguageServerSelector::Name(LanguageServerName(
10204                                            SharedString::from(name),
10205                                        ))
10206                                    }
10207                                })
10208                            })
10209                            .collect(),
10210                        cx,
10211                    )
10212                    .detach_and_log_err(cx);
10213            }
10214        })?;
10215
10216        Ok(proto::Ack {})
10217    }
10218
10219    pub async fn handle_cancel_language_server_work(
10220        lsp_store: Entity<Self>,
10221        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10222        mut cx: AsyncApp,
10223    ) -> Result<proto::Ack> {
10224        lsp_store.update(&mut cx, |lsp_store, cx| {
10225            if let Some(work) = envelope.payload.work {
10226                match work {
10227                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10228                        let buffers =
10229                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10230                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10231                    }
10232                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10233                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10234                        let token = work
10235                            .token
10236                            .map(|token| {
10237                                ProgressToken::from_proto(token)
10238                                    .context("invalid work progress token")
10239                            })
10240                            .transpose()?;
10241                        lsp_store.cancel_language_server_work(server_id, token, cx);
10242                    }
10243                }
10244            }
10245            anyhow::Ok(())
10246        })??;
10247
10248        Ok(proto::Ack {})
10249    }
10250
10251    fn buffer_ids_to_buffers(
10252        &mut self,
10253        buffer_ids: impl Iterator<Item = u64>,
10254        cx: &mut Context<Self>,
10255    ) -> Vec<Entity<Buffer>> {
10256        buffer_ids
10257            .into_iter()
10258            .flat_map(|buffer_id| {
10259                self.buffer_store
10260                    .read(cx)
10261                    .get(BufferId::new(buffer_id).log_err()?)
10262            })
10263            .collect::<Vec<_>>()
10264    }
10265
10266    async fn handle_apply_additional_edits_for_completion(
10267        this: Entity<Self>,
10268        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10269        mut cx: AsyncApp,
10270    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10271        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10272            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10273            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10274            let completion = Self::deserialize_completion(
10275                envelope.payload.completion.context("invalid completion")?,
10276            )?;
10277            anyhow::Ok((buffer, completion))
10278        })??;
10279
10280        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10281            this.apply_additional_edits_for_completion(
10282                buffer,
10283                Rc::new(RefCell::new(Box::new([Completion {
10284                    replace_range: completion.replace_range,
10285                    new_text: completion.new_text,
10286                    source: completion.source,
10287                    documentation: None,
10288                    label: CodeLabel::default(),
10289                    match_start: None,
10290                    snippet_deduplication_key: None,
10291                    insert_text_mode: None,
10292                    icon_path: None,
10293                    confirm: None,
10294                }]))),
10295                0,
10296                false,
10297                cx,
10298            )
10299        })?;
10300
10301        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10302            transaction: apply_additional_edits
10303                .await?
10304                .as_ref()
10305                .map(language::proto::serialize_transaction),
10306        })
10307    }
10308
10309    pub fn last_formatting_failure(&self) -> Option<&str> {
10310        self.last_formatting_failure.as_deref()
10311    }
10312
10313    pub fn reset_last_formatting_failure(&mut self) {
10314        self.last_formatting_failure = None;
10315    }
10316
10317    pub fn environment_for_buffer(
10318        &self,
10319        buffer: &Entity<Buffer>,
10320        cx: &mut Context<Self>,
10321    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10322        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10323            environment.update(cx, |env, cx| {
10324                env.buffer_environment(buffer, &self.worktree_store, cx)
10325            })
10326        } else {
10327            Task::ready(None).shared()
10328        }
10329    }
10330
10331    pub fn format(
10332        &mut self,
10333        buffers: HashSet<Entity<Buffer>>,
10334        target: LspFormatTarget,
10335        push_to_history: bool,
10336        trigger: FormatTrigger,
10337        cx: &mut Context<Self>,
10338    ) -> Task<anyhow::Result<ProjectTransaction>> {
10339        let logger = zlog::scoped!("format");
10340        if self.as_local().is_some() {
10341            zlog::trace!(logger => "Formatting locally");
10342            let logger = zlog::scoped!(logger => "local");
10343            let buffers = buffers
10344                .into_iter()
10345                .map(|buffer_handle| {
10346                    let buffer = buffer_handle.read(cx);
10347                    let buffer_abs_path = File::from_dyn(buffer.file())
10348                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10349
10350                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10351                })
10352                .collect::<Vec<_>>();
10353
10354            cx.spawn(async move |lsp_store, cx| {
10355                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10356
10357                for (handle, abs_path, id) in buffers {
10358                    let env = lsp_store
10359                        .update(cx, |lsp_store, cx| {
10360                            lsp_store.environment_for_buffer(&handle, cx)
10361                        })?
10362                        .await;
10363
10364                    let ranges = match &target {
10365                        LspFormatTarget::Buffers => None,
10366                        LspFormatTarget::Ranges(ranges) => {
10367                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10368                        }
10369                    };
10370
10371                    formattable_buffers.push(FormattableBuffer {
10372                        handle,
10373                        abs_path,
10374                        env,
10375                        ranges,
10376                    });
10377                }
10378                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10379
10380                let format_timer = zlog::time!(logger => "Formatting buffers");
10381                let result = LocalLspStore::format_locally(
10382                    lsp_store.clone(),
10383                    formattable_buffers,
10384                    push_to_history,
10385                    trigger,
10386                    logger,
10387                    cx,
10388                )
10389                .await;
10390                format_timer.end();
10391
10392                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10393
10394                lsp_store.update(cx, |lsp_store, _| {
10395                    lsp_store.update_last_formatting_failure(&result);
10396                })?;
10397
10398                result
10399            })
10400        } else if let Some((client, project_id)) = self.upstream_client() {
10401            zlog::trace!(logger => "Formatting remotely");
10402            let logger = zlog::scoped!(logger => "remote");
10403            // Don't support formatting ranges via remote
10404            match target {
10405                LspFormatTarget::Buffers => {}
10406                LspFormatTarget::Ranges(_) => {
10407                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10408                    return Task::ready(Ok(ProjectTransaction::default()));
10409                }
10410            }
10411
10412            let buffer_store = self.buffer_store();
10413            cx.spawn(async move |lsp_store, cx| {
10414                zlog::trace!(logger => "Sending remote format request");
10415                let request_timer = zlog::time!(logger => "remote format request");
10416                let result = client
10417                    .request(proto::FormatBuffers {
10418                        project_id,
10419                        trigger: trigger as i32,
10420                        buffer_ids: buffers
10421                            .iter()
10422                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10423                            .collect::<Result<_>>()?,
10424                    })
10425                    .await
10426                    .and_then(|result| result.transaction.context("missing transaction"));
10427                request_timer.end();
10428
10429                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10430
10431                lsp_store.update(cx, |lsp_store, _| {
10432                    lsp_store.update_last_formatting_failure(&result);
10433                })?;
10434
10435                let transaction_response = result?;
10436                let _timer = zlog::time!(logger => "deserializing project transaction");
10437                buffer_store
10438                    .update(cx, |buffer_store, cx| {
10439                        buffer_store.deserialize_project_transaction(
10440                            transaction_response,
10441                            push_to_history,
10442                            cx,
10443                        )
10444                    })?
10445                    .await
10446            })
10447        } else {
10448            zlog::trace!(logger => "Not formatting");
10449            Task::ready(Ok(ProjectTransaction::default()))
10450        }
10451    }
10452
10453    async fn handle_format_buffers(
10454        this: Entity<Self>,
10455        envelope: TypedEnvelope<proto::FormatBuffers>,
10456        mut cx: AsyncApp,
10457    ) -> Result<proto::FormatBuffersResponse> {
10458        let sender_id = envelope.original_sender_id().unwrap_or_default();
10459        let format = this.update(&mut cx, |this, cx| {
10460            let mut buffers = HashSet::default();
10461            for buffer_id in &envelope.payload.buffer_ids {
10462                let buffer_id = BufferId::new(*buffer_id)?;
10463                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10464            }
10465            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10466            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10467        })??;
10468
10469        let project_transaction = format.await?;
10470        let project_transaction = this.update(&mut cx, |this, cx| {
10471            this.buffer_store.update(cx, |buffer_store, cx| {
10472                buffer_store.serialize_project_transaction_for_peer(
10473                    project_transaction,
10474                    sender_id,
10475                    cx,
10476                )
10477            })
10478        })?;
10479        Ok(proto::FormatBuffersResponse {
10480            transaction: Some(project_transaction),
10481        })
10482    }
10483
10484    async fn handle_apply_code_action_kind(
10485        this: Entity<Self>,
10486        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10487        mut cx: AsyncApp,
10488    ) -> Result<proto::ApplyCodeActionKindResponse> {
10489        let sender_id = envelope.original_sender_id().unwrap_or_default();
10490        let format = this.update(&mut cx, |this, cx| {
10491            let mut buffers = HashSet::default();
10492            for buffer_id in &envelope.payload.buffer_ids {
10493                let buffer_id = BufferId::new(*buffer_id)?;
10494                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10495            }
10496            let kind = match envelope.payload.kind.as_str() {
10497                "" => CodeActionKind::EMPTY,
10498                "quickfix" => CodeActionKind::QUICKFIX,
10499                "refactor" => CodeActionKind::REFACTOR,
10500                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10501                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10502                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10503                "source" => CodeActionKind::SOURCE,
10504                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10505                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10506                _ => anyhow::bail!(
10507                    "Invalid code action kind {}",
10508                    envelope.payload.kind.as_str()
10509                ),
10510            };
10511            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10512        })??;
10513
10514        let project_transaction = format.await?;
10515        let project_transaction = this.update(&mut cx, |this, cx| {
10516            this.buffer_store.update(cx, |buffer_store, cx| {
10517                buffer_store.serialize_project_transaction_for_peer(
10518                    project_transaction,
10519                    sender_id,
10520                    cx,
10521                )
10522            })
10523        })?;
10524        Ok(proto::ApplyCodeActionKindResponse {
10525            transaction: Some(project_transaction),
10526        })
10527    }
10528
10529    async fn shutdown_language_server(
10530        server_state: Option<LanguageServerState>,
10531        name: LanguageServerName,
10532        cx: &mut AsyncApp,
10533    ) {
10534        let server = match server_state {
10535            Some(LanguageServerState::Starting { startup, .. }) => {
10536                let mut timer = cx
10537                    .background_executor()
10538                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10539                    .fuse();
10540
10541                select! {
10542                    server = startup.fuse() => server,
10543                    () = timer => {
10544                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10545                        None
10546                    },
10547                }
10548            }
10549
10550            Some(LanguageServerState::Running { server, .. }) => Some(server),
10551
10552            None => None,
10553        };
10554
10555        if let Some(server) = server
10556            && let Some(shutdown) = server.shutdown()
10557        {
10558            shutdown.await;
10559        }
10560    }
10561
10562    // Returns a list of all of the worktrees which no longer have a language server and the root path
10563    // for the stopped server
10564    fn stop_local_language_server(
10565        &mut self,
10566        server_id: LanguageServerId,
10567        cx: &mut Context<Self>,
10568    ) -> Task<()> {
10569        let local = match &mut self.mode {
10570            LspStoreMode::Local(local) => local,
10571            _ => {
10572                return Task::ready(());
10573            }
10574        };
10575
10576        // Remove this server ID from all entries in the given worktree.
10577        local
10578            .language_server_ids
10579            .retain(|_, state| state.id != server_id);
10580        self.buffer_store.update(cx, |buffer_store, cx| {
10581            for buffer in buffer_store.buffers() {
10582                buffer.update(cx, |buffer, cx| {
10583                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10584                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10585                });
10586            }
10587        });
10588
10589        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10590            summaries.retain(|path, summaries_by_server_id| {
10591                if summaries_by_server_id.remove(&server_id).is_some() {
10592                    if let Some((client, project_id)) = self.downstream_client.clone() {
10593                        client
10594                            .send(proto::UpdateDiagnosticSummary {
10595                                project_id,
10596                                worktree_id: worktree_id.to_proto(),
10597                                summary: Some(proto::DiagnosticSummary {
10598                                    path: path.as_ref().to_proto(),
10599                                    language_server_id: server_id.0 as u64,
10600                                    error_count: 0,
10601                                    warning_count: 0,
10602                                }),
10603                                more_summaries: Vec::new(),
10604                            })
10605                            .log_err();
10606                    }
10607                    !summaries_by_server_id.is_empty()
10608                } else {
10609                    true
10610                }
10611            });
10612        }
10613
10614        let local = self.as_local_mut().unwrap();
10615        for diagnostics in local.diagnostics.values_mut() {
10616            diagnostics.retain(|_, diagnostics_by_server_id| {
10617                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10618                    diagnostics_by_server_id.remove(ix);
10619                    !diagnostics_by_server_id.is_empty()
10620                } else {
10621                    true
10622                }
10623            });
10624        }
10625        local.language_server_watched_paths.remove(&server_id);
10626
10627        let server_state = local.language_servers.remove(&server_id);
10628        self.cleanup_lsp_data(server_id);
10629        let name = self
10630            .language_server_statuses
10631            .remove(&server_id)
10632            .map(|status| status.name)
10633            .or_else(|| {
10634                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10635                    Some(adapter.name())
10636                } else {
10637                    None
10638                }
10639            });
10640
10641        if let Some(name) = name {
10642            log::info!("stopping language server {name}");
10643            self.languages
10644                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10645            cx.notify();
10646
10647            return cx.spawn(async move |lsp_store, cx| {
10648                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10649                lsp_store
10650                    .update(cx, |lsp_store, cx| {
10651                        lsp_store
10652                            .languages
10653                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10654                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10655                        cx.notify();
10656                    })
10657                    .ok();
10658            });
10659        }
10660
10661        if server_state.is_some() {
10662            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10663        }
10664        Task::ready(())
10665    }
10666
10667    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10668        if let Some((client, project_id)) = self.upstream_client() {
10669            let request = client.request(proto::StopLanguageServers {
10670                project_id,
10671                buffer_ids: Vec::new(),
10672                also_servers: Vec::new(),
10673                all: true,
10674            });
10675            cx.background_spawn(request).detach_and_log_err(cx);
10676        } else {
10677            let Some(local) = self.as_local_mut() else {
10678                return;
10679            };
10680            let language_servers_to_stop = local
10681                .language_server_ids
10682                .values()
10683                .map(|state| state.id)
10684                .collect();
10685            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10686            let tasks = language_servers_to_stop
10687                .into_iter()
10688                .map(|server| self.stop_local_language_server(server, cx))
10689                .collect::<Vec<_>>();
10690            cx.background_spawn(async move {
10691                futures::future::join_all(tasks).await;
10692            })
10693            .detach();
10694        }
10695    }
10696
10697    pub fn restart_language_servers_for_buffers(
10698        &mut self,
10699        buffers: Vec<Entity<Buffer>>,
10700        only_restart_servers: HashSet<LanguageServerSelector>,
10701        cx: &mut Context<Self>,
10702    ) {
10703        if let Some((client, project_id)) = self.upstream_client() {
10704            let request = client.request(proto::RestartLanguageServers {
10705                project_id,
10706                buffer_ids: buffers
10707                    .into_iter()
10708                    .map(|b| b.read(cx).remote_id().to_proto())
10709                    .collect(),
10710                only_servers: only_restart_servers
10711                    .into_iter()
10712                    .map(|selector| {
10713                        let selector = match selector {
10714                            LanguageServerSelector::Id(language_server_id) => {
10715                                proto::language_server_selector::Selector::ServerId(
10716                                    language_server_id.to_proto(),
10717                                )
10718                            }
10719                            LanguageServerSelector::Name(language_server_name) => {
10720                                proto::language_server_selector::Selector::Name(
10721                                    language_server_name.to_string(),
10722                                )
10723                            }
10724                        };
10725                        proto::LanguageServerSelector {
10726                            selector: Some(selector),
10727                        }
10728                    })
10729                    .collect(),
10730                all: false,
10731            });
10732            cx.background_spawn(request).detach_and_log_err(cx);
10733        } else {
10734            let stop_task = if only_restart_servers.is_empty() {
10735                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10736            } else {
10737                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10738            };
10739            cx.spawn(async move |lsp_store, cx| {
10740                stop_task.await;
10741                lsp_store
10742                    .update(cx, |lsp_store, cx| {
10743                        for buffer in buffers {
10744                            lsp_store.register_buffer_with_language_servers(
10745                                &buffer,
10746                                only_restart_servers.clone(),
10747                                true,
10748                                cx,
10749                            );
10750                        }
10751                    })
10752                    .ok()
10753            })
10754            .detach();
10755        }
10756    }
10757
10758    pub fn stop_language_servers_for_buffers(
10759        &mut self,
10760        buffers: Vec<Entity<Buffer>>,
10761        also_stop_servers: HashSet<LanguageServerSelector>,
10762        cx: &mut Context<Self>,
10763    ) -> Task<Result<()>> {
10764        if let Some((client, project_id)) = self.upstream_client() {
10765            let request = client.request(proto::StopLanguageServers {
10766                project_id,
10767                buffer_ids: buffers
10768                    .into_iter()
10769                    .map(|b| b.read(cx).remote_id().to_proto())
10770                    .collect(),
10771                also_servers: also_stop_servers
10772                    .into_iter()
10773                    .map(|selector| {
10774                        let selector = match selector {
10775                            LanguageServerSelector::Id(language_server_id) => {
10776                                proto::language_server_selector::Selector::ServerId(
10777                                    language_server_id.to_proto(),
10778                                )
10779                            }
10780                            LanguageServerSelector::Name(language_server_name) => {
10781                                proto::language_server_selector::Selector::Name(
10782                                    language_server_name.to_string(),
10783                                )
10784                            }
10785                        };
10786                        proto::LanguageServerSelector {
10787                            selector: Some(selector),
10788                        }
10789                    })
10790                    .collect(),
10791                all: false,
10792            });
10793            cx.background_spawn(async move {
10794                let _ = request.await?;
10795                Ok(())
10796            })
10797        } else {
10798            let task =
10799                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10800            cx.background_spawn(async move {
10801                task.await;
10802                Ok(())
10803            })
10804        }
10805    }
10806
10807    fn stop_local_language_servers_for_buffers(
10808        &mut self,
10809        buffers: &[Entity<Buffer>],
10810        also_stop_servers: HashSet<LanguageServerSelector>,
10811        cx: &mut Context<Self>,
10812    ) -> Task<()> {
10813        let Some(local) = self.as_local_mut() else {
10814            return Task::ready(());
10815        };
10816        let mut language_server_names_to_stop = BTreeSet::default();
10817        let mut language_servers_to_stop = also_stop_servers
10818            .into_iter()
10819            .flat_map(|selector| match selector {
10820                LanguageServerSelector::Id(id) => Some(id),
10821                LanguageServerSelector::Name(name) => {
10822                    language_server_names_to_stop.insert(name);
10823                    None
10824                }
10825            })
10826            .collect::<BTreeSet<_>>();
10827
10828        let mut covered_worktrees = HashSet::default();
10829        for buffer in buffers {
10830            buffer.update(cx, |buffer, cx| {
10831                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
10832                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
10833                    && covered_worktrees.insert(worktree_id)
10834                {
10835                    language_server_names_to_stop.retain(|name| {
10836                        let old_ids_count = language_servers_to_stop.len();
10837                        let all_language_servers_with_this_name = local
10838                            .language_server_ids
10839                            .iter()
10840                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
10841                        language_servers_to_stop.extend(all_language_servers_with_this_name);
10842                        old_ids_count == language_servers_to_stop.len()
10843                    });
10844                }
10845            });
10846        }
10847        for name in language_server_names_to_stop {
10848            language_servers_to_stop.extend(
10849                local
10850                    .language_server_ids
10851                    .iter()
10852                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
10853            );
10854        }
10855
10856        local.lsp_tree.remove_nodes(&language_servers_to_stop);
10857        let tasks = language_servers_to_stop
10858            .into_iter()
10859            .map(|server| self.stop_local_language_server(server, cx))
10860            .collect::<Vec<_>>();
10861
10862        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
10863    }
10864
10865    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
10866        let (worktree, relative_path) =
10867            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
10868
10869        let project_path = ProjectPath {
10870            worktree_id: worktree.read(cx).id(),
10871            path: relative_path,
10872        };
10873
10874        Some(
10875            self.buffer_store()
10876                .read(cx)
10877                .get_by_path(&project_path)?
10878                .read(cx),
10879        )
10880    }
10881
10882    #[cfg(any(test, feature = "test-support"))]
10883    pub fn update_diagnostics(
10884        &mut self,
10885        server_id: LanguageServerId,
10886        diagnostics: lsp::PublishDiagnosticsParams,
10887        result_id: Option<String>,
10888        source_kind: DiagnosticSourceKind,
10889        disk_based_sources: &[String],
10890        cx: &mut Context<Self>,
10891    ) -> Result<()> {
10892        self.merge_lsp_diagnostics(
10893            source_kind,
10894            vec![DocumentDiagnosticsUpdate {
10895                diagnostics,
10896                result_id,
10897                server_id,
10898                disk_based_sources: Cow::Borrowed(disk_based_sources),
10899            }],
10900            |_, _, _| false,
10901            cx,
10902        )
10903    }
10904
10905    pub fn merge_lsp_diagnostics(
10906        &mut self,
10907        source_kind: DiagnosticSourceKind,
10908        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
10909        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
10910        cx: &mut Context<Self>,
10911    ) -> Result<()> {
10912        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
10913        let updates = lsp_diagnostics
10914            .into_iter()
10915            .filter_map(|update| {
10916                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
10917                Some(DocumentDiagnosticsUpdate {
10918                    diagnostics: self.lsp_to_document_diagnostics(
10919                        abs_path,
10920                        source_kind,
10921                        update.server_id,
10922                        update.diagnostics,
10923                        &update.disk_based_sources,
10924                    ),
10925                    result_id: update.result_id,
10926                    server_id: update.server_id,
10927                    disk_based_sources: update.disk_based_sources,
10928                })
10929            })
10930            .collect();
10931        self.merge_diagnostic_entries(updates, merge, cx)?;
10932        Ok(())
10933    }
10934
10935    fn lsp_to_document_diagnostics(
10936        &mut self,
10937        document_abs_path: PathBuf,
10938        source_kind: DiagnosticSourceKind,
10939        server_id: LanguageServerId,
10940        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
10941        disk_based_sources: &[String],
10942    ) -> DocumentDiagnostics {
10943        let mut diagnostics = Vec::default();
10944        let mut primary_diagnostic_group_ids = HashMap::default();
10945        let mut sources_by_group_id = HashMap::default();
10946        let mut supporting_diagnostics = HashMap::default();
10947
10948        let adapter = self.language_server_adapter_for_id(server_id);
10949
10950        // Ensure that primary diagnostics are always the most severe
10951        lsp_diagnostics
10952            .diagnostics
10953            .sort_by_key(|item| item.severity);
10954
10955        for diagnostic in &lsp_diagnostics.diagnostics {
10956            let source = diagnostic.source.as_ref();
10957            let range = range_from_lsp(diagnostic.range);
10958            let is_supporting = diagnostic
10959                .related_information
10960                .as_ref()
10961                .is_some_and(|infos| {
10962                    infos.iter().any(|info| {
10963                        primary_diagnostic_group_ids.contains_key(&(
10964                            source,
10965                            diagnostic.code.clone(),
10966                            range_from_lsp(info.location.range),
10967                        ))
10968                    })
10969                });
10970
10971            let is_unnecessary = diagnostic
10972                .tags
10973                .as_ref()
10974                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
10975
10976            let underline = self
10977                .language_server_adapter_for_id(server_id)
10978                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
10979
10980            if is_supporting {
10981                supporting_diagnostics.insert(
10982                    (source, diagnostic.code.clone(), range),
10983                    (diagnostic.severity, is_unnecessary),
10984                );
10985            } else {
10986                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
10987                let is_disk_based =
10988                    source.is_some_and(|source| disk_based_sources.contains(source));
10989
10990                sources_by_group_id.insert(group_id, source);
10991                primary_diagnostic_group_ids
10992                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
10993
10994                diagnostics.push(DiagnosticEntry {
10995                    range,
10996                    diagnostic: Diagnostic {
10997                        source: diagnostic.source.clone(),
10998                        source_kind,
10999                        code: diagnostic.code.clone(),
11000                        code_description: diagnostic
11001                            .code_description
11002                            .as_ref()
11003                            .and_then(|d| d.href.clone()),
11004                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11005                        markdown: adapter.as_ref().and_then(|adapter| {
11006                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11007                        }),
11008                        message: diagnostic.message.trim().to_string(),
11009                        group_id,
11010                        is_primary: true,
11011                        is_disk_based,
11012                        is_unnecessary,
11013                        underline,
11014                        data: diagnostic.data.clone(),
11015                    },
11016                });
11017                if let Some(infos) = &diagnostic.related_information {
11018                    for info in infos {
11019                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11020                            let range = range_from_lsp(info.location.range);
11021                            diagnostics.push(DiagnosticEntry {
11022                                range,
11023                                diagnostic: Diagnostic {
11024                                    source: diagnostic.source.clone(),
11025                                    source_kind,
11026                                    code: diagnostic.code.clone(),
11027                                    code_description: diagnostic
11028                                        .code_description
11029                                        .as_ref()
11030                                        .and_then(|d| d.href.clone()),
11031                                    severity: DiagnosticSeverity::INFORMATION,
11032                                    markdown: adapter.as_ref().and_then(|adapter| {
11033                                        adapter.diagnostic_message_to_markdown(&info.message)
11034                                    }),
11035                                    message: info.message.trim().to_string(),
11036                                    group_id,
11037                                    is_primary: false,
11038                                    is_disk_based,
11039                                    is_unnecessary: false,
11040                                    underline,
11041                                    data: diagnostic.data.clone(),
11042                                },
11043                            });
11044                        }
11045                    }
11046                }
11047            }
11048        }
11049
11050        for entry in &mut diagnostics {
11051            let diagnostic = &mut entry.diagnostic;
11052            if !diagnostic.is_primary {
11053                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11054                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11055                    source,
11056                    diagnostic.code.clone(),
11057                    entry.range.clone(),
11058                )) {
11059                    if let Some(severity) = severity {
11060                        diagnostic.severity = severity;
11061                    }
11062                    diagnostic.is_unnecessary = is_unnecessary;
11063                }
11064            }
11065        }
11066
11067        DocumentDiagnostics {
11068            diagnostics,
11069            document_abs_path,
11070            version: lsp_diagnostics.version,
11071        }
11072    }
11073
11074    fn insert_newly_running_language_server(
11075        &mut self,
11076        adapter: Arc<CachedLspAdapter>,
11077        language_server: Arc<LanguageServer>,
11078        server_id: LanguageServerId,
11079        key: LanguageServerSeed,
11080        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11081        cx: &mut Context<Self>,
11082    ) {
11083        let Some(local) = self.as_local_mut() else {
11084            return;
11085        };
11086        // If the language server for this key doesn't match the server id, don't store the
11087        // server. Which will cause it to be dropped, killing the process
11088        if local
11089            .language_server_ids
11090            .get(&key)
11091            .map(|state| state.id != server_id)
11092            .unwrap_or(false)
11093        {
11094            return;
11095        }
11096
11097        // Update language_servers collection with Running variant of LanguageServerState
11098        // indicating that the server is up and running and ready
11099        let workspace_folders = workspace_folders.lock().clone();
11100        language_server.set_workspace_folders(workspace_folders);
11101
11102        let workspace_diagnostics_refresh_tasks = language_server
11103            .capabilities()
11104            .diagnostic_provider
11105            .and_then(|provider| {
11106                local
11107                    .language_server_dynamic_registrations
11108                    .entry(server_id)
11109                    .or_default()
11110                    .diagnostics
11111                    .entry(None)
11112                    .or_insert(provider.clone());
11113                let workspace_refresher =
11114                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11115
11116                Some((None, workspace_refresher))
11117            })
11118            .into_iter()
11119            .collect();
11120        local.language_servers.insert(
11121            server_id,
11122            LanguageServerState::Running {
11123                workspace_diagnostics_refresh_tasks,
11124                adapter: adapter.clone(),
11125                server: language_server.clone(),
11126                simulate_disk_based_diagnostics_completion: None,
11127            },
11128        );
11129        local
11130            .languages
11131            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11132        if let Some(file_ops_caps) = language_server
11133            .capabilities()
11134            .workspace
11135            .as_ref()
11136            .and_then(|ws| ws.file_operations.as_ref())
11137        {
11138            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11139            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11140            if did_rename_caps.or(will_rename_caps).is_some() {
11141                let watcher = RenamePathsWatchedForServer::default()
11142                    .with_did_rename_patterns(did_rename_caps)
11143                    .with_will_rename_patterns(will_rename_caps);
11144                local
11145                    .language_server_paths_watched_for_rename
11146                    .insert(server_id, watcher);
11147            }
11148        }
11149
11150        self.language_server_statuses.insert(
11151            server_id,
11152            LanguageServerStatus {
11153                name: language_server.name(),
11154                pending_work: Default::default(),
11155                has_pending_diagnostic_updates: false,
11156                progress_tokens: Default::default(),
11157                worktree: Some(key.worktree_id),
11158            },
11159        );
11160
11161        cx.emit(LspStoreEvent::LanguageServerAdded(
11162            server_id,
11163            language_server.name(),
11164            Some(key.worktree_id),
11165        ));
11166
11167        let server_capabilities = language_server.capabilities();
11168        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11169            downstream_client
11170                .send(proto::StartLanguageServer {
11171                    project_id: *project_id,
11172                    server: Some(proto::LanguageServer {
11173                        id: server_id.to_proto(),
11174                        name: language_server.name().to_string(),
11175                        worktree_id: Some(key.worktree_id.to_proto()),
11176                    }),
11177                    capabilities: serde_json::to_string(&server_capabilities)
11178                        .expect("serializing server LSP capabilities"),
11179                })
11180                .log_err();
11181        }
11182        self.lsp_server_capabilities
11183            .insert(server_id, server_capabilities);
11184
11185        // Tell the language server about every open buffer in the worktree that matches the language.
11186        // Also check for buffers in worktrees that reused this server
11187        let mut worktrees_using_server = vec![key.worktree_id];
11188        if let Some(local) = self.as_local() {
11189            // Find all worktrees that have this server in their language server tree
11190            for (worktree_id, servers) in &local.lsp_tree.instances {
11191                if *worktree_id != key.worktree_id {
11192                    for server_map in servers.roots.values() {
11193                        if server_map
11194                            .values()
11195                            .any(|(node, _)| node.id() == Some(server_id))
11196                        {
11197                            worktrees_using_server.push(*worktree_id);
11198                        }
11199                    }
11200                }
11201            }
11202        }
11203
11204        let mut buffer_paths_registered = Vec::new();
11205        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11206            let mut lsp_adapters = HashMap::default();
11207            for buffer_handle in buffer_store.buffers() {
11208                let buffer = buffer_handle.read(cx);
11209                let file = match File::from_dyn(buffer.file()) {
11210                    Some(file) => file,
11211                    None => continue,
11212                };
11213                let language = match buffer.language() {
11214                    Some(language) => language,
11215                    None => continue,
11216                };
11217
11218                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11219                    || !lsp_adapters
11220                        .entry(language.name())
11221                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11222                        .iter()
11223                        .any(|a| a.name == key.name)
11224                {
11225                    continue;
11226                }
11227                // didOpen
11228                let file = match file.as_local() {
11229                    Some(file) => file,
11230                    None => continue,
11231                };
11232
11233                let local = self.as_local_mut().unwrap();
11234
11235                let buffer_id = buffer.remote_id();
11236                if local.registered_buffers.contains_key(&buffer_id) {
11237                    let versions = local
11238                        .buffer_snapshots
11239                        .entry(buffer_id)
11240                        .or_default()
11241                        .entry(server_id)
11242                        .and_modify(|_| {
11243                            assert!(
11244                            false,
11245                            "There should not be an existing snapshot for a newly inserted buffer"
11246                        )
11247                        })
11248                        .or_insert_with(|| {
11249                            vec![LspBufferSnapshot {
11250                                version: 0,
11251                                snapshot: buffer.text_snapshot(),
11252                            }]
11253                        });
11254
11255                    let snapshot = versions.last().unwrap();
11256                    let version = snapshot.version;
11257                    let initial_snapshot = &snapshot.snapshot;
11258                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11259                    language_server.register_buffer(
11260                        uri,
11261                        adapter.language_id(&language.name()),
11262                        version,
11263                        initial_snapshot.text(),
11264                    );
11265                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11266                    local
11267                        .buffers_opened_in_servers
11268                        .entry(buffer_id)
11269                        .or_default()
11270                        .insert(server_id);
11271                }
11272                buffer_handle.update(cx, |buffer, cx| {
11273                    buffer.set_completion_triggers(
11274                        server_id,
11275                        language_server
11276                            .capabilities()
11277                            .completion_provider
11278                            .as_ref()
11279                            .and_then(|provider| {
11280                                provider
11281                                    .trigger_characters
11282                                    .as_ref()
11283                                    .map(|characters| characters.iter().cloned().collect())
11284                            })
11285                            .unwrap_or_default(),
11286                        cx,
11287                    )
11288                });
11289            }
11290        });
11291
11292        for (buffer_id, abs_path) in buffer_paths_registered {
11293            cx.emit(LspStoreEvent::LanguageServerUpdate {
11294                language_server_id: server_id,
11295                name: Some(adapter.name()),
11296                message: proto::update_language_server::Variant::RegisteredForBuffer(
11297                    proto::RegisteredForBuffer {
11298                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11299                        buffer_id: buffer_id.to_proto(),
11300                    },
11301                ),
11302            });
11303        }
11304
11305        cx.notify();
11306    }
11307
11308    pub fn language_servers_running_disk_based_diagnostics(
11309        &self,
11310    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11311        self.language_server_statuses
11312            .iter()
11313            .filter_map(|(id, status)| {
11314                if status.has_pending_diagnostic_updates {
11315                    Some(*id)
11316                } else {
11317                    None
11318                }
11319            })
11320    }
11321
11322    pub(crate) fn cancel_language_server_work_for_buffers(
11323        &mut self,
11324        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11325        cx: &mut Context<Self>,
11326    ) {
11327        if let Some((client, project_id)) = self.upstream_client() {
11328            let request = client.request(proto::CancelLanguageServerWork {
11329                project_id,
11330                work: Some(proto::cancel_language_server_work::Work::Buffers(
11331                    proto::cancel_language_server_work::Buffers {
11332                        buffer_ids: buffers
11333                            .into_iter()
11334                            .map(|b| b.read(cx).remote_id().to_proto())
11335                            .collect(),
11336                    },
11337                )),
11338            });
11339            cx.background_spawn(request).detach_and_log_err(cx);
11340        } else if let Some(local) = self.as_local() {
11341            let servers = buffers
11342                .into_iter()
11343                .flat_map(|buffer| {
11344                    buffer.update(cx, |buffer, cx| {
11345                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11346                    })
11347                })
11348                .collect::<HashSet<_>>();
11349            for server_id in servers {
11350                self.cancel_language_server_work(server_id, None, cx);
11351            }
11352        }
11353    }
11354
11355    pub(crate) fn cancel_language_server_work(
11356        &mut self,
11357        server_id: LanguageServerId,
11358        token_to_cancel: Option<ProgressToken>,
11359        cx: &mut Context<Self>,
11360    ) {
11361        if let Some(local) = self.as_local() {
11362            let status = self.language_server_statuses.get(&server_id);
11363            let server = local.language_servers.get(&server_id);
11364            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11365            {
11366                for (token, progress) in &status.pending_work {
11367                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11368                        && token != token_to_cancel
11369                    {
11370                        continue;
11371                    }
11372                    if progress.is_cancellable {
11373                        server
11374                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11375                                WorkDoneProgressCancelParams {
11376                                    token: token.to_lsp(),
11377                                },
11378                            )
11379                            .ok();
11380                    }
11381                }
11382            }
11383        } else if let Some((client, project_id)) = self.upstream_client() {
11384            let request = client.request(proto::CancelLanguageServerWork {
11385                project_id,
11386                work: Some(
11387                    proto::cancel_language_server_work::Work::LanguageServerWork(
11388                        proto::cancel_language_server_work::LanguageServerWork {
11389                            language_server_id: server_id.to_proto(),
11390                            token: token_to_cancel.map(|token| token.to_proto()),
11391                        },
11392                    ),
11393                ),
11394            });
11395            cx.background_spawn(request).detach_and_log_err(cx);
11396        }
11397    }
11398
11399    fn register_supplementary_language_server(
11400        &mut self,
11401        id: LanguageServerId,
11402        name: LanguageServerName,
11403        server: Arc<LanguageServer>,
11404        cx: &mut Context<Self>,
11405    ) {
11406        if let Some(local) = self.as_local_mut() {
11407            local
11408                .supplementary_language_servers
11409                .insert(id, (name.clone(), server));
11410            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11411        }
11412    }
11413
11414    fn unregister_supplementary_language_server(
11415        &mut self,
11416        id: LanguageServerId,
11417        cx: &mut Context<Self>,
11418    ) {
11419        if let Some(local) = self.as_local_mut() {
11420            local.supplementary_language_servers.remove(&id);
11421            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11422        }
11423    }
11424
11425    pub(crate) fn supplementary_language_servers(
11426        &self,
11427    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11428        self.as_local().into_iter().flat_map(|local| {
11429            local
11430                .supplementary_language_servers
11431                .iter()
11432                .map(|(id, (name, _))| (*id, name.clone()))
11433        })
11434    }
11435
11436    pub fn language_server_adapter_for_id(
11437        &self,
11438        id: LanguageServerId,
11439    ) -> Option<Arc<CachedLspAdapter>> {
11440        self.as_local()
11441            .and_then(|local| local.language_servers.get(&id))
11442            .and_then(|language_server_state| match language_server_state {
11443                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11444                _ => None,
11445            })
11446    }
11447
11448    pub(super) fn update_local_worktree_language_servers(
11449        &mut self,
11450        worktree_handle: &Entity<Worktree>,
11451        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11452        cx: &mut Context<Self>,
11453    ) {
11454        if changes.is_empty() {
11455            return;
11456        }
11457
11458        let Some(local) = self.as_local() else { return };
11459
11460        local.prettier_store.update(cx, |prettier_store, cx| {
11461            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11462        });
11463
11464        let worktree_id = worktree_handle.read(cx).id();
11465        let mut language_server_ids = local
11466            .language_server_ids
11467            .iter()
11468            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11469            .collect::<Vec<_>>();
11470        language_server_ids.sort();
11471        language_server_ids.dedup();
11472
11473        // let abs_path = worktree_handle.read(cx).abs_path();
11474        for server_id in &language_server_ids {
11475            if let Some(LanguageServerState::Running { server, .. }) =
11476                local.language_servers.get(server_id)
11477                && let Some(watched_paths) = local
11478                    .language_server_watched_paths
11479                    .get(server_id)
11480                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11481            {
11482                let params = lsp::DidChangeWatchedFilesParams {
11483                    changes: changes
11484                        .iter()
11485                        .filter_map(|(path, _, change)| {
11486                            if !watched_paths.is_match(path.as_std_path()) {
11487                                return None;
11488                            }
11489                            let typ = match change {
11490                                PathChange::Loaded => return None,
11491                                PathChange::Added => lsp::FileChangeType::CREATED,
11492                                PathChange::Removed => lsp::FileChangeType::DELETED,
11493                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11494                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11495                            };
11496                            let uri = lsp::Uri::from_file_path(
11497                                worktree_handle.read(cx).absolutize(&path),
11498                            )
11499                            .ok()?;
11500                            Some(lsp::FileEvent { uri, typ })
11501                        })
11502                        .collect(),
11503                };
11504                if !params.changes.is_empty() {
11505                    server
11506                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11507                        .ok();
11508                }
11509            }
11510        }
11511        for (path, _, _) in changes {
11512            if let Some(file_name) = path.file_name()
11513                && local.watched_manifest_filenames.contains(file_name)
11514            {
11515                self.request_workspace_config_refresh();
11516                break;
11517            }
11518        }
11519    }
11520
11521    pub fn wait_for_remote_buffer(
11522        &mut self,
11523        id: BufferId,
11524        cx: &mut Context<Self>,
11525    ) -> Task<Result<Entity<Buffer>>> {
11526        self.buffer_store.update(cx, |buffer_store, cx| {
11527            buffer_store.wait_for_remote_buffer(id, cx)
11528        })
11529    }
11530
11531    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11532        let mut result = proto::Symbol {
11533            language_server_name: symbol.language_server_name.0.to_string(),
11534            source_worktree_id: symbol.source_worktree_id.to_proto(),
11535            language_server_id: symbol.source_language_server_id.to_proto(),
11536            name: symbol.name.clone(),
11537            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11538            start: Some(proto::PointUtf16 {
11539                row: symbol.range.start.0.row,
11540                column: symbol.range.start.0.column,
11541            }),
11542            end: Some(proto::PointUtf16 {
11543                row: symbol.range.end.0.row,
11544                column: symbol.range.end.0.column,
11545            }),
11546            worktree_id: Default::default(),
11547            path: Default::default(),
11548            signature: Default::default(),
11549        };
11550        match &symbol.path {
11551            SymbolLocation::InProject(path) => {
11552                result.worktree_id = path.worktree_id.to_proto();
11553                result.path = path.path.to_proto();
11554            }
11555            SymbolLocation::OutsideProject {
11556                abs_path,
11557                signature,
11558            } => {
11559                result.path = abs_path.to_string_lossy().into_owned();
11560                result.signature = signature.to_vec();
11561            }
11562        }
11563        result
11564    }
11565
11566    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11567        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11568        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11569        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11570
11571        let path = if serialized_symbol.signature.is_empty() {
11572            SymbolLocation::InProject(ProjectPath {
11573                worktree_id,
11574                path: RelPath::from_proto(&serialized_symbol.path)
11575                    .context("invalid symbol path")?,
11576            })
11577        } else {
11578            SymbolLocation::OutsideProject {
11579                abs_path: Path::new(&serialized_symbol.path).into(),
11580                signature: serialized_symbol
11581                    .signature
11582                    .try_into()
11583                    .map_err(|_| anyhow!("invalid signature"))?,
11584            }
11585        };
11586
11587        let start = serialized_symbol.start.context("invalid start")?;
11588        let end = serialized_symbol.end.context("invalid end")?;
11589        Ok(CoreSymbol {
11590            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11591            source_worktree_id,
11592            source_language_server_id: LanguageServerId::from_proto(
11593                serialized_symbol.language_server_id,
11594            ),
11595            path,
11596            name: serialized_symbol.name,
11597            range: Unclipped(PointUtf16::new(start.row, start.column))
11598                ..Unclipped(PointUtf16::new(end.row, end.column)),
11599            kind,
11600        })
11601    }
11602
11603    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11604        let mut serialized_completion = proto::Completion {
11605            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11606            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11607            new_text: completion.new_text.clone(),
11608            ..proto::Completion::default()
11609        };
11610        match &completion.source {
11611            CompletionSource::Lsp {
11612                insert_range,
11613                server_id,
11614                lsp_completion,
11615                lsp_defaults,
11616                resolved,
11617            } => {
11618                let (old_insert_start, old_insert_end) = insert_range
11619                    .as_ref()
11620                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11621                    .unzip();
11622
11623                serialized_completion.old_insert_start = old_insert_start;
11624                serialized_completion.old_insert_end = old_insert_end;
11625                serialized_completion.source = proto::completion::Source::Lsp as i32;
11626                serialized_completion.server_id = server_id.0 as u64;
11627                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11628                serialized_completion.lsp_defaults = lsp_defaults
11629                    .as_deref()
11630                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11631                serialized_completion.resolved = *resolved;
11632            }
11633            CompletionSource::BufferWord {
11634                word_range,
11635                resolved,
11636            } => {
11637                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11638                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11639                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11640                serialized_completion.resolved = *resolved;
11641            }
11642            CompletionSource::Custom => {
11643                serialized_completion.source = proto::completion::Source::Custom as i32;
11644                serialized_completion.resolved = true;
11645            }
11646            CompletionSource::Dap { sort_text } => {
11647                serialized_completion.source = proto::completion::Source::Dap as i32;
11648                serialized_completion.sort_text = Some(sort_text.clone());
11649            }
11650        }
11651
11652        serialized_completion
11653    }
11654
11655    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11656        let old_replace_start = completion
11657            .old_replace_start
11658            .and_then(deserialize_anchor)
11659            .context("invalid old start")?;
11660        let old_replace_end = completion
11661            .old_replace_end
11662            .and_then(deserialize_anchor)
11663            .context("invalid old end")?;
11664        let insert_range = {
11665            match completion.old_insert_start.zip(completion.old_insert_end) {
11666                Some((start, end)) => {
11667                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11668                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11669                    Some(start..end)
11670                }
11671                None => None,
11672            }
11673        };
11674        Ok(CoreCompletion {
11675            replace_range: old_replace_start..old_replace_end,
11676            new_text: completion.new_text,
11677            source: match proto::completion::Source::from_i32(completion.source) {
11678                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11679                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11680                    insert_range,
11681                    server_id: LanguageServerId::from_proto(completion.server_id),
11682                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11683                    lsp_defaults: completion
11684                        .lsp_defaults
11685                        .as_deref()
11686                        .map(serde_json::from_slice)
11687                        .transpose()?,
11688                    resolved: completion.resolved,
11689                },
11690                Some(proto::completion::Source::BufferWord) => {
11691                    let word_range = completion
11692                        .buffer_word_start
11693                        .and_then(deserialize_anchor)
11694                        .context("invalid buffer word start")?
11695                        ..completion
11696                            .buffer_word_end
11697                            .and_then(deserialize_anchor)
11698                            .context("invalid buffer word end")?;
11699                    CompletionSource::BufferWord {
11700                        word_range,
11701                        resolved: completion.resolved,
11702                    }
11703                }
11704                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11705                    sort_text: completion
11706                        .sort_text
11707                        .context("expected sort text to exist")?,
11708                },
11709                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11710            },
11711        })
11712    }
11713
11714    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11715        let (kind, lsp_action) = match &action.lsp_action {
11716            LspAction::Action(code_action) => (
11717                proto::code_action::Kind::Action as i32,
11718                serde_json::to_vec(code_action).unwrap(),
11719            ),
11720            LspAction::Command(command) => (
11721                proto::code_action::Kind::Command as i32,
11722                serde_json::to_vec(command).unwrap(),
11723            ),
11724            LspAction::CodeLens(code_lens) => (
11725                proto::code_action::Kind::CodeLens as i32,
11726                serde_json::to_vec(code_lens).unwrap(),
11727            ),
11728        };
11729
11730        proto::CodeAction {
11731            server_id: action.server_id.0 as u64,
11732            start: Some(serialize_anchor(&action.range.start)),
11733            end: Some(serialize_anchor(&action.range.end)),
11734            lsp_action,
11735            kind,
11736            resolved: action.resolved,
11737        }
11738    }
11739
11740    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11741        let start = action
11742            .start
11743            .and_then(deserialize_anchor)
11744            .context("invalid start")?;
11745        let end = action
11746            .end
11747            .and_then(deserialize_anchor)
11748            .context("invalid end")?;
11749        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11750            Some(proto::code_action::Kind::Action) => {
11751                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11752            }
11753            Some(proto::code_action::Kind::Command) => {
11754                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11755            }
11756            Some(proto::code_action::Kind::CodeLens) => {
11757                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11758            }
11759            None => anyhow::bail!("Unknown action kind {}", action.kind),
11760        };
11761        Ok(CodeAction {
11762            server_id: LanguageServerId(action.server_id as usize),
11763            range: start..end,
11764            resolved: action.resolved,
11765            lsp_action,
11766        })
11767    }
11768
11769    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11770        match &formatting_result {
11771            Ok(_) => self.last_formatting_failure = None,
11772            Err(error) => {
11773                let error_string = format!("{error:#}");
11774                log::error!("Formatting failed: {error_string}");
11775                self.last_formatting_failure
11776                    .replace(error_string.lines().join(" "));
11777            }
11778        }
11779    }
11780
11781    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11782        self.lsp_server_capabilities.remove(&for_server);
11783        for lsp_data in self.lsp_data.values_mut() {
11784            lsp_data.remove_server_data(for_server);
11785        }
11786        if let Some(local) = self.as_local_mut() {
11787            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11788            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11789                buffer_servers.remove(&for_server);
11790            }
11791        }
11792    }
11793
11794    pub fn result_id(
11795        &self,
11796        server_id: LanguageServerId,
11797        buffer_id: BufferId,
11798        cx: &App,
11799    ) -> Option<String> {
11800        let abs_path = self
11801            .buffer_store
11802            .read(cx)
11803            .get(buffer_id)
11804            .and_then(|b| File::from_dyn(b.read(cx).file()))
11805            .map(|f| f.abs_path(cx))?;
11806        self.as_local()?
11807            .buffer_pull_diagnostics_result_ids
11808            .get(&server_id)?
11809            .get(&abs_path)?
11810            .clone()
11811    }
11812
11813    pub fn all_result_ids(&self, server_id: LanguageServerId) -> HashMap<PathBuf, String> {
11814        let Some(local) = self.as_local() else {
11815            return HashMap::default();
11816        };
11817        local
11818            .buffer_pull_diagnostics_result_ids
11819            .get(&server_id)
11820            .into_iter()
11821            .flatten()
11822            .filter_map(|(abs_path, result_id)| Some((abs_path.clone(), result_id.clone()?)))
11823            .collect()
11824    }
11825
11826    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
11827        if let Some(LanguageServerState::Running {
11828            workspace_diagnostics_refresh_tasks,
11829            ..
11830        }) = self
11831            .as_local_mut()
11832            .and_then(|local| local.language_servers.get_mut(&server_id))
11833        {
11834            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
11835                diagnostics.refresh_tx.try_send(()).ok();
11836            }
11837        }
11838    }
11839
11840    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
11841        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
11842            return;
11843        };
11844        let Some(local) = self.as_local_mut() else {
11845            return;
11846        };
11847
11848        for server_id in buffer.update(cx, |buffer, cx| {
11849            local.language_server_ids_for_buffer(buffer, cx)
11850        }) {
11851            if let Some(LanguageServerState::Running {
11852                workspace_diagnostics_refresh_tasks,
11853                ..
11854            }) = local.language_servers.get_mut(&server_id)
11855            {
11856                for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
11857                    diagnostics.refresh_tx.try_send(()).ok();
11858                }
11859            }
11860        }
11861    }
11862
11863    fn apply_workspace_diagnostic_report(
11864        &mut self,
11865        server_id: LanguageServerId,
11866        report: lsp::WorkspaceDiagnosticReportResult,
11867        cx: &mut Context<Self>,
11868    ) {
11869        let workspace_diagnostics =
11870            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(report, server_id);
11871        let mut unchanged_buffers = HashSet::default();
11872        let mut changed_buffers = HashSet::default();
11873        let workspace_diagnostics_updates = workspace_diagnostics
11874            .into_iter()
11875            .filter_map(
11876                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
11877                    LspPullDiagnostics::Response {
11878                        server_id,
11879                        uri,
11880                        diagnostics,
11881                    } => Some((server_id, uri, diagnostics, workspace_diagnostics.version)),
11882                    LspPullDiagnostics::Default => None,
11883                },
11884            )
11885            .fold(
11886                HashMap::default(),
11887                |mut acc, (server_id, uri, diagnostics, version)| {
11888                    let (result_id, diagnostics) = match diagnostics {
11889                        PulledDiagnostics::Unchanged { result_id } => {
11890                            unchanged_buffers.insert(uri.clone());
11891                            (Some(result_id), Vec::new())
11892                        }
11893                        PulledDiagnostics::Changed {
11894                            result_id,
11895                            diagnostics,
11896                        } => {
11897                            changed_buffers.insert(uri.clone());
11898                            (result_id, diagnostics)
11899                        }
11900                    };
11901                    let disk_based_sources = Cow::Owned(
11902                        self.language_server_adapter_for_id(server_id)
11903                            .as_ref()
11904                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
11905                            .unwrap_or(&[])
11906                            .to_vec(),
11907                    );
11908                    acc.entry(server_id)
11909                        .or_insert_with(Vec::new)
11910                        .push(DocumentDiagnosticsUpdate {
11911                            server_id,
11912                            diagnostics: lsp::PublishDiagnosticsParams {
11913                                uri,
11914                                diagnostics,
11915                                version,
11916                            },
11917                            result_id,
11918                            disk_based_sources,
11919                        });
11920                    acc
11921                },
11922            );
11923
11924        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
11925            self.merge_lsp_diagnostics(
11926                DiagnosticSourceKind::Pulled,
11927                diagnostic_updates,
11928                |buffer, old_diagnostic, cx| {
11929                    File::from_dyn(buffer.file())
11930                        .and_then(|file| {
11931                            let abs_path = file.as_local()?.abs_path(cx);
11932                            lsp::Uri::from_file_path(abs_path).ok()
11933                        })
11934                        .is_none_or(|buffer_uri| {
11935                            unchanged_buffers.contains(&buffer_uri)
11936                                || match old_diagnostic.source_kind {
11937                                    DiagnosticSourceKind::Pulled => {
11938                                        !changed_buffers.contains(&buffer_uri)
11939                                    }
11940                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
11941                                        true
11942                                    }
11943                                }
11944                        })
11945                },
11946                cx,
11947            )
11948            .log_err();
11949        }
11950    }
11951
11952    fn register_server_capabilities(
11953        &mut self,
11954        server_id: LanguageServerId,
11955        params: lsp::RegistrationParams,
11956        cx: &mut Context<Self>,
11957    ) -> anyhow::Result<()> {
11958        let server = self
11959            .language_server_for_id(server_id)
11960            .with_context(|| format!("no server {server_id} found"))?;
11961        for reg in params.registrations {
11962            match reg.method.as_str() {
11963                "workspace/didChangeWatchedFiles" => {
11964                    if let Some(options) = reg.register_options {
11965                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11966                            let caps = serde_json::from_value(options)?;
11967                            local_lsp_store
11968                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
11969                            true
11970                        } else {
11971                            false
11972                        };
11973                        if notify {
11974                            notify_server_capabilities_updated(&server, cx);
11975                        }
11976                    }
11977                }
11978                "workspace/didChangeConfiguration" => {
11979                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11980                }
11981                "workspace/didChangeWorkspaceFolders" => {
11982                    // In this case register options is an empty object, we can ignore it
11983                    let caps = lsp::WorkspaceFoldersServerCapabilities {
11984                        supported: Some(true),
11985                        change_notifications: Some(OneOf::Right(reg.id)),
11986                    };
11987                    server.update_capabilities(|capabilities| {
11988                        capabilities
11989                            .workspace
11990                            .get_or_insert_default()
11991                            .workspace_folders = Some(caps);
11992                    });
11993                    notify_server_capabilities_updated(&server, cx);
11994                }
11995                "workspace/symbol" => {
11996                    let options = parse_register_capabilities(reg)?;
11997                    server.update_capabilities(|capabilities| {
11998                        capabilities.workspace_symbol_provider = Some(options);
11999                    });
12000                    notify_server_capabilities_updated(&server, cx);
12001                }
12002                "workspace/fileOperations" => {
12003                    if let Some(options) = reg.register_options {
12004                        let caps = serde_json::from_value(options)?;
12005                        server.update_capabilities(|capabilities| {
12006                            capabilities
12007                                .workspace
12008                                .get_or_insert_default()
12009                                .file_operations = Some(caps);
12010                        });
12011                        notify_server_capabilities_updated(&server, cx);
12012                    }
12013                }
12014                "workspace/executeCommand" => {
12015                    if let Some(options) = reg.register_options {
12016                        let options = serde_json::from_value(options)?;
12017                        server.update_capabilities(|capabilities| {
12018                            capabilities.execute_command_provider = Some(options);
12019                        });
12020                        notify_server_capabilities_updated(&server, cx);
12021                    }
12022                }
12023                "textDocument/rangeFormatting" => {
12024                    let options = parse_register_capabilities(reg)?;
12025                    server.update_capabilities(|capabilities| {
12026                        capabilities.document_range_formatting_provider = Some(options);
12027                    });
12028                    notify_server_capabilities_updated(&server, cx);
12029                }
12030                "textDocument/onTypeFormatting" => {
12031                    if let Some(options) = reg
12032                        .register_options
12033                        .map(serde_json::from_value)
12034                        .transpose()?
12035                    {
12036                        server.update_capabilities(|capabilities| {
12037                            capabilities.document_on_type_formatting_provider = Some(options);
12038                        });
12039                        notify_server_capabilities_updated(&server, cx);
12040                    }
12041                }
12042                "textDocument/formatting" => {
12043                    let options = parse_register_capabilities(reg)?;
12044                    server.update_capabilities(|capabilities| {
12045                        capabilities.document_formatting_provider = Some(options);
12046                    });
12047                    notify_server_capabilities_updated(&server, cx);
12048                }
12049                "textDocument/rename" => {
12050                    let options = parse_register_capabilities(reg)?;
12051                    server.update_capabilities(|capabilities| {
12052                        capabilities.rename_provider = Some(options);
12053                    });
12054                    notify_server_capabilities_updated(&server, cx);
12055                }
12056                "textDocument/inlayHint" => {
12057                    let options = parse_register_capabilities(reg)?;
12058                    server.update_capabilities(|capabilities| {
12059                        capabilities.inlay_hint_provider = Some(options);
12060                    });
12061                    notify_server_capabilities_updated(&server, cx);
12062                }
12063                "textDocument/documentSymbol" => {
12064                    let options = parse_register_capabilities(reg)?;
12065                    server.update_capabilities(|capabilities| {
12066                        capabilities.document_symbol_provider = Some(options);
12067                    });
12068                    notify_server_capabilities_updated(&server, cx);
12069                }
12070                "textDocument/codeAction" => {
12071                    let options = parse_register_capabilities(reg)?;
12072                    let provider = match options {
12073                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12074                        OneOf::Right(caps) => caps,
12075                    };
12076                    server.update_capabilities(|capabilities| {
12077                        capabilities.code_action_provider = Some(provider);
12078                    });
12079                    notify_server_capabilities_updated(&server, cx);
12080                }
12081                "textDocument/definition" => {
12082                    let options = parse_register_capabilities(reg)?;
12083                    server.update_capabilities(|capabilities| {
12084                        capabilities.definition_provider = Some(options);
12085                    });
12086                    notify_server_capabilities_updated(&server, cx);
12087                }
12088                "textDocument/completion" => {
12089                    if let Some(caps) = reg
12090                        .register_options
12091                        .map(serde_json::from_value::<CompletionOptions>)
12092                        .transpose()?
12093                    {
12094                        server.update_capabilities(|capabilities| {
12095                            capabilities.completion_provider = Some(caps.clone());
12096                        });
12097
12098                        if let Some(local) = self.as_local() {
12099                            let mut buffers_with_language_server = Vec::new();
12100                            for handle in self.buffer_store.read(cx).buffers() {
12101                                let buffer_id = handle.read(cx).remote_id();
12102                                if local
12103                                    .buffers_opened_in_servers
12104                                    .get(&buffer_id)
12105                                    .filter(|s| s.contains(&server_id))
12106                                    .is_some()
12107                                {
12108                                    buffers_with_language_server.push(handle);
12109                                }
12110                            }
12111                            let triggers = caps
12112                                .trigger_characters
12113                                .unwrap_or_default()
12114                                .into_iter()
12115                                .collect::<BTreeSet<_>>();
12116                            for handle in buffers_with_language_server {
12117                                let triggers = triggers.clone();
12118                                let _ = handle.update(cx, move |buffer, cx| {
12119                                    buffer.set_completion_triggers(server_id, triggers, cx);
12120                                });
12121                            }
12122                        }
12123                        notify_server_capabilities_updated(&server, cx);
12124                    }
12125                }
12126                "textDocument/hover" => {
12127                    let options = parse_register_capabilities(reg)?;
12128                    let provider = match options {
12129                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12130                        OneOf::Right(caps) => caps,
12131                    };
12132                    server.update_capabilities(|capabilities| {
12133                        capabilities.hover_provider = Some(provider);
12134                    });
12135                    notify_server_capabilities_updated(&server, cx);
12136                }
12137                "textDocument/signatureHelp" => {
12138                    if let Some(caps) = reg
12139                        .register_options
12140                        .map(serde_json::from_value)
12141                        .transpose()?
12142                    {
12143                        server.update_capabilities(|capabilities| {
12144                            capabilities.signature_help_provider = Some(caps);
12145                        });
12146                        notify_server_capabilities_updated(&server, cx);
12147                    }
12148                }
12149                "textDocument/didChange" => {
12150                    if let Some(sync_kind) = reg
12151                        .register_options
12152                        .and_then(|opts| opts.get("syncKind").cloned())
12153                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12154                        .transpose()?
12155                    {
12156                        server.update_capabilities(|capabilities| {
12157                            let mut sync_options =
12158                                Self::take_text_document_sync_options(capabilities);
12159                            sync_options.change = Some(sync_kind);
12160                            capabilities.text_document_sync =
12161                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12162                        });
12163                        notify_server_capabilities_updated(&server, cx);
12164                    }
12165                }
12166                "textDocument/didSave" => {
12167                    if let Some(include_text) = reg
12168                        .register_options
12169                        .map(|opts| {
12170                            let transpose = opts
12171                                .get("includeText")
12172                                .cloned()
12173                                .map(serde_json::from_value::<Option<bool>>)
12174                                .transpose();
12175                            match transpose {
12176                                Ok(value) => Ok(value.flatten()),
12177                                Err(e) => Err(e),
12178                            }
12179                        })
12180                        .transpose()?
12181                    {
12182                        server.update_capabilities(|capabilities| {
12183                            let mut sync_options =
12184                                Self::take_text_document_sync_options(capabilities);
12185                            sync_options.save =
12186                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12187                                    include_text,
12188                                }));
12189                            capabilities.text_document_sync =
12190                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12191                        });
12192                        notify_server_capabilities_updated(&server, cx);
12193                    }
12194                }
12195                "textDocument/codeLens" => {
12196                    if let Some(caps) = reg
12197                        .register_options
12198                        .map(serde_json::from_value)
12199                        .transpose()?
12200                    {
12201                        server.update_capabilities(|capabilities| {
12202                            capabilities.code_lens_provider = Some(caps);
12203                        });
12204                        notify_server_capabilities_updated(&server, cx);
12205                    }
12206                }
12207                "textDocument/diagnostic" => {
12208                    if let Some(caps) = reg
12209                        .register_options
12210                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12211                        .transpose()?
12212                    {
12213                        let local = self
12214                            .as_local_mut()
12215                            .context("Expected LSP Store to be local")?;
12216                        let state = local
12217                            .language_servers
12218                            .get_mut(&server_id)
12219                            .context("Could not obtain Language Servers state")?;
12220                        local
12221                            .language_server_dynamic_registrations
12222                            .entry(server_id)
12223                            .or_default()
12224                            .diagnostics
12225                            .insert(Some(reg.id.clone()), caps.clone());
12226
12227                        if let LanguageServerState::Running {
12228                            workspace_diagnostics_refresh_tasks,
12229                            ..
12230                        } = state
12231                            && let Some(task) = lsp_workspace_diagnostics_refresh(
12232                                Some(reg.id.clone()),
12233                                caps.clone(),
12234                                server.clone(),
12235                                cx,
12236                            )
12237                        {
12238                            workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12239                        }
12240
12241                        let mut did_update_caps = false;
12242                        server.update_capabilities(|capabilities| {
12243                            if capabilities.diagnostic_provider.as_ref().is_none_or(
12244                                |current_caps| {
12245                                    let supports_workspace_diagnostics =
12246                                        |capabilities: &DiagnosticServerCapabilities| {
12247                                            match capabilities {
12248                                            DiagnosticServerCapabilities::Options(
12249                                                diagnostic_options,
12250                                            ) => diagnostic_options.workspace_diagnostics,
12251                                            DiagnosticServerCapabilities::RegistrationOptions(
12252                                                diagnostic_registration_options,
12253                                            ) => {
12254                                                diagnostic_registration_options
12255                                                    .diagnostic_options
12256                                                    .workspace_diagnostics
12257                                            }
12258                                        }
12259                                        };
12260                                    // We don't actually care about capabilities.diagnostic_provider, but it IS relevant for the remote peer
12261                                    // to know that there's at least one provider. Otherwise, it will never ask us to issue documentdiagnostic calls on their behalf,
12262                                    // as it'll think that they're not supported.
12263                                    // If we did not support any workspace diagnostics up to this point but now do, let's update.
12264                                    !supports_workspace_diagnostics(current_caps)
12265                                        & supports_workspace_diagnostics(&caps)
12266                                },
12267                            ) {
12268                                did_update_caps = true;
12269                                capabilities.diagnostic_provider = Some(caps);
12270                            }
12271                        });
12272                        if did_update_caps {
12273                            notify_server_capabilities_updated(&server, cx);
12274                        }
12275                    }
12276                }
12277                "textDocument/documentColor" => {
12278                    let options = parse_register_capabilities(reg)?;
12279                    let provider = match options {
12280                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12281                        OneOf::Right(caps) => caps,
12282                    };
12283                    server.update_capabilities(|capabilities| {
12284                        capabilities.color_provider = Some(provider);
12285                    });
12286                    notify_server_capabilities_updated(&server, cx);
12287                }
12288                _ => log::warn!("unhandled capability registration: {reg:?}"),
12289            }
12290        }
12291
12292        Ok(())
12293    }
12294
12295    fn unregister_server_capabilities(
12296        &mut self,
12297        server_id: LanguageServerId,
12298        params: lsp::UnregistrationParams,
12299        cx: &mut Context<Self>,
12300    ) -> anyhow::Result<()> {
12301        let server = self
12302            .language_server_for_id(server_id)
12303            .with_context(|| format!("no server {server_id} found"))?;
12304        for unreg in params.unregisterations.iter() {
12305            match unreg.method.as_str() {
12306                "workspace/didChangeWatchedFiles" => {
12307                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12308                        local_lsp_store
12309                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12310                        true
12311                    } else {
12312                        false
12313                    };
12314                    if notify {
12315                        notify_server_capabilities_updated(&server, cx);
12316                    }
12317                }
12318                "workspace/didChangeConfiguration" => {
12319                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12320                }
12321                "workspace/didChangeWorkspaceFolders" => {
12322                    server.update_capabilities(|capabilities| {
12323                        capabilities
12324                            .workspace
12325                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12326                                workspace_folders: None,
12327                                file_operations: None,
12328                            })
12329                            .workspace_folders = None;
12330                    });
12331                    notify_server_capabilities_updated(&server, cx);
12332                }
12333                "workspace/symbol" => {
12334                    server.update_capabilities(|capabilities| {
12335                        capabilities.workspace_symbol_provider = None
12336                    });
12337                    notify_server_capabilities_updated(&server, cx);
12338                }
12339                "workspace/fileOperations" => {
12340                    server.update_capabilities(|capabilities| {
12341                        capabilities
12342                            .workspace
12343                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12344                                workspace_folders: None,
12345                                file_operations: None,
12346                            })
12347                            .file_operations = None;
12348                    });
12349                    notify_server_capabilities_updated(&server, cx);
12350                }
12351                "workspace/executeCommand" => {
12352                    server.update_capabilities(|capabilities| {
12353                        capabilities.execute_command_provider = None;
12354                    });
12355                    notify_server_capabilities_updated(&server, cx);
12356                }
12357                "textDocument/rangeFormatting" => {
12358                    server.update_capabilities(|capabilities| {
12359                        capabilities.document_range_formatting_provider = None
12360                    });
12361                    notify_server_capabilities_updated(&server, cx);
12362                }
12363                "textDocument/onTypeFormatting" => {
12364                    server.update_capabilities(|capabilities| {
12365                        capabilities.document_on_type_formatting_provider = None;
12366                    });
12367                    notify_server_capabilities_updated(&server, cx);
12368                }
12369                "textDocument/formatting" => {
12370                    server.update_capabilities(|capabilities| {
12371                        capabilities.document_formatting_provider = None;
12372                    });
12373                    notify_server_capabilities_updated(&server, cx);
12374                }
12375                "textDocument/rename" => {
12376                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12377                    notify_server_capabilities_updated(&server, cx);
12378                }
12379                "textDocument/codeAction" => {
12380                    server.update_capabilities(|capabilities| {
12381                        capabilities.code_action_provider = None;
12382                    });
12383                    notify_server_capabilities_updated(&server, cx);
12384                }
12385                "textDocument/definition" => {
12386                    server.update_capabilities(|capabilities| {
12387                        capabilities.definition_provider = None;
12388                    });
12389                    notify_server_capabilities_updated(&server, cx);
12390                }
12391                "textDocument/completion" => {
12392                    server.update_capabilities(|capabilities| {
12393                        capabilities.completion_provider = None;
12394                    });
12395                    notify_server_capabilities_updated(&server, cx);
12396                }
12397                "textDocument/hover" => {
12398                    server.update_capabilities(|capabilities| {
12399                        capabilities.hover_provider = None;
12400                    });
12401                    notify_server_capabilities_updated(&server, cx);
12402                }
12403                "textDocument/signatureHelp" => {
12404                    server.update_capabilities(|capabilities| {
12405                        capabilities.signature_help_provider = None;
12406                    });
12407                    notify_server_capabilities_updated(&server, cx);
12408                }
12409                "textDocument/didChange" => {
12410                    server.update_capabilities(|capabilities| {
12411                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12412                        sync_options.change = None;
12413                        capabilities.text_document_sync =
12414                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12415                    });
12416                    notify_server_capabilities_updated(&server, cx);
12417                }
12418                "textDocument/didSave" => {
12419                    server.update_capabilities(|capabilities| {
12420                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12421                        sync_options.save = None;
12422                        capabilities.text_document_sync =
12423                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12424                    });
12425                    notify_server_capabilities_updated(&server, cx);
12426                }
12427                "textDocument/codeLens" => {
12428                    server.update_capabilities(|capabilities| {
12429                        capabilities.code_lens_provider = None;
12430                    });
12431                    notify_server_capabilities_updated(&server, cx);
12432                }
12433                "textDocument/diagnostic" => {
12434                    let local = self
12435                        .as_local_mut()
12436                        .context("Expected LSP Store to be local")?;
12437
12438                    let state = local
12439                        .language_servers
12440                        .get_mut(&server_id)
12441                        .context("Could not obtain Language Servers state")?;
12442                    let options = local
12443                        .language_server_dynamic_registrations
12444                        .get_mut(&server_id)
12445                        .with_context(|| {
12446                            format!("Expected dynamic registration to exist for server {server_id}")
12447                        })?.diagnostics
12448                        .remove(&Some(unreg.id.clone()))
12449                        .with_context(|| format!(
12450                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12451                            unreg.id)
12452                        )?;
12453
12454                    let mut has_any_diagnostic_providers_still = true;
12455                    if let Some(identifier) = diagnostic_identifier(&options)
12456                        && let LanguageServerState::Running {
12457                            workspace_diagnostics_refresh_tasks,
12458                            ..
12459                        } = state
12460                    {
12461                        workspace_diagnostics_refresh_tasks.remove(&identifier);
12462                        has_any_diagnostic_providers_still =
12463                            !workspace_diagnostics_refresh_tasks.is_empty();
12464                    }
12465
12466                    if !has_any_diagnostic_providers_still {
12467                        server.update_capabilities(|capabilities| {
12468                            debug_assert!(capabilities.diagnostic_provider.is_some());
12469                            capabilities.diagnostic_provider = None;
12470                        });
12471                    }
12472
12473                    notify_server_capabilities_updated(&server, cx);
12474                }
12475                "textDocument/documentColor" => {
12476                    server.update_capabilities(|capabilities| {
12477                        capabilities.color_provider = None;
12478                    });
12479                    notify_server_capabilities_updated(&server, cx);
12480                }
12481                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12482            }
12483        }
12484
12485        Ok(())
12486    }
12487
12488    async fn deduplicate_range_based_lsp_requests<T>(
12489        lsp_store: &Entity<Self>,
12490        server_id: Option<LanguageServerId>,
12491        lsp_request_id: LspRequestId,
12492        proto_request: &T::ProtoRequest,
12493        range: Range<Anchor>,
12494        cx: &mut AsyncApp,
12495    ) -> Result<()>
12496    where
12497        T: LspCommand,
12498        T::ProtoRequest: proto::LspRequestMessage,
12499    {
12500        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12501        let version = deserialize_version(proto_request.buffer_version());
12502        let buffer = lsp_store.update(cx, |this, cx| {
12503            this.buffer_store.read(cx).get_existing(buffer_id)
12504        })??;
12505        buffer
12506            .update(cx, |buffer, _| buffer.wait_for_version(version))?
12507            .await?;
12508        lsp_store.update(cx, |lsp_store, cx| {
12509            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12510            let chunks_queried_for = lsp_data
12511                .inlay_hints
12512                .applicable_chunks(&[range])
12513                .collect::<Vec<_>>();
12514            match chunks_queried_for.as_slice() {
12515                &[chunk] => {
12516                    let key = LspKey {
12517                        request_type: TypeId::of::<T>(),
12518                        server_queried: server_id,
12519                    };
12520                    let previous_request = lsp_data
12521                        .chunk_lsp_requests
12522                        .entry(key)
12523                        .or_default()
12524                        .insert(chunk, lsp_request_id);
12525                    if let Some((previous_request, running_requests)) =
12526                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12527                    {
12528                        running_requests.remove(&previous_request);
12529                    }
12530                }
12531                _ambiguous_chunks => {
12532                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12533                    // there, a buffer version-based check will be performed and outdated requests discarded.
12534                }
12535            }
12536            anyhow::Ok(())
12537        })??;
12538
12539        Ok(())
12540    }
12541
12542    async fn query_lsp_locally<T>(
12543        lsp_store: Entity<Self>,
12544        for_server_id: Option<LanguageServerId>,
12545        sender_id: proto::PeerId,
12546        lsp_request_id: LspRequestId,
12547        proto_request: T::ProtoRequest,
12548        position: Option<Anchor>,
12549        cx: &mut AsyncApp,
12550    ) -> Result<()>
12551    where
12552        T: LspCommand + Clone,
12553        T::ProtoRequest: proto::LspRequestMessage,
12554        <T::ProtoRequest as proto::RequestMessage>::Response:
12555            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12556    {
12557        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12558        let version = deserialize_version(proto_request.buffer_version());
12559        let buffer = lsp_store.update(cx, |this, cx| {
12560            this.buffer_store.read(cx).get_existing(buffer_id)
12561        })??;
12562        buffer
12563            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))?
12564            .await?;
12565        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version())?;
12566        let request =
12567            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12568        let key = LspKey {
12569            request_type: TypeId::of::<T>(),
12570            server_queried: for_server_id,
12571        };
12572        lsp_store.update(cx, |lsp_store, cx| {
12573            let request_task = match for_server_id {
12574                Some(server_id) => {
12575                    let server_task = lsp_store.request_lsp(
12576                        buffer.clone(),
12577                        LanguageServerToQuery::Other(server_id),
12578                        request.clone(),
12579                        cx,
12580                    );
12581                    cx.background_spawn(async move {
12582                        let mut responses = Vec::new();
12583                        match server_task.await {
12584                            Ok(response) => responses.push((server_id, response)),
12585                            // rust-analyzer likes to error with this when its still loading up
12586                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
12587                            Err(e) => log::error!(
12588                                "Error handling response for request {request:?}: {e:#}"
12589                            ),
12590                        }
12591                        responses
12592                    })
12593                }
12594                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12595            };
12596            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12597            if T::ProtoRequest::stop_previous_requests() {
12598                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12599                    lsp_requests.clear();
12600                }
12601            }
12602            lsp_data.lsp_requests.entry(key).or_default().insert(
12603                lsp_request_id,
12604                cx.spawn(async move |lsp_store, cx| {
12605                    let response = request_task.await;
12606                    lsp_store
12607                        .update(cx, |lsp_store, cx| {
12608                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12609                            {
12610                                let response = response
12611                                    .into_iter()
12612                                    .map(|(server_id, response)| {
12613                                        (
12614                                            server_id.to_proto(),
12615                                            T::response_to_proto(
12616                                                response,
12617                                                lsp_store,
12618                                                sender_id,
12619                                                &buffer_version,
12620                                                cx,
12621                                            )
12622                                            .into(),
12623                                        )
12624                                    })
12625                                    .collect::<HashMap<_, _>>();
12626                                match client.send_lsp_response::<T::ProtoRequest>(
12627                                    project_id,
12628                                    lsp_request_id,
12629                                    response,
12630                                ) {
12631                                    Ok(()) => {}
12632                                    Err(e) => {
12633                                        log::error!("Failed to send LSP response: {e:#}",)
12634                                    }
12635                                }
12636                            }
12637                        })
12638                        .ok();
12639                }),
12640            );
12641        })?;
12642        Ok(())
12643    }
12644
12645    fn take_text_document_sync_options(
12646        capabilities: &mut lsp::ServerCapabilities,
12647    ) -> lsp::TextDocumentSyncOptions {
12648        match capabilities.text_document_sync.take() {
12649            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12650            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12651                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12652                sync_options.change = Some(sync_kind);
12653                sync_options
12654            }
12655            None => lsp::TextDocumentSyncOptions::default(),
12656        }
12657    }
12658
12659    #[cfg(any(test, feature = "test-support"))]
12660    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
12661        Some(
12662            self.lsp_data
12663                .get_mut(&buffer_id)?
12664                .code_lens
12665                .take()?
12666                .update
12667                .take()?
12668                .1,
12669        )
12670    }
12671
12672    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
12673        self.downstream_client.clone()
12674    }
12675
12676    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
12677        self.worktree_store.clone()
12678    }
12679
12680    /// Gets what's stored in the LSP data for the given buffer.
12681    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
12682        self.lsp_data.get_mut(&buffer_id)
12683    }
12684
12685    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
12686    /// new [`BufferLspData`] will be created to replace the previous state.
12687    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
12688        let (buffer_id, buffer_version) =
12689            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
12690        let lsp_data = self
12691            .lsp_data
12692            .entry(buffer_id)
12693            .or_insert_with(|| BufferLspData::new(buffer, cx));
12694        if buffer_version.changed_since(&lsp_data.buffer_version) {
12695            *lsp_data = BufferLspData::new(buffer, cx);
12696        }
12697        lsp_data
12698    }
12699}
12700
12701// Registration with registerOptions as null, should fallback to true.
12702// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
12703fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
12704    reg: lsp::Registration,
12705) -> Result<OneOf<bool, T>> {
12706    Ok(match reg.register_options {
12707        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
12708        None => OneOf::Left(true),
12709    })
12710}
12711
12712fn subscribe_to_binary_statuses(
12713    languages: &Arc<LanguageRegistry>,
12714    cx: &mut Context<'_, LspStore>,
12715) -> Task<()> {
12716    let mut server_statuses = languages.language_server_binary_statuses();
12717    cx.spawn(async move |lsp_store, cx| {
12718        while let Some((server_name, binary_status)) = server_statuses.next().await {
12719            if lsp_store
12720                .update(cx, |_, cx| {
12721                    let mut message = None;
12722                    let binary_status = match binary_status {
12723                        BinaryStatus::None => proto::ServerBinaryStatus::None,
12724                        BinaryStatus::CheckingForUpdate => {
12725                            proto::ServerBinaryStatus::CheckingForUpdate
12726                        }
12727                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
12728                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
12729                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
12730                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
12731                        BinaryStatus::Failed { error } => {
12732                            message = Some(error);
12733                            proto::ServerBinaryStatus::Failed
12734                        }
12735                    };
12736                    cx.emit(LspStoreEvent::LanguageServerUpdate {
12737                        // Binary updates are about the binary that might not have any language server id at that point.
12738                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
12739                        language_server_id: LanguageServerId(0),
12740                        name: Some(server_name),
12741                        message: proto::update_language_server::Variant::StatusUpdate(
12742                            proto::StatusUpdate {
12743                                message,
12744                                status: Some(proto::status_update::Status::Binary(
12745                                    binary_status as i32,
12746                                )),
12747                            },
12748                        ),
12749                    });
12750                })
12751                .is_err()
12752            {
12753                break;
12754            }
12755        }
12756    })
12757}
12758
12759fn lsp_workspace_diagnostics_refresh(
12760    registration_id: Option<String>,
12761    options: DiagnosticServerCapabilities,
12762    server: Arc<LanguageServer>,
12763    cx: &mut Context<'_, LspStore>,
12764) -> Option<WorkspaceRefreshTask> {
12765    let identifier = diagnostic_identifier(&options)?;
12766
12767    let (progress_tx, mut progress_rx) = mpsc::channel(1);
12768    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
12769    refresh_tx.try_send(()).ok();
12770
12771    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
12772        let mut attempts = 0;
12773        let max_attempts = 50;
12774        let mut requests = 0;
12775
12776        loop {
12777            let Some(()) = refresh_rx.recv().await else {
12778                return;
12779            };
12780
12781            'request: loop {
12782                requests += 1;
12783                if attempts > max_attempts {
12784                    log::error!(
12785                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
12786                    );
12787                    return;
12788                }
12789                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
12790                cx.background_executor()
12791                    .timer(Duration::from_millis(backoff_millis))
12792                    .await;
12793                attempts += 1;
12794
12795                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
12796                    lsp_store
12797                        .all_result_ids(server.server_id())
12798                        .into_iter()
12799                        .filter_map(|(abs_path, result_id)| {
12800                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
12801                            Some(lsp::PreviousResultId {
12802                                uri,
12803                                value: result_id,
12804                            })
12805                        })
12806                        .collect()
12807                }) else {
12808                    return;
12809                };
12810
12811                let token = if let Some(identifier) = &registration_id {
12812                    format!(
12813                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{identifier}",
12814                        server.server_id(),
12815                    )
12816                } else {
12817                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
12818                };
12819
12820                progress_rx.try_recv().ok();
12821                let timer =
12822                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
12823                let progress = pin!(progress_rx.recv().fuse());
12824                let response_result = server
12825                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
12826                        lsp::WorkspaceDiagnosticParams {
12827                            previous_result_ids,
12828                            identifier: identifier.clone(),
12829                            work_done_progress_params: Default::default(),
12830                            partial_result_params: lsp::PartialResultParams {
12831                                partial_result_token: Some(lsp::ProgressToken::String(token)),
12832                            },
12833                        },
12834                        select(timer, progress).then(|either| match either {
12835                            Either::Left((message, ..)) => ready(message).left_future(),
12836                            Either::Right(..) => pending::<String>().right_future(),
12837                        }),
12838                    )
12839                    .await;
12840
12841                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
12842                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
12843                match response_result {
12844                    ConnectionResult::Timeout => {
12845                        log::error!("Timeout during workspace diagnostics pull");
12846                        continue 'request;
12847                    }
12848                    ConnectionResult::ConnectionReset => {
12849                        log::error!("Server closed a workspace diagnostics pull request");
12850                        continue 'request;
12851                    }
12852                    ConnectionResult::Result(Err(e)) => {
12853                        log::error!("Error during workspace diagnostics pull: {e:#}");
12854                        break 'request;
12855                    }
12856                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
12857                        attempts = 0;
12858                        if lsp_store
12859                            .update(cx, |lsp_store, cx| {
12860                                lsp_store.apply_workspace_diagnostic_report(
12861                                    server.server_id(),
12862                                    pulled_diagnostics,
12863                                    cx,
12864                                )
12865                            })
12866                            .is_err()
12867                        {
12868                            return;
12869                        }
12870                        break 'request;
12871                    }
12872                }
12873            }
12874        }
12875    });
12876
12877    Some(WorkspaceRefreshTask {
12878        refresh_tx,
12879        progress_tx,
12880        task: workspace_query_language_server,
12881    })
12882}
12883
12884fn diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<Option<String>> {
12885    match &options {
12886        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
12887            if !diagnostic_options.workspace_diagnostics {
12888                return None;
12889            }
12890            Some(diagnostic_options.identifier.clone())
12891        }
12892        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
12893            let diagnostic_options = &registration_options.diagnostic_options;
12894            if !diagnostic_options.workspace_diagnostics {
12895                return None;
12896            }
12897            Some(diagnostic_options.identifier.clone())
12898        }
12899    }
12900}
12901
12902fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
12903    let CompletionSource::BufferWord {
12904        word_range,
12905        resolved,
12906    } = &mut completion.source
12907    else {
12908        return;
12909    };
12910    if *resolved {
12911        return;
12912    }
12913
12914    if completion.new_text
12915        != snapshot
12916            .text_for_range(word_range.clone())
12917            .collect::<String>()
12918    {
12919        return;
12920    }
12921
12922    let mut offset = 0;
12923    for chunk in snapshot.chunks(word_range.clone(), true) {
12924        let end_offset = offset + chunk.text.len();
12925        if let Some(highlight_id) = chunk.syntax_highlight_id {
12926            completion
12927                .label
12928                .runs
12929                .push((offset..end_offset, highlight_id));
12930        }
12931        offset = end_offset;
12932    }
12933    *resolved = true;
12934}
12935
12936impl EventEmitter<LspStoreEvent> for LspStore {}
12937
12938fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
12939    hover
12940        .contents
12941        .retain(|hover_block| !hover_block.text.trim().is_empty());
12942    if hover.contents.is_empty() {
12943        None
12944    } else {
12945        Some(hover)
12946    }
12947}
12948
12949async fn populate_labels_for_completions(
12950    new_completions: Vec<CoreCompletion>,
12951    language: Option<Arc<Language>>,
12952    lsp_adapter: Option<Arc<CachedLspAdapter>>,
12953) -> Vec<Completion> {
12954    let lsp_completions = new_completions
12955        .iter()
12956        .filter_map(|new_completion| {
12957            new_completion
12958                .source
12959                .lsp_completion(true)
12960                .map(|lsp_completion| lsp_completion.into_owned())
12961        })
12962        .collect::<Vec<_>>();
12963
12964    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
12965        lsp_adapter
12966            .labels_for_completions(&lsp_completions, language)
12967            .await
12968            .log_err()
12969            .unwrap_or_default()
12970    } else {
12971        Vec::new()
12972    }
12973    .into_iter()
12974    .fuse();
12975
12976    let mut completions = Vec::new();
12977    for completion in new_completions {
12978        match completion.source.lsp_completion(true) {
12979            Some(lsp_completion) => {
12980                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
12981
12982                let mut label = labels.next().flatten().unwrap_or_else(|| {
12983                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
12984                });
12985                ensure_uniform_list_compatible_label(&mut label);
12986                completions.push(Completion {
12987                    label,
12988                    documentation,
12989                    replace_range: completion.replace_range,
12990                    new_text: completion.new_text,
12991                    insert_text_mode: lsp_completion.insert_text_mode,
12992                    source: completion.source,
12993                    icon_path: None,
12994                    confirm: None,
12995                    match_start: None,
12996                    snippet_deduplication_key: None,
12997                });
12998            }
12999            None => {
13000                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13001                ensure_uniform_list_compatible_label(&mut label);
13002                completions.push(Completion {
13003                    label,
13004                    documentation: None,
13005                    replace_range: completion.replace_range,
13006                    new_text: completion.new_text,
13007                    source: completion.source,
13008                    insert_text_mode: None,
13009                    icon_path: None,
13010                    confirm: None,
13011                    match_start: None,
13012                    snippet_deduplication_key: None,
13013                });
13014            }
13015        }
13016    }
13017    completions
13018}
13019
13020#[derive(Debug)]
13021pub enum LanguageServerToQuery {
13022    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13023    FirstCapable,
13024    /// Query a specific language server.
13025    Other(LanguageServerId),
13026}
13027
13028#[derive(Default)]
13029struct RenamePathsWatchedForServer {
13030    did_rename: Vec<RenameActionPredicate>,
13031    will_rename: Vec<RenameActionPredicate>,
13032}
13033
13034impl RenamePathsWatchedForServer {
13035    fn with_did_rename_patterns(
13036        mut self,
13037        did_rename: Option<&FileOperationRegistrationOptions>,
13038    ) -> Self {
13039        if let Some(did_rename) = did_rename {
13040            self.did_rename = did_rename
13041                .filters
13042                .iter()
13043                .filter_map(|filter| filter.try_into().log_err())
13044                .collect();
13045        }
13046        self
13047    }
13048    fn with_will_rename_patterns(
13049        mut self,
13050        will_rename: Option<&FileOperationRegistrationOptions>,
13051    ) -> Self {
13052        if let Some(will_rename) = will_rename {
13053            self.will_rename = will_rename
13054                .filters
13055                .iter()
13056                .filter_map(|filter| filter.try_into().log_err())
13057                .collect();
13058        }
13059        self
13060    }
13061
13062    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13063        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13064    }
13065    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13066        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13067    }
13068}
13069
13070impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13071    type Error = globset::Error;
13072    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13073        Ok(Self {
13074            kind: ops.pattern.matches.clone(),
13075            glob: GlobBuilder::new(&ops.pattern.glob)
13076                .case_insensitive(
13077                    ops.pattern
13078                        .options
13079                        .as_ref()
13080                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13081                )
13082                .build()?
13083                .compile_matcher(),
13084        })
13085    }
13086}
13087struct RenameActionPredicate {
13088    glob: GlobMatcher,
13089    kind: Option<FileOperationPatternKind>,
13090}
13091
13092impl RenameActionPredicate {
13093    // Returns true if language server should be notified
13094    fn eval(&self, path: &str, is_dir: bool) -> bool {
13095        self.kind.as_ref().is_none_or(|kind| {
13096            let expected_kind = if is_dir {
13097                FileOperationPatternKind::Folder
13098            } else {
13099                FileOperationPatternKind::File
13100            };
13101            kind == &expected_kind
13102        }) && self.glob.is_match(path)
13103    }
13104}
13105
13106#[derive(Default)]
13107struct LanguageServerWatchedPaths {
13108    worktree_paths: HashMap<WorktreeId, GlobSet>,
13109    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13110}
13111
13112#[derive(Default)]
13113struct LanguageServerWatchedPathsBuilder {
13114    worktree_paths: HashMap<WorktreeId, GlobSet>,
13115    abs_paths: HashMap<Arc<Path>, GlobSet>,
13116}
13117
13118impl LanguageServerWatchedPathsBuilder {
13119    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13120        self.worktree_paths.insert(worktree_id, glob_set);
13121    }
13122    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13123        self.abs_paths.insert(path, glob_set);
13124    }
13125    fn build(
13126        self,
13127        fs: Arc<dyn Fs>,
13128        language_server_id: LanguageServerId,
13129        cx: &mut Context<LspStore>,
13130    ) -> LanguageServerWatchedPaths {
13131        let lsp_store = cx.weak_entity();
13132
13133        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13134        let abs_paths = self
13135            .abs_paths
13136            .into_iter()
13137            .map(|(abs_path, globset)| {
13138                let task = cx.spawn({
13139                    let abs_path = abs_path.clone();
13140                    let fs = fs.clone();
13141
13142                    let lsp_store = lsp_store.clone();
13143                    async move |_, cx| {
13144                        maybe!(async move {
13145                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13146                            while let Some(update) = push_updates.0.next().await {
13147                                let action = lsp_store
13148                                    .update(cx, |this, _| {
13149                                        let Some(local) = this.as_local() else {
13150                                            return ControlFlow::Break(());
13151                                        };
13152                                        let Some(watcher) = local
13153                                            .language_server_watched_paths
13154                                            .get(&language_server_id)
13155                                        else {
13156                                            return ControlFlow::Break(());
13157                                        };
13158                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13159                                            "Watched abs path is not registered with a watcher",
13160                                        );
13161                                        let matching_entries = update
13162                                            .into_iter()
13163                                            .filter(|event| globs.is_match(&event.path))
13164                                            .collect::<Vec<_>>();
13165                                        this.lsp_notify_abs_paths_changed(
13166                                            language_server_id,
13167                                            matching_entries,
13168                                        );
13169                                        ControlFlow::Continue(())
13170                                    })
13171                                    .ok()?;
13172
13173                                if action.is_break() {
13174                                    break;
13175                                }
13176                            }
13177                            Some(())
13178                        })
13179                        .await;
13180                    }
13181                });
13182                (abs_path, (globset, task))
13183            })
13184            .collect();
13185        LanguageServerWatchedPaths {
13186            worktree_paths: self.worktree_paths,
13187            abs_paths,
13188        }
13189    }
13190}
13191
13192struct LspBufferSnapshot {
13193    version: i32,
13194    snapshot: TextBufferSnapshot,
13195}
13196
13197/// A prompt requested by LSP server.
13198#[derive(Clone, Debug)]
13199pub struct LanguageServerPromptRequest {
13200    pub level: PromptLevel,
13201    pub message: String,
13202    pub actions: Vec<MessageActionItem>,
13203    pub lsp_name: String,
13204    pub(crate) response_channel: Sender<MessageActionItem>,
13205}
13206
13207impl LanguageServerPromptRequest {
13208    pub async fn respond(self, index: usize) -> Option<()> {
13209        if let Some(response) = self.actions.into_iter().nth(index) {
13210            self.response_channel.send(response).await.ok()
13211        } else {
13212            None
13213        }
13214    }
13215}
13216impl PartialEq for LanguageServerPromptRequest {
13217    fn eq(&self, other: &Self) -> bool {
13218        self.message == other.message && self.actions == other.actions
13219    }
13220}
13221
13222#[derive(Clone, Debug, PartialEq)]
13223pub enum LanguageServerLogType {
13224    Log(MessageType),
13225    Trace { verbose_info: Option<String> },
13226    Rpc { received: bool },
13227}
13228
13229impl LanguageServerLogType {
13230    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13231        match self {
13232            Self::Log(log_type) => {
13233                use proto::log_message::LogLevel;
13234                let level = match *log_type {
13235                    MessageType::ERROR => LogLevel::Error,
13236                    MessageType::WARNING => LogLevel::Warning,
13237                    MessageType::INFO => LogLevel::Info,
13238                    MessageType::LOG => LogLevel::Log,
13239                    other => {
13240                        log::warn!("Unknown lsp log message type: {other:?}");
13241                        LogLevel::Log
13242                    }
13243                };
13244                proto::language_server_log::LogType::Log(proto::LogMessage {
13245                    level: level as i32,
13246                })
13247            }
13248            Self::Trace { verbose_info } => {
13249                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13250                    verbose_info: verbose_info.to_owned(),
13251                })
13252            }
13253            Self::Rpc { received } => {
13254                let kind = if *received {
13255                    proto::rpc_message::Kind::Received
13256                } else {
13257                    proto::rpc_message::Kind::Sent
13258                };
13259                let kind = kind as i32;
13260                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13261            }
13262        }
13263    }
13264
13265    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13266        use proto::log_message::LogLevel;
13267        use proto::rpc_message;
13268        match log_type {
13269            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13270                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13271                    LogLevel::Error => MessageType::ERROR,
13272                    LogLevel::Warning => MessageType::WARNING,
13273                    LogLevel::Info => MessageType::INFO,
13274                    LogLevel::Log => MessageType::LOG,
13275                },
13276            ),
13277            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13278                verbose_info: trace_message.verbose_info,
13279            },
13280            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13281                received: match rpc_message::Kind::from_i32(message.kind)
13282                    .unwrap_or(rpc_message::Kind::Received)
13283                {
13284                    rpc_message::Kind::Received => true,
13285                    rpc_message::Kind::Sent => false,
13286                },
13287            },
13288        }
13289    }
13290}
13291
13292pub struct WorkspaceRefreshTask {
13293    refresh_tx: mpsc::Sender<()>,
13294    progress_tx: mpsc::Sender<()>,
13295    #[allow(dead_code)]
13296    task: Task<()>,
13297}
13298
13299pub enum LanguageServerState {
13300    Starting {
13301        startup: Task<Option<Arc<LanguageServer>>>,
13302        /// List of language servers that will be added to the workspace once it's initialization completes.
13303        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13304    },
13305
13306    Running {
13307        adapter: Arc<CachedLspAdapter>,
13308        server: Arc<LanguageServer>,
13309        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13310        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13311    },
13312}
13313
13314impl LanguageServerState {
13315    fn add_workspace_folder(&self, uri: Uri) {
13316        match self {
13317            LanguageServerState::Starting {
13318                pending_workspace_folders,
13319                ..
13320            } => {
13321                pending_workspace_folders.lock().insert(uri);
13322            }
13323            LanguageServerState::Running { server, .. } => {
13324                server.add_workspace_folder(uri);
13325            }
13326        }
13327    }
13328    fn _remove_workspace_folder(&self, uri: Uri) {
13329        match self {
13330            LanguageServerState::Starting {
13331                pending_workspace_folders,
13332                ..
13333            } => {
13334                pending_workspace_folders.lock().remove(&uri);
13335            }
13336            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13337        }
13338    }
13339}
13340
13341impl std::fmt::Debug for LanguageServerState {
13342    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13343        match self {
13344            LanguageServerState::Starting { .. } => {
13345                f.debug_struct("LanguageServerState::Starting").finish()
13346            }
13347            LanguageServerState::Running { .. } => {
13348                f.debug_struct("LanguageServerState::Running").finish()
13349            }
13350        }
13351    }
13352}
13353
13354#[derive(Clone, Debug, Serialize)]
13355pub struct LanguageServerProgress {
13356    pub is_disk_based_diagnostics_progress: bool,
13357    pub is_cancellable: bool,
13358    pub title: Option<String>,
13359    pub message: Option<String>,
13360    pub percentage: Option<usize>,
13361    #[serde(skip_serializing)]
13362    pub last_update_at: Instant,
13363}
13364
13365#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13366pub struct DiagnosticSummary {
13367    pub error_count: usize,
13368    pub warning_count: usize,
13369}
13370
13371impl DiagnosticSummary {
13372    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13373        let mut this = Self {
13374            error_count: 0,
13375            warning_count: 0,
13376        };
13377
13378        for entry in diagnostics {
13379            if entry.diagnostic.is_primary {
13380                match entry.diagnostic.severity {
13381                    DiagnosticSeverity::ERROR => this.error_count += 1,
13382                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13383                    _ => {}
13384                }
13385            }
13386        }
13387
13388        this
13389    }
13390
13391    pub fn is_empty(&self) -> bool {
13392        self.error_count == 0 && self.warning_count == 0
13393    }
13394
13395    pub fn to_proto(
13396        self,
13397        language_server_id: LanguageServerId,
13398        path: &RelPath,
13399    ) -> proto::DiagnosticSummary {
13400        proto::DiagnosticSummary {
13401            path: path.to_proto(),
13402            language_server_id: language_server_id.0 as u64,
13403            error_count: self.error_count as u32,
13404            warning_count: self.warning_count as u32,
13405        }
13406    }
13407}
13408
13409#[derive(Clone, Debug)]
13410pub enum CompletionDocumentation {
13411    /// There is no documentation for this completion.
13412    Undocumented,
13413    /// A single line of documentation.
13414    SingleLine(SharedString),
13415    /// Multiple lines of plain text documentation.
13416    MultiLinePlainText(SharedString),
13417    /// Markdown documentation.
13418    MultiLineMarkdown(SharedString),
13419    /// Both single line and multiple lines of plain text documentation.
13420    SingleLineAndMultiLinePlainText {
13421        single_line: SharedString,
13422        plain_text: Option<SharedString>,
13423    },
13424}
13425
13426impl CompletionDocumentation {
13427    #[cfg(any(test, feature = "test-support"))]
13428    pub fn text(&self) -> SharedString {
13429        match self {
13430            CompletionDocumentation::Undocumented => "".into(),
13431            CompletionDocumentation::SingleLine(s) => s.clone(),
13432            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13433            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13434            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13435                single_line.clone()
13436            }
13437        }
13438    }
13439}
13440
13441impl From<lsp::Documentation> for CompletionDocumentation {
13442    fn from(docs: lsp::Documentation) -> Self {
13443        match docs {
13444            lsp::Documentation::String(text) => {
13445                if text.lines().count() <= 1 {
13446                    CompletionDocumentation::SingleLine(text.into())
13447                } else {
13448                    CompletionDocumentation::MultiLinePlainText(text.into())
13449                }
13450            }
13451
13452            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13453                lsp::MarkupKind::PlainText => {
13454                    if value.lines().count() <= 1 {
13455                        CompletionDocumentation::SingleLine(value.into())
13456                    } else {
13457                        CompletionDocumentation::MultiLinePlainText(value.into())
13458                    }
13459                }
13460
13461                lsp::MarkupKind::Markdown => {
13462                    CompletionDocumentation::MultiLineMarkdown(value.into())
13463                }
13464            },
13465        }
13466    }
13467}
13468
13469pub enum ResolvedHint {
13470    Resolved(InlayHint),
13471    Resolving(Shared<Task<()>>),
13472}
13473
13474fn glob_literal_prefix(glob: &Path) -> PathBuf {
13475    glob.components()
13476        .take_while(|component| match component {
13477            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13478            _ => true,
13479        })
13480        .collect()
13481}
13482
13483pub struct SshLspAdapter {
13484    name: LanguageServerName,
13485    binary: LanguageServerBinary,
13486    initialization_options: Option<String>,
13487    code_action_kinds: Option<Vec<CodeActionKind>>,
13488}
13489
13490impl SshLspAdapter {
13491    pub fn new(
13492        name: LanguageServerName,
13493        binary: LanguageServerBinary,
13494        initialization_options: Option<String>,
13495        code_action_kinds: Option<String>,
13496    ) -> Self {
13497        Self {
13498            name,
13499            binary,
13500            initialization_options,
13501            code_action_kinds: code_action_kinds
13502                .as_ref()
13503                .and_then(|c| serde_json::from_str(c).ok()),
13504        }
13505    }
13506}
13507
13508impl LspInstaller for SshLspAdapter {
13509    type BinaryVersion = ();
13510    async fn check_if_user_installed(
13511        &self,
13512        _: &dyn LspAdapterDelegate,
13513        _: Option<Toolchain>,
13514        _: &AsyncApp,
13515    ) -> Option<LanguageServerBinary> {
13516        Some(self.binary.clone())
13517    }
13518
13519    async fn cached_server_binary(
13520        &self,
13521        _: PathBuf,
13522        _: &dyn LspAdapterDelegate,
13523    ) -> Option<LanguageServerBinary> {
13524        None
13525    }
13526
13527    async fn fetch_latest_server_version(
13528        &self,
13529        _: &dyn LspAdapterDelegate,
13530        _: bool,
13531        _: &mut AsyncApp,
13532    ) -> Result<()> {
13533        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13534    }
13535
13536    async fn fetch_server_binary(
13537        &self,
13538        _: (),
13539        _: PathBuf,
13540        _: &dyn LspAdapterDelegate,
13541    ) -> Result<LanguageServerBinary> {
13542        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13543    }
13544}
13545
13546#[async_trait(?Send)]
13547impl LspAdapter for SshLspAdapter {
13548    fn name(&self) -> LanguageServerName {
13549        self.name.clone()
13550    }
13551
13552    async fn initialization_options(
13553        self: Arc<Self>,
13554        _: &Arc<dyn LspAdapterDelegate>,
13555    ) -> Result<Option<serde_json::Value>> {
13556        let Some(options) = &self.initialization_options else {
13557            return Ok(None);
13558        };
13559        let result = serde_json::from_str(options)?;
13560        Ok(result)
13561    }
13562
13563    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13564        self.code_action_kinds.clone()
13565    }
13566}
13567
13568pub fn language_server_settings<'a>(
13569    delegate: &'a dyn LspAdapterDelegate,
13570    language: &LanguageServerName,
13571    cx: &'a App,
13572) -> Option<&'a LspSettings> {
13573    language_server_settings_for(
13574        SettingsLocation {
13575            worktree_id: delegate.worktree_id(),
13576            path: RelPath::empty(),
13577        },
13578        language,
13579        cx,
13580    )
13581}
13582
13583pub(crate) fn language_server_settings_for<'a>(
13584    location: SettingsLocation<'a>,
13585    language: &LanguageServerName,
13586    cx: &'a App,
13587) -> Option<&'a LspSettings> {
13588    ProjectSettings::get(Some(location), cx).lsp.get(language)
13589}
13590
13591pub struct LocalLspAdapterDelegate {
13592    lsp_store: WeakEntity<LspStore>,
13593    worktree: worktree::Snapshot,
13594    fs: Arc<dyn Fs>,
13595    http_client: Arc<dyn HttpClient>,
13596    language_registry: Arc<LanguageRegistry>,
13597    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13598}
13599
13600impl LocalLspAdapterDelegate {
13601    pub fn new(
13602        language_registry: Arc<LanguageRegistry>,
13603        environment: &Entity<ProjectEnvironment>,
13604        lsp_store: WeakEntity<LspStore>,
13605        worktree: &Entity<Worktree>,
13606        http_client: Arc<dyn HttpClient>,
13607        fs: Arc<dyn Fs>,
13608        cx: &mut App,
13609    ) -> Arc<Self> {
13610        let load_shell_env_task =
13611            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
13612
13613        Arc::new(Self {
13614            lsp_store,
13615            worktree: worktree.read(cx).snapshot(),
13616            fs,
13617            http_client,
13618            language_registry,
13619            load_shell_env_task,
13620        })
13621    }
13622
13623    fn from_local_lsp(
13624        local: &LocalLspStore,
13625        worktree: &Entity<Worktree>,
13626        cx: &mut App,
13627    ) -> Arc<Self> {
13628        Self::new(
13629            local.languages.clone(),
13630            &local.environment,
13631            local.weak.clone(),
13632            worktree,
13633            local.http_client.clone(),
13634            local.fs.clone(),
13635            cx,
13636        )
13637    }
13638}
13639
13640#[async_trait]
13641impl LspAdapterDelegate for LocalLspAdapterDelegate {
13642    fn show_notification(&self, message: &str, cx: &mut App) {
13643        self.lsp_store
13644            .update(cx, |_, cx| {
13645                cx.emit(LspStoreEvent::Notification(message.to_owned()))
13646            })
13647            .ok();
13648    }
13649
13650    fn http_client(&self) -> Arc<dyn HttpClient> {
13651        self.http_client.clone()
13652    }
13653
13654    fn worktree_id(&self) -> WorktreeId {
13655        self.worktree.id()
13656    }
13657
13658    fn worktree_root_path(&self) -> &Path {
13659        self.worktree.abs_path().as_ref()
13660    }
13661
13662    fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
13663        self.worktree.resolve_executable_path(path)
13664    }
13665
13666    async fn shell_env(&self) -> HashMap<String, String> {
13667        let task = self.load_shell_env_task.clone();
13668        task.await.unwrap_or_default()
13669    }
13670
13671    async fn npm_package_installed_version(
13672        &self,
13673        package_name: &str,
13674    ) -> Result<Option<(PathBuf, String)>> {
13675        let local_package_directory = self.worktree_root_path();
13676        let node_modules_directory = local_package_directory.join("node_modules");
13677
13678        if let Some(version) =
13679            read_package_installed_version(node_modules_directory.clone(), package_name).await?
13680        {
13681            return Ok(Some((node_modules_directory, version)));
13682        }
13683        let Some(npm) = self.which("npm".as_ref()).await else {
13684            log::warn!(
13685                "Failed to find npm executable for {:?}",
13686                local_package_directory
13687            );
13688            return Ok(None);
13689        };
13690
13691        let env = self.shell_env().await;
13692        let output = util::command::new_smol_command(&npm)
13693            .args(["root", "-g"])
13694            .envs(env)
13695            .current_dir(local_package_directory)
13696            .output()
13697            .await?;
13698        let global_node_modules =
13699            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
13700
13701        if let Some(version) =
13702            read_package_installed_version(global_node_modules.clone(), package_name).await?
13703        {
13704            return Ok(Some((global_node_modules, version)));
13705        }
13706        return Ok(None);
13707    }
13708
13709    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
13710        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
13711        if self.fs.is_file(&worktree_abs_path).await {
13712            worktree_abs_path.pop();
13713        }
13714
13715        let env = self.shell_env().await;
13716
13717        let shell_path = env.get("PATH").cloned();
13718
13719        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
13720    }
13721
13722    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
13723        let mut working_dir = self.worktree_root_path().to_path_buf();
13724        if self.fs.is_file(&working_dir).await {
13725            working_dir.pop();
13726        }
13727        let output = util::command::new_smol_command(&command.path)
13728            .args(command.arguments)
13729            .envs(command.env.clone().unwrap_or_default())
13730            .current_dir(working_dir)
13731            .output()
13732            .await?;
13733
13734        anyhow::ensure!(
13735            output.status.success(),
13736            "{}, stdout: {:?}, stderr: {:?}",
13737            output.status,
13738            String::from_utf8_lossy(&output.stdout),
13739            String::from_utf8_lossy(&output.stderr)
13740        );
13741        Ok(())
13742    }
13743
13744    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
13745        self.language_registry
13746            .update_lsp_binary_status(server_name, status);
13747    }
13748
13749    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
13750        self.language_registry
13751            .all_lsp_adapters()
13752            .into_iter()
13753            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
13754            .collect()
13755    }
13756
13757    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
13758        let dir = self.language_registry.language_server_download_dir(name)?;
13759
13760        if !dir.exists() {
13761            smol::fs::create_dir_all(&dir)
13762                .await
13763                .context("failed to create container directory")
13764                .log_err()?;
13765        }
13766
13767        Some(dir)
13768    }
13769
13770    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
13771        let entry = self
13772            .worktree
13773            .entry_for_path(path)
13774            .with_context(|| format!("no worktree entry for path {path:?}"))?;
13775        let abs_path = self.worktree.absolutize(&entry.path);
13776        self.fs.load(&abs_path).await
13777    }
13778}
13779
13780async fn populate_labels_for_symbols(
13781    symbols: Vec<CoreSymbol>,
13782    language_registry: &Arc<LanguageRegistry>,
13783    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13784    output: &mut Vec<Symbol>,
13785) {
13786    #[allow(clippy::mutable_key_type)]
13787    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
13788
13789    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
13790    for symbol in symbols {
13791        let Some(file_name) = symbol.path.file_name() else {
13792            continue;
13793        };
13794        let language = language_registry
13795            .load_language_for_file_path(Path::new(file_name))
13796            .await
13797            .ok()
13798            .or_else(|| {
13799                unknown_paths.insert(file_name.into());
13800                None
13801            });
13802        symbols_by_language
13803            .entry(language)
13804            .or_default()
13805            .push(symbol);
13806    }
13807
13808    for unknown_path in unknown_paths {
13809        log::info!("no language found for symbol in file {unknown_path:?}");
13810    }
13811
13812    let mut label_params = Vec::new();
13813    for (language, mut symbols) in symbols_by_language {
13814        label_params.clear();
13815        label_params.extend(
13816            symbols
13817                .iter_mut()
13818                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
13819        );
13820
13821        let mut labels = Vec::new();
13822        if let Some(language) = language {
13823            let lsp_adapter = lsp_adapter.clone().or_else(|| {
13824                language_registry
13825                    .lsp_adapters(&language.name())
13826                    .first()
13827                    .cloned()
13828            });
13829            if let Some(lsp_adapter) = lsp_adapter {
13830                labels = lsp_adapter
13831                    .labels_for_symbols(&label_params, &language)
13832                    .await
13833                    .log_err()
13834                    .unwrap_or_default();
13835            }
13836        }
13837
13838        for ((symbol, (name, _)), label) in symbols
13839            .into_iter()
13840            .zip(label_params.drain(..))
13841            .zip(labels.into_iter().chain(iter::repeat(None)))
13842        {
13843            output.push(Symbol {
13844                language_server_name: symbol.language_server_name,
13845                source_worktree_id: symbol.source_worktree_id,
13846                source_language_server_id: symbol.source_language_server_id,
13847                path: symbol.path,
13848                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
13849                name,
13850                kind: symbol.kind,
13851                range: symbol.range,
13852            });
13853        }
13854    }
13855}
13856
13857fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
13858    match server.capabilities().text_document_sync.as_ref()? {
13859        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
13860            // Server wants didSave but didn't specify includeText.
13861            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
13862            // Server doesn't want didSave at all.
13863            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
13864            // Server provided SaveOptions.
13865            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
13866                Some(save_options.include_text.unwrap_or(false))
13867            }
13868        },
13869        // We do not have any save info. Kind affects didChange only.
13870        lsp::TextDocumentSyncCapability::Kind(_) => None,
13871    }
13872}
13873
13874/// Completion items are displayed in a `UniformList`.
13875/// Usually, those items are single-line strings, but in LSP responses,
13876/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
13877/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
13878/// 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,
13879/// breaking the completions menu presentation.
13880///
13881/// 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.
13882fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
13883    let mut new_text = String::with_capacity(label.text.len());
13884    let mut offset_map = vec![0; label.text.len() + 1];
13885    let mut last_char_was_space = false;
13886    let mut new_idx = 0;
13887    let chars = label.text.char_indices().fuse();
13888    let mut newlines_removed = false;
13889
13890    for (idx, c) in chars {
13891        offset_map[idx] = new_idx;
13892
13893        match c {
13894            '\n' if last_char_was_space => {
13895                newlines_removed = true;
13896            }
13897            '\t' | ' ' if last_char_was_space => {}
13898            '\n' if !last_char_was_space => {
13899                new_text.push(' ');
13900                new_idx += 1;
13901                last_char_was_space = true;
13902                newlines_removed = true;
13903            }
13904            ' ' | '\t' => {
13905                new_text.push(' ');
13906                new_idx += 1;
13907                last_char_was_space = true;
13908            }
13909            _ => {
13910                new_text.push(c);
13911                new_idx += c.len_utf8();
13912                last_char_was_space = false;
13913            }
13914        }
13915    }
13916    offset_map[label.text.len()] = new_idx;
13917
13918    // Only modify the label if newlines were removed.
13919    if !newlines_removed {
13920        return;
13921    }
13922
13923    let last_index = new_idx;
13924    let mut run_ranges_errors = Vec::new();
13925    label.runs.retain_mut(|(range, _)| {
13926        match offset_map.get(range.start) {
13927            Some(&start) => range.start = start,
13928            None => {
13929                run_ranges_errors.push(range.clone());
13930                return false;
13931            }
13932        }
13933
13934        match offset_map.get(range.end) {
13935            Some(&end) => range.end = end,
13936            None => {
13937                run_ranges_errors.push(range.clone());
13938                range.end = last_index;
13939            }
13940        }
13941        true
13942    });
13943    if !run_ranges_errors.is_empty() {
13944        log::error!(
13945            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
13946            label.text
13947        );
13948    }
13949
13950    let mut wrong_filter_range = None;
13951    if label.filter_range == (0..label.text.len()) {
13952        label.filter_range = 0..new_text.len();
13953    } else {
13954        let mut original_filter_range = Some(label.filter_range.clone());
13955        match offset_map.get(label.filter_range.start) {
13956            Some(&start) => label.filter_range.start = start,
13957            None => {
13958                wrong_filter_range = original_filter_range.take();
13959                label.filter_range.start = last_index;
13960            }
13961        }
13962
13963        match offset_map.get(label.filter_range.end) {
13964            Some(&end) => label.filter_range.end = end,
13965            None => {
13966                wrong_filter_range = original_filter_range.take();
13967                label.filter_range.end = last_index;
13968            }
13969        }
13970    }
13971    if let Some(wrong_filter_range) = wrong_filter_range {
13972        log::error!(
13973            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
13974            label.text
13975        );
13976    }
13977
13978    label.text = new_text;
13979}
13980
13981#[cfg(test)]
13982mod tests {
13983    use language::HighlightId;
13984
13985    use super::*;
13986
13987    #[test]
13988    fn test_glob_literal_prefix() {
13989        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
13990        assert_eq!(
13991            glob_literal_prefix(Path::new("node_modules/**/*.js")),
13992            Path::new("node_modules")
13993        );
13994        assert_eq!(
13995            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13996            Path::new("foo")
13997        );
13998        assert_eq!(
13999            glob_literal_prefix(Path::new("foo/bar/baz.js")),
14000            Path::new("foo/bar/baz.js")
14001        );
14002
14003        #[cfg(target_os = "windows")]
14004        {
14005            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
14006            assert_eq!(
14007                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
14008                Path::new("node_modules")
14009            );
14010            assert_eq!(
14011                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
14012                Path::new("foo")
14013            );
14014            assert_eq!(
14015                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
14016                Path::new("foo/bar/baz.js")
14017            );
14018        }
14019    }
14020
14021    #[test]
14022    fn test_multi_len_chars_normalization() {
14023        let mut label = CodeLabel::new(
14024            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
14025            0..6,
14026            vec![(0..6, HighlightId(1))],
14027        );
14028        ensure_uniform_list_compatible_label(&mut label);
14029        assert_eq!(
14030            label,
14031            CodeLabel::new(
14032                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
14033                0..6,
14034                vec![(0..6, HighlightId(1))],
14035            )
14036        );
14037    }
14038}