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    trusted_worktrees::{PathTrust, TrustedWorktrees, TrustedWorktreesEvent},
   42    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   43    yarn::YarnPathStore,
   44};
   45use anyhow::{Context as _, Result, anyhow};
   46use async_trait::async_trait;
   47use client::{TypedEnvelope, proto};
   48use clock::Global;
   49use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   50use futures::{
   51    AsyncWriteExt, Future, FutureExt, StreamExt,
   52    future::{Either, Shared, join_all, pending, select},
   53    select, select_biased,
   54    stream::FuturesUnordered,
   55};
   56use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   57use gpui::{
   58    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString,
   59    Subscription, Task, WeakEntity,
   60};
   61use http_client::HttpClient;
   62use itertools::Itertools as _;
   63use language::{
   64    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, Capability, CodeLabel,
   65    Diagnostic, DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language,
   66    LanguageName, LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller,
   67    ManifestDelegate, ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16,
   68    Toolchain, Transaction, Unclipped,
   69    language_settings::{FormatOnSave, Formatter, LanguageSettings, language_settings},
   70    point_to_lsp,
   71    proto::{
   72        deserialize_anchor, deserialize_anchor_range, deserialize_lsp_edit, deserialize_version,
   73        serialize_anchor, serialize_anchor_range, serialize_lsp_edit, serialize_version,
   74    },
   75    range_from_lsp, range_to_lsp,
   76    row_chunk::RowChunk,
   77};
   78use lsp::{
   79    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   80    DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   81    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   82    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LSP_REQUEST_TIMEOUT,
   83    LanguageServer, LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId,
   84    LanguageServerName, LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType,
   85    OneOf, RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri,
   86    WillRenameFiles, WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   87};
   88use node_runtime::read_package_installed_version;
   89use parking_lot::Mutex;
   90use postage::{mpsc, sink::Sink, stream::Stream, watch};
   91use rand::prelude::*;
   92use rpc::{
   93    AnyProtoClient, ErrorCode, ErrorExt as _,
   94    proto::{LspRequestId, LspRequestMessage as _},
   95};
   96use semver::Version;
   97use serde::Serialize;
   98use serde_json::Value;
   99use settings::{Settings, SettingsLocation, SettingsStore};
  100use sha2::{Digest, Sha256};
  101use snippet::Snippet;
  102use std::{
  103    any::TypeId,
  104    borrow::Cow,
  105    cell::RefCell,
  106    cmp::{Ordering, Reverse},
  107    collections::{VecDeque, hash_map},
  108    convert::TryInto,
  109    ffi::OsStr,
  110    future::ready,
  111    iter, mem,
  112    ops::{ControlFlow, Range},
  113    path::{self, Path, PathBuf},
  114    pin::pin,
  115    rc::Rc,
  116    sync::{
  117        Arc,
  118        atomic::{self, AtomicUsize},
  119    },
  120    time::{Duration, Instant},
  121    vec,
  122};
  123use sum_tree::Dimensions;
  124use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, ToPoint as _};
  125
  126use util::{
  127    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  128    paths::{PathStyle, SanitizedPath, UrlExt},
  129    post_inc,
  130    redact::redact_command,
  131    rel_path::RelPath,
  132};
  133
  134pub use fs::*;
  135pub use language::Location;
  136pub use lsp_store::inlay_hint_cache::{CacheInlayHints, InvalidationStrategy};
  137#[cfg(any(test, feature = "test-support"))]
  138pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  139pub use worktree::{
  140    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  141    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  142};
  143
  144const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  145pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  146const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  147const SERVER_DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(10);
  148static NEXT_PROMPT_REQUEST_ID: AtomicUsize = AtomicUsize::new(0);
  149
  150#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  151pub enum ProgressToken {
  152    Number(i32),
  153    String(SharedString),
  154}
  155
  156impl std::fmt::Display for ProgressToken {
  157    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  158        match self {
  159            Self::Number(number) => write!(f, "{number}"),
  160            Self::String(string) => write!(f, "{string}"),
  161        }
  162    }
  163}
  164
  165impl ProgressToken {
  166    fn from_lsp(value: lsp::NumberOrString) -> Self {
  167        match value {
  168            lsp::NumberOrString::Number(number) => Self::Number(number),
  169            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  170        }
  171    }
  172
  173    fn to_lsp(&self) -> lsp::NumberOrString {
  174        match self {
  175            Self::Number(number) => lsp::NumberOrString::Number(*number),
  176            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  177        }
  178    }
  179
  180    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  181        Some(match value.value? {
  182            proto::progress_token::Value::Number(number) => Self::Number(number),
  183            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  184        })
  185    }
  186
  187    fn to_proto(&self) -> proto::ProgressToken {
  188        proto::ProgressToken {
  189            value: Some(match self {
  190                Self::Number(number) => proto::progress_token::Value::Number(*number),
  191                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  192            }),
  193        }
  194    }
  195}
  196
  197#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  198pub enum FormatTrigger {
  199    Save,
  200    Manual,
  201}
  202
  203pub enum LspFormatTarget {
  204    Buffers,
  205    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  206}
  207
  208#[derive(Clone, PartialEq, Eq, Hash)]
  209pub struct OpenLspBufferHandle(Entity<OpenLspBuffer>);
  210
  211struct OpenLspBuffer(Entity<Buffer>);
  212
  213impl FormatTrigger {
  214    fn from_proto(value: i32) -> FormatTrigger {
  215        match value {
  216            0 => FormatTrigger::Save,
  217            1 => FormatTrigger::Manual,
  218            _ => FormatTrigger::Save,
  219        }
  220    }
  221}
  222
  223#[derive(Clone)]
  224struct UnifiedLanguageServer {
  225    id: LanguageServerId,
  226    project_roots: HashSet<Arc<RelPath>>,
  227}
  228
  229#[derive(Clone, Debug, Hash, PartialEq, Eq)]
  230struct LanguageServerSeed {
  231    worktree_id: WorktreeId,
  232    name: LanguageServerName,
  233    toolchain: Option<Toolchain>,
  234    settings: Arc<LspSettings>,
  235}
  236
  237#[derive(Debug)]
  238pub struct DocumentDiagnosticsUpdate<'a, D> {
  239    pub diagnostics: D,
  240    pub result_id: Option<SharedString>,
  241    pub registration_id: Option<SharedString>,
  242    pub server_id: LanguageServerId,
  243    pub disk_based_sources: Cow<'a, [String]>,
  244}
  245
  246pub struct DocumentDiagnostics {
  247    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  248    document_abs_path: PathBuf,
  249    version: Option<i32>,
  250}
  251
  252#[derive(Default, Debug)]
  253struct DynamicRegistrations {
  254    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  255    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  256}
  257
  258pub struct LocalLspStore {
  259    weak: WeakEntity<LspStore>,
  260    pub worktree_store: Entity<WorktreeStore>,
  261    toolchain_store: Entity<LocalToolchainStore>,
  262    http_client: Arc<dyn HttpClient>,
  263    environment: Entity<ProjectEnvironment>,
  264    fs: Arc<dyn Fs>,
  265    languages: Arc<LanguageRegistry>,
  266    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  267    yarn: Entity<YarnPathStore>,
  268    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  269    buffers_being_formatted: HashSet<BufferId>,
  270    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  271    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  272    watched_manifest_filenames: HashSet<ManifestName>,
  273    language_server_paths_watched_for_rename:
  274        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  275    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  276    supplementary_language_servers:
  277        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  278    prettier_store: Entity<PrettierStore>,
  279    next_diagnostic_group_id: usize,
  280    diagnostics: HashMap<
  281        WorktreeId,
  282        HashMap<
  283            Arc<RelPath>,
  284            Vec<(
  285                LanguageServerId,
  286                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  287            )>,
  288        >,
  289    >,
  290    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  291    _subscription: gpui::Subscription,
  292    lsp_tree: LanguageServerTree,
  293    registered_buffers: HashMap<BufferId, usize>,
  294    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  295    buffer_pull_diagnostics_result_ids: HashMap<
  296        LanguageServerId,
  297        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  298    >,
  299    workspace_pull_diagnostics_result_ids: HashMap<
  300        LanguageServerId,
  301        HashMap<Option<SharedString>, HashMap<PathBuf, Option<SharedString>>>,
  302    >,
  303    restricted_worktrees_tasks: HashMap<WorktreeId, (Subscription, watch::Receiver<bool>)>,
  304
  305    buffers_to_refresh_hash_set: HashSet<BufferId>,
  306    buffers_to_refresh_queue: VecDeque<BufferId>,
  307    _background_diagnostics_worker: Shared<Task<()>>,
  308}
  309
  310impl LocalLspStore {
  311    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  312    pub fn running_language_server_for_id(
  313        &self,
  314        id: LanguageServerId,
  315    ) -> Option<&Arc<LanguageServer>> {
  316        let language_server_state = self.language_servers.get(&id)?;
  317
  318        match language_server_state {
  319            LanguageServerState::Running { server, .. } => Some(server),
  320            LanguageServerState::Starting { .. } => None,
  321        }
  322    }
  323
  324    fn get_or_insert_language_server(
  325        &mut self,
  326        worktree_handle: &Entity<Worktree>,
  327        delegate: Arc<LocalLspAdapterDelegate>,
  328        disposition: &Arc<LaunchDisposition>,
  329        language_name: &LanguageName,
  330        cx: &mut App,
  331    ) -> LanguageServerId {
  332        let key = LanguageServerSeed {
  333            worktree_id: worktree_handle.read(cx).id(),
  334            name: disposition.server_name.clone(),
  335            settings: disposition.settings.clone(),
  336            toolchain: disposition.toolchain.clone(),
  337        };
  338        if let Some(state) = self.language_server_ids.get_mut(&key) {
  339            state.project_roots.insert(disposition.path.path.clone());
  340            state.id
  341        } else {
  342            let adapter = self
  343                .languages
  344                .lsp_adapters(language_name)
  345                .into_iter()
  346                .find(|adapter| adapter.name() == disposition.server_name)
  347                .expect("To find LSP adapter");
  348            let new_language_server_id = self.start_language_server(
  349                worktree_handle,
  350                delegate,
  351                adapter,
  352                disposition.settings.clone(),
  353                key.clone(),
  354                cx,
  355            );
  356            if let Some(state) = self.language_server_ids.get_mut(&key) {
  357                state.project_roots.insert(disposition.path.path.clone());
  358            } else {
  359                debug_assert!(
  360                    false,
  361                    "Expected `start_language_server` to ensure that `key` exists in a map"
  362                );
  363            }
  364            new_language_server_id
  365        }
  366    }
  367
  368    fn start_language_server(
  369        &mut self,
  370        worktree_handle: &Entity<Worktree>,
  371        delegate: Arc<LocalLspAdapterDelegate>,
  372        adapter: Arc<CachedLspAdapter>,
  373        settings: Arc<LspSettings>,
  374        key: LanguageServerSeed,
  375        cx: &mut App,
  376    ) -> LanguageServerId {
  377        let worktree = worktree_handle.read(cx);
  378
  379        let worktree_id = worktree.id();
  380        let worktree_abs_path = worktree.abs_path();
  381        let toolchain = key.toolchain.clone();
  382        let override_options = settings.initialization_options.clone();
  383
  384        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  385
  386        let server_id = self.languages.next_language_server_id();
  387        log::trace!(
  388            "attempting to start language server {:?}, path: {worktree_abs_path:?}, id: {server_id}",
  389            adapter.name.0
  390        );
  391
  392        let wait_until_worktree_trust =
  393            TrustedWorktrees::try_get_global(cx).and_then(|trusted_worktrees| {
  394                let can_trust = trusted_worktrees.update(cx, |trusted_worktrees, cx| {
  395                    trusted_worktrees.can_trust(&self.worktree_store, worktree_id, cx)
  396                });
  397                if can_trust {
  398                    self.restricted_worktrees_tasks.remove(&worktree_id);
  399                    None
  400                } else {
  401                    match self.restricted_worktrees_tasks.entry(worktree_id) {
  402                        hash_map::Entry::Occupied(o) => Some(o.get().1.clone()),
  403                        hash_map::Entry::Vacant(v) => {
  404                            let (mut tx, rx) = watch::channel::<bool>();
  405                            let lsp_store = self.weak.clone();
  406                            let subscription = cx.subscribe(&trusted_worktrees, move |_, e, cx| {
  407                                if let TrustedWorktreesEvent::Trusted(_, trusted_paths) = e {
  408                                    if trusted_paths.contains(&PathTrust::Worktree(worktree_id)) {
  409                                        tx.blocking_send(true).ok();
  410                                        lsp_store
  411                                            .update(cx, |lsp_store, _| {
  412                                                if let Some(local_lsp_store) =
  413                                                    lsp_store.as_local_mut()
  414                                                {
  415                                                    local_lsp_store
  416                                                        .restricted_worktrees_tasks
  417                                                        .remove(&worktree_id);
  418                                                }
  419                                            })
  420                                            .ok();
  421                                    }
  422                                }
  423                            });
  424                            v.insert((subscription, rx.clone()));
  425                            Some(rx)
  426                        }
  427                    }
  428                }
  429            });
  430        let update_binary_status = wait_until_worktree_trust.is_none();
  431
  432        let binary = self.get_language_server_binary(
  433            worktree_abs_path.clone(),
  434            adapter.clone(),
  435            settings,
  436            toolchain.clone(),
  437            delegate.clone(),
  438            true,
  439            wait_until_worktree_trust,
  440            cx,
  441        );
  442        let pending_workspace_folders = Arc::<Mutex<BTreeSet<Uri>>>::default();
  443
  444        let pending_server = cx.spawn({
  445            let adapter = adapter.clone();
  446            let server_name = adapter.name.clone();
  447            let stderr_capture = stderr_capture.clone();
  448            #[cfg(any(test, feature = "test-support"))]
  449            let lsp_store = self.weak.clone();
  450            let pending_workspace_folders = pending_workspace_folders.clone();
  451            async move |cx| {
  452                let binary = binary.await?;
  453                #[cfg(any(test, feature = "test-support"))]
  454                if let Some(server) = lsp_store
  455                    .update(&mut cx.clone(), |this, cx| {
  456                        this.languages.create_fake_language_server(
  457                            server_id,
  458                            &server_name,
  459                            binary.clone(),
  460                            &mut cx.to_async(),
  461                        )
  462                    })
  463                    .ok()
  464                    .flatten()
  465                {
  466                    return Ok(server);
  467                }
  468
  469                let code_action_kinds = adapter.code_action_kinds();
  470                lsp::LanguageServer::new(
  471                    stderr_capture,
  472                    server_id,
  473                    server_name,
  474                    binary,
  475                    &worktree_abs_path,
  476                    code_action_kinds,
  477                    Some(pending_workspace_folders),
  478                    cx,
  479                )
  480            }
  481        });
  482
  483        let startup = {
  484            let server_name = adapter.name.0.clone();
  485            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  486            let key = key.clone();
  487            let adapter = adapter.clone();
  488            let lsp_store = self.weak.clone();
  489            let pending_workspace_folders = pending_workspace_folders.clone();
  490
  491            let pull_diagnostics = ProjectSettings::get_global(cx)
  492                .diagnostics
  493                .lsp_pull_diagnostics
  494                .enabled;
  495            cx.spawn(async move |cx| {
  496                let result = async {
  497                    let language_server = pending_server.await?;
  498
  499                    let workspace_config = Self::workspace_configuration_for_adapter(
  500                        adapter.adapter.clone(),
  501                        &delegate,
  502                        toolchain,
  503                        None,
  504                        cx,
  505                    )
  506                    .await?;
  507
  508                    let mut initialization_options = Self::initialization_options_for_adapter(
  509                        adapter.adapter.clone(),
  510                        &delegate,
  511                    )
  512                    .await?;
  513
  514                    match (&mut initialization_options, override_options) {
  515                        (Some(initialization_options), Some(override_options)) => {
  516                            merge_json_value_into(override_options, initialization_options);
  517                        }
  518                        (None, override_options) => initialization_options = override_options,
  519                        _ => {}
  520                    }
  521
  522                    let initialization_params = cx.update(|cx| {
  523                        let mut params =
  524                            language_server.default_initialize_params(pull_diagnostics, cx);
  525                        params.initialization_options = initialization_options;
  526                        adapter.adapter.prepare_initialize_params(params, cx)
  527                    })?;
  528
  529                    Self::setup_lsp_messages(
  530                        lsp_store.clone(),
  531                        &language_server,
  532                        delegate.clone(),
  533                        adapter.clone(),
  534                    );
  535
  536                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  537                        settings: workspace_config,
  538                    };
  539                    let language_server = cx
  540                        .update(|cx| {
  541                            language_server.initialize(
  542                                initialization_params,
  543                                Arc::new(did_change_configuration_params.clone()),
  544                                cx,
  545                            )
  546                        })
  547                        .await
  548                        .inspect_err(|_| {
  549                            if let Some(lsp_store) = lsp_store.upgrade() {
  550                                lsp_store.update(cx, |lsp_store, cx| {
  551                                    lsp_store.cleanup_lsp_data(server_id);
  552                                    cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  553                                });
  554                            }
  555                        })?;
  556
  557                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  558                        did_change_configuration_params,
  559                    )?;
  560
  561                    anyhow::Ok(language_server)
  562                }
  563                .await;
  564
  565                match result {
  566                    Ok(server) => {
  567                        lsp_store
  568                            .update(cx, |lsp_store, cx| {
  569                                lsp_store.insert_newly_running_language_server(
  570                                    adapter,
  571                                    server.clone(),
  572                                    server_id,
  573                                    key,
  574                                    pending_workspace_folders,
  575                                    cx,
  576                                );
  577                            })
  578                            .ok();
  579                        stderr_capture.lock().take();
  580                        Some(server)
  581                    }
  582
  583                    Err(err) => {
  584                        let log = stderr_capture.lock().take().unwrap_or_default();
  585                        delegate.update_status(
  586                            adapter.name(),
  587                            BinaryStatus::Failed {
  588                                error: if log.is_empty() {
  589                                    format!("{err:#}")
  590                                } else {
  591                                    format!("{err:#}\n-- stderr --\n{log}")
  592                                },
  593                            },
  594                        );
  595                        log::error!(
  596                            "Failed to start language server {server_name:?}: {}",
  597                            redact_command(&format!("{err:?}"))
  598                        );
  599                        if !log.is_empty() {
  600                            log::error!("server stderr: {}", redact_command(&log));
  601                        }
  602                        None
  603                    }
  604                }
  605            })
  606        };
  607        let state = LanguageServerState::Starting {
  608            startup,
  609            pending_workspace_folders,
  610        };
  611
  612        if update_binary_status {
  613            self.languages
  614                .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  615        }
  616
  617        self.language_servers.insert(server_id, state);
  618        self.language_server_ids
  619            .entry(key)
  620            .or_insert(UnifiedLanguageServer {
  621                id: server_id,
  622                project_roots: Default::default(),
  623            });
  624        server_id
  625    }
  626
  627    fn get_language_server_binary(
  628        &self,
  629        worktree_abs_path: Arc<Path>,
  630        adapter: Arc<CachedLspAdapter>,
  631        settings: Arc<LspSettings>,
  632        toolchain: Option<Toolchain>,
  633        delegate: Arc<dyn LspAdapterDelegate>,
  634        allow_binary_download: bool,
  635        wait_until_worktree_trust: Option<watch::Receiver<bool>>,
  636        cx: &mut App,
  637    ) -> Task<Result<LanguageServerBinary>> {
  638        if let Some(settings) = &settings.binary
  639            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  640        {
  641            let settings = settings.clone();
  642            let languages = self.languages.clone();
  643            return cx.background_spawn(async move {
  644                if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  645                    let already_trusted =  *wait_until_worktree_trust.borrow();
  646                    if !already_trusted {
  647                        log::info!(
  648                            "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  649                            adapter.name(),
  650                        );
  651                        while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  652                            if worktree_trusted {
  653                                break;
  654                            }
  655                        }
  656                        log::info!(
  657                            "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  658                            adapter.name(),
  659                        );
  660                    }
  661                    languages
  662                        .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  663                }
  664                let mut env = delegate.shell_env().await;
  665                env.extend(settings.env.unwrap_or_default());
  666
  667                Ok(LanguageServerBinary {
  668                    path: delegate.resolve_executable_path(path),
  669                    env: Some(env),
  670                    arguments: settings
  671                        .arguments
  672                        .unwrap_or_default()
  673                        .iter()
  674                        .map(Into::into)
  675                        .collect(),
  676                })
  677            });
  678        }
  679        let lsp_binary_options = LanguageServerBinaryOptions {
  680            allow_path_lookup: !settings
  681                .binary
  682                .as_ref()
  683                .and_then(|b| b.ignore_system_version)
  684                .unwrap_or_default(),
  685            allow_binary_download,
  686            pre_release: settings
  687                .fetch
  688                .as_ref()
  689                .and_then(|f| f.pre_release)
  690                .unwrap_or(false),
  691        };
  692
  693        cx.spawn(async move |cx| {
  694            if let Some(mut wait_until_worktree_trust) = wait_until_worktree_trust {
  695                let already_trusted =  *wait_until_worktree_trust.borrow();
  696                if !already_trusted {
  697                    log::info!(
  698                        "Waiting for worktree {worktree_abs_path:?} to be trusted, before starting language server {}",
  699                        adapter.name(),
  700                    );
  701                    while let Some(worktree_trusted) = wait_until_worktree_trust.recv().await {
  702                        if worktree_trusted {
  703                            break;
  704                        }
  705                    }
  706                    log::info!(
  707                        "Worktree {worktree_abs_path:?} is trusted, starting language server {}",
  708                            adapter.name(),
  709                    );
  710                }
  711            }
  712
  713            let (existing_binary, maybe_download_binary) = adapter
  714                .clone()
  715                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  716                .await
  717                .await;
  718
  719            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  720
  721            let mut binary = match (existing_binary, maybe_download_binary) {
  722                (binary, None) => binary?,
  723                (Err(_), Some(downloader)) => downloader.await?,
  724                (Ok(existing_binary), Some(downloader)) => {
  725                    let mut download_timeout = cx
  726                        .background_executor()
  727                        .timer(SERVER_DOWNLOAD_TIMEOUT)
  728                        .fuse();
  729                    let mut downloader = downloader.fuse();
  730                    futures::select! {
  731                        _ = download_timeout => {
  732                            // Return existing binary and kick the existing work to the background.
  733                            cx.spawn(async move |_| downloader.await).detach();
  734                            Ok(existing_binary)
  735                        },
  736                        downloaded_or_existing_binary = downloader => {
  737                            // If download fails, this results in the existing binary.
  738                            downloaded_or_existing_binary
  739                        }
  740                    }?
  741                }
  742            };
  743            let mut shell_env = delegate.shell_env().await;
  744
  745            shell_env.extend(binary.env.unwrap_or_default());
  746
  747            if let Some(settings) = settings.binary.as_ref() {
  748                if let Some(arguments) = &settings.arguments {
  749                    binary.arguments = arguments.iter().map(Into::into).collect();
  750                }
  751                if let Some(env) = &settings.env {
  752                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  753                }
  754            }
  755
  756            binary.env = Some(shell_env);
  757            Ok(binary)
  758        })
  759    }
  760
  761    fn setup_lsp_messages(
  762        lsp_store: WeakEntity<LspStore>,
  763        language_server: &LanguageServer,
  764        delegate: Arc<dyn LspAdapterDelegate>,
  765        adapter: Arc<CachedLspAdapter>,
  766    ) {
  767        let name = language_server.name();
  768        let server_id = language_server.server_id();
  769        language_server
  770            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  771                let adapter = adapter.clone();
  772                let this = lsp_store.clone();
  773                move |mut params, cx| {
  774                    let adapter = adapter.clone();
  775                    if let Some(this) = this.upgrade() {
  776                        this.update(cx, |this, cx| {
  777                            {
  778                                let buffer = params
  779                                    .uri
  780                                    .to_file_path()
  781                                    .map(|file_path| this.get_buffer(&file_path, cx))
  782                                    .ok()
  783                                    .flatten();
  784                                adapter.process_diagnostics(&mut params, server_id, buffer);
  785                            }
  786
  787                            this.merge_lsp_diagnostics(
  788                                DiagnosticSourceKind::Pushed,
  789                                vec![DocumentDiagnosticsUpdate {
  790                                    server_id,
  791                                    diagnostics: params,
  792                                    result_id: None,
  793                                    disk_based_sources: Cow::Borrowed(
  794                                        &adapter.disk_based_diagnostic_sources,
  795                                    ),
  796                                    registration_id: None,
  797                                }],
  798                                |_, diagnostic, cx| match diagnostic.source_kind {
  799                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  800                                        adapter.retain_old_diagnostic(diagnostic, cx)
  801                                    }
  802                                    DiagnosticSourceKind::Pulled => true,
  803                                },
  804                                cx,
  805                            )
  806                            .log_err();
  807                        });
  808                    }
  809                }
  810            })
  811            .detach();
  812        language_server
  813            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  814                let adapter = adapter.adapter.clone();
  815                let delegate = delegate.clone();
  816                let this = lsp_store.clone();
  817                move |params, cx| {
  818                    let adapter = adapter.clone();
  819                    let delegate = delegate.clone();
  820                    let this = this.clone();
  821                    let mut cx = cx.clone();
  822                    async move {
  823                        let toolchain_for_id = this
  824                            .update(&mut cx, |this, _| {
  825                                this.as_local()?.language_server_ids.iter().find_map(
  826                                    |(seed, value)| {
  827                                        (value.id == server_id).then(|| seed.toolchain.clone())
  828                                    },
  829                                )
  830                            })?
  831                            .context("Expected the LSP store to be in a local mode")?;
  832
  833                        let mut scope_uri_to_workspace_config = BTreeMap::new();
  834                        for item in &params.items {
  835                            let scope_uri = item.scope_uri.clone();
  836                            let std::collections::btree_map::Entry::Vacant(new_scope_uri) =
  837                                scope_uri_to_workspace_config.entry(scope_uri.clone())
  838                            else {
  839                                // We've already queried workspace configuration of this URI.
  840                                continue;
  841                            };
  842                            let workspace_config = Self::workspace_configuration_for_adapter(
  843                                adapter.clone(),
  844                                &delegate,
  845                                toolchain_for_id.clone(),
  846                                scope_uri,
  847                                &mut cx,
  848                            )
  849                            .await?;
  850                            new_scope_uri.insert(workspace_config);
  851                        }
  852
  853                        Ok(params
  854                            .items
  855                            .into_iter()
  856                            .filter_map(|item| {
  857                                let workspace_config =
  858                                    scope_uri_to_workspace_config.get(&item.scope_uri)?;
  859                                if let Some(section) = &item.section {
  860                                    Some(
  861                                        workspace_config
  862                                            .get(section)
  863                                            .cloned()
  864                                            .unwrap_or(serde_json::Value::Null),
  865                                    )
  866                                } else {
  867                                    Some(workspace_config.clone())
  868                                }
  869                            })
  870                            .collect())
  871                    }
  872                }
  873            })
  874            .detach();
  875
  876        language_server
  877            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  878                let this = lsp_store.clone();
  879                move |_, cx| {
  880                    let this = this.clone();
  881                    let cx = cx.clone();
  882                    async move {
  883                        let Some(server) =
  884                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  885                        else {
  886                            return Ok(None);
  887                        };
  888                        let root = server.workspace_folders();
  889                        Ok(Some(
  890                            root.into_iter()
  891                                .map(|uri| WorkspaceFolder {
  892                                    uri,
  893                                    name: Default::default(),
  894                                })
  895                                .collect(),
  896                        ))
  897                    }
  898                }
  899            })
  900            .detach();
  901        // Even though we don't have handling for these requests, respond to them to
  902        // avoid stalling any language server like `gopls` which waits for a response
  903        // to these requests when initializing.
  904        language_server
  905            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  906                let this = lsp_store.clone();
  907                move |params, cx| {
  908                    let this = this.clone();
  909                    let mut cx = cx.clone();
  910                    async move {
  911                        this.update(&mut cx, |this, _| {
  912                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  913                            {
  914                                status
  915                                    .progress_tokens
  916                                    .insert(ProgressToken::from_lsp(params.token));
  917                            }
  918                        })?;
  919
  920                        Ok(())
  921                    }
  922                }
  923            })
  924            .detach();
  925
  926        language_server
  927            .on_request::<lsp::request::RegisterCapability, _, _>({
  928                let lsp_store = lsp_store.clone();
  929                move |params, cx| {
  930                    let lsp_store = lsp_store.clone();
  931                    let mut cx = cx.clone();
  932                    async move {
  933                        lsp_store
  934                            .update(&mut cx, |lsp_store, cx| {
  935                                if lsp_store.as_local().is_some() {
  936                                    match lsp_store
  937                                        .register_server_capabilities(server_id, params, cx)
  938                                    {
  939                                        Ok(()) => {}
  940                                        Err(e) => {
  941                                            log::error!(
  942                                                "Failed to register server capabilities: {e:#}"
  943                                            );
  944                                        }
  945                                    };
  946                                }
  947                            })
  948                            .ok();
  949                        Ok(())
  950                    }
  951                }
  952            })
  953            .detach();
  954
  955        language_server
  956            .on_request::<lsp::request::UnregisterCapability, _, _>({
  957                let lsp_store = lsp_store.clone();
  958                move |params, cx| {
  959                    let lsp_store = lsp_store.clone();
  960                    let mut cx = cx.clone();
  961                    async move {
  962                        lsp_store
  963                            .update(&mut cx, |lsp_store, cx| {
  964                                if lsp_store.as_local().is_some() {
  965                                    match lsp_store
  966                                        .unregister_server_capabilities(server_id, params, cx)
  967                                    {
  968                                        Ok(()) => {}
  969                                        Err(e) => {
  970                                            log::error!(
  971                                                "Failed to unregister server capabilities: {e:#}"
  972                                            );
  973                                        }
  974                                    }
  975                                }
  976                            })
  977                            .ok();
  978                        Ok(())
  979                    }
  980                }
  981            })
  982            .detach();
  983
  984        language_server
  985            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  986                let this = lsp_store.clone();
  987                move |params, cx| {
  988                    let mut cx = cx.clone();
  989                    let this = this.clone();
  990                    async move {
  991                        LocalLspStore::on_lsp_workspace_edit(
  992                            this.clone(),
  993                            params,
  994                            server_id,
  995                            &mut cx,
  996                        )
  997                        .await
  998                    }
  999                }
 1000            })
 1001            .detach();
 1002
 1003        language_server
 1004            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
 1005                let lsp_store = lsp_store.clone();
 1006                let request_id = Arc::new(AtomicUsize::new(0));
 1007                move |(), cx| {
 1008                    let lsp_store = lsp_store.clone();
 1009                    let request_id = request_id.clone();
 1010                    let mut cx = cx.clone();
 1011                    async move {
 1012                        lsp_store
 1013                            .update(&mut cx, |lsp_store, cx| {
 1014                                let request_id =
 1015                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
 1016                                cx.emit(LspStoreEvent::RefreshInlayHints {
 1017                                    server_id,
 1018                                    request_id,
 1019                                });
 1020                                lsp_store
 1021                                    .downstream_client
 1022                                    .as_ref()
 1023                                    .map(|(client, project_id)| {
 1024                                        client.send(proto::RefreshInlayHints {
 1025                                            project_id: *project_id,
 1026                                            server_id: server_id.to_proto(),
 1027                                            request_id: request_id.map(|id| id as u64),
 1028                                        })
 1029                                    })
 1030                            })?
 1031                            .transpose()?;
 1032                        Ok(())
 1033                    }
 1034                }
 1035            })
 1036            .detach();
 1037
 1038        language_server
 1039            .on_request::<lsp::request::CodeLensRefresh, _, _>({
 1040                let this = lsp_store.clone();
 1041                move |(), cx| {
 1042                    let this = this.clone();
 1043                    let mut cx = cx.clone();
 1044                    async move {
 1045                        this.update(&mut cx, |this, cx| {
 1046                            cx.emit(LspStoreEvent::RefreshCodeLens);
 1047                            this.downstream_client.as_ref().map(|(client, project_id)| {
 1048                                client.send(proto::RefreshCodeLens {
 1049                                    project_id: *project_id,
 1050                                })
 1051                            })
 1052                        })?
 1053                        .transpose()?;
 1054                        Ok(())
 1055                    }
 1056                }
 1057            })
 1058            .detach();
 1059
 1060        language_server
 1061            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
 1062                let this = lsp_store.clone();
 1063                move |(), cx| {
 1064                    let this = this.clone();
 1065                    let mut cx = cx.clone();
 1066                    async move {
 1067                        this.update(&mut cx, |lsp_store, cx| {
 1068                            lsp_store.pull_workspace_diagnostics(server_id);
 1069                            lsp_store
 1070                                .downstream_client
 1071                                .as_ref()
 1072                                .map(|(client, project_id)| {
 1073                                    client.send(proto::PullWorkspaceDiagnostics {
 1074                                        project_id: *project_id,
 1075                                        server_id: server_id.to_proto(),
 1076                                    })
 1077                                })
 1078                                .transpose()?;
 1079                            anyhow::Ok(
 1080                                lsp_store.pull_document_diagnostics_for_server(server_id, None, cx),
 1081                            )
 1082                        })??
 1083                        .await;
 1084                        Ok(())
 1085                    }
 1086                }
 1087            })
 1088            .detach();
 1089
 1090        language_server
 1091            .on_request::<lsp::request::ShowMessageRequest, _, _>({
 1092                let this = lsp_store.clone();
 1093                let name = name.to_string();
 1094                let adapter = adapter.clone();
 1095                move |params, cx| {
 1096                    let this = this.clone();
 1097                    let name = name.to_string();
 1098                    let adapter = adapter.clone();
 1099                    let mut cx = cx.clone();
 1100                    async move {
 1101                        let actions = params.actions.unwrap_or_default();
 1102                        let message = params.message.clone();
 1103                        let (tx, rx) = smol::channel::bounded::<MessageActionItem>(1);
 1104                        let level = match params.typ {
 1105                            lsp::MessageType::ERROR => PromptLevel::Critical,
 1106                            lsp::MessageType::WARNING => PromptLevel::Warning,
 1107                            _ => PromptLevel::Info,
 1108                        };
 1109                        let request = LanguageServerPromptRequest::new(
 1110                            level,
 1111                            params.message,
 1112                            actions,
 1113                            name.clone(),
 1114                            tx,
 1115                        );
 1116
 1117                        let did_update = this
 1118                            .update(&mut cx, |_, cx| {
 1119                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1120                            })
 1121                            .is_ok();
 1122                        if did_update {
 1123                            let response = rx.recv().await.ok();
 1124                            if let Some(ref selected_action) = response {
 1125                                let context = language::PromptResponseContext {
 1126                                    message,
 1127                                    selected_action: selected_action.clone(),
 1128                                };
 1129                                adapter.process_prompt_response(&context, &mut cx)
 1130                            }
 1131
 1132                            Ok(response)
 1133                        } else {
 1134                            Ok(None)
 1135                        }
 1136                    }
 1137                }
 1138            })
 1139            .detach();
 1140        language_server
 1141            .on_notification::<lsp::notification::ShowMessage, _>({
 1142                let this = lsp_store.clone();
 1143                let name = name.to_string();
 1144                move |params, cx| {
 1145                    let this = this.clone();
 1146                    let name = name.to_string();
 1147                    let mut cx = cx.clone();
 1148
 1149                    let (tx, _) = smol::channel::bounded(1);
 1150                    let level = match params.typ {
 1151                        lsp::MessageType::ERROR => PromptLevel::Critical,
 1152                        lsp::MessageType::WARNING => PromptLevel::Warning,
 1153                        _ => PromptLevel::Info,
 1154                    };
 1155                    let request =
 1156                        LanguageServerPromptRequest::new(level, params.message, vec![], name, tx);
 1157
 1158                    let _ = this.update(&mut cx, |_, cx| {
 1159                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
 1160                    });
 1161                }
 1162            })
 1163            .detach();
 1164
 1165        let disk_based_diagnostics_progress_token =
 1166            adapter.disk_based_diagnostics_progress_token.clone();
 1167
 1168        language_server
 1169            .on_notification::<lsp::notification::Progress, _>({
 1170                let this = lsp_store.clone();
 1171                move |params, cx| {
 1172                    if let Some(this) = this.upgrade() {
 1173                        this.update(cx, |this, cx| {
 1174                            this.on_lsp_progress(
 1175                                params,
 1176                                server_id,
 1177                                disk_based_diagnostics_progress_token.clone(),
 1178                                cx,
 1179                            );
 1180                        });
 1181                    }
 1182                }
 1183            })
 1184            .detach();
 1185
 1186        language_server
 1187            .on_notification::<lsp::notification::LogMessage, _>({
 1188                let this = lsp_store.clone();
 1189                move |params, cx| {
 1190                    if let Some(this) = this.upgrade() {
 1191                        this.update(cx, |_, cx| {
 1192                            cx.emit(LspStoreEvent::LanguageServerLog(
 1193                                server_id,
 1194                                LanguageServerLogType::Log(params.typ),
 1195                                params.message,
 1196                            ));
 1197                        });
 1198                    }
 1199                }
 1200            })
 1201            .detach();
 1202
 1203        language_server
 1204            .on_notification::<lsp::notification::LogTrace, _>({
 1205                let this = lsp_store.clone();
 1206                move |params, cx| {
 1207                    let mut cx = cx.clone();
 1208                    if let Some(this) = this.upgrade() {
 1209                        this.update(&mut cx, |_, cx| {
 1210                            cx.emit(LspStoreEvent::LanguageServerLog(
 1211                                server_id,
 1212                                LanguageServerLogType::Trace {
 1213                                    verbose_info: params.verbose,
 1214                                },
 1215                                params.message,
 1216                            ));
 1217                        });
 1218                    }
 1219                }
 1220            })
 1221            .detach();
 1222
 1223        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1224        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1225        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1226        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1227    }
 1228
 1229    fn shutdown_language_servers_on_quit(
 1230        &mut self,
 1231        _: &mut Context<LspStore>,
 1232    ) -> impl Future<Output = ()> + use<> {
 1233        let shutdown_futures = self
 1234            .language_servers
 1235            .drain()
 1236            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1237            .collect::<Vec<_>>();
 1238
 1239        async move {
 1240            join_all(shutdown_futures).await;
 1241        }
 1242    }
 1243
 1244    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1245        match server_state {
 1246            LanguageServerState::Running { server, .. } => {
 1247                if let Some(shutdown) = server.shutdown() {
 1248                    shutdown.await;
 1249                }
 1250            }
 1251            LanguageServerState::Starting { startup, .. } => {
 1252                if let Some(server) = startup.await
 1253                    && let Some(shutdown) = server.shutdown()
 1254                {
 1255                    shutdown.await;
 1256                }
 1257            }
 1258        }
 1259        Ok(())
 1260    }
 1261
 1262    fn language_servers_for_worktree(
 1263        &self,
 1264        worktree_id: WorktreeId,
 1265    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1266        self.language_server_ids
 1267            .iter()
 1268            .filter_map(move |(seed, state)| {
 1269                if seed.worktree_id != worktree_id {
 1270                    return None;
 1271                }
 1272
 1273                if let Some(LanguageServerState::Running { server, .. }) =
 1274                    self.language_servers.get(&state.id)
 1275                {
 1276                    Some(server)
 1277                } else {
 1278                    None
 1279                }
 1280            })
 1281    }
 1282
 1283    fn language_server_ids_for_project_path(
 1284        &self,
 1285        project_path: ProjectPath,
 1286        language: &Language,
 1287        cx: &mut App,
 1288    ) -> Vec<LanguageServerId> {
 1289        let Some(worktree) = self
 1290            .worktree_store
 1291            .read(cx)
 1292            .worktree_for_id(project_path.worktree_id, cx)
 1293        else {
 1294            return Vec::new();
 1295        };
 1296        let delegate: Arc<dyn ManifestDelegate> =
 1297            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1298
 1299        self.lsp_tree
 1300            .get(
 1301                project_path,
 1302                language.name(),
 1303                language.manifest(),
 1304                &delegate,
 1305                cx,
 1306            )
 1307            .collect::<Vec<_>>()
 1308    }
 1309
 1310    fn language_server_ids_for_buffer(
 1311        &self,
 1312        buffer: &Buffer,
 1313        cx: &mut App,
 1314    ) -> Vec<LanguageServerId> {
 1315        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1316            let worktree_id = file.worktree_id(cx);
 1317
 1318            let path: Arc<RelPath> = file
 1319                .path()
 1320                .parent()
 1321                .map(Arc::from)
 1322                .unwrap_or_else(|| file.path().clone());
 1323            let worktree_path = ProjectPath { worktree_id, path };
 1324            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1325        } else {
 1326            Vec::new()
 1327        }
 1328    }
 1329
 1330    fn language_servers_for_buffer<'a>(
 1331        &'a self,
 1332        buffer: &'a Buffer,
 1333        cx: &'a mut App,
 1334    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1335        self.language_server_ids_for_buffer(buffer, cx)
 1336            .into_iter()
 1337            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1338                LanguageServerState::Running {
 1339                    adapter, server, ..
 1340                } => Some((adapter, server)),
 1341                _ => None,
 1342            })
 1343    }
 1344
 1345    async fn execute_code_action_kind_locally(
 1346        lsp_store: WeakEntity<LspStore>,
 1347        mut buffers: Vec<Entity<Buffer>>,
 1348        kind: CodeActionKind,
 1349        push_to_history: bool,
 1350        cx: &mut AsyncApp,
 1351    ) -> anyhow::Result<ProjectTransaction> {
 1352        // Do not allow multiple concurrent code actions requests for the
 1353        // same buffer.
 1354        lsp_store.update(cx, |this, cx| {
 1355            let this = this.as_local_mut().unwrap();
 1356            buffers.retain(|buffer| {
 1357                this.buffers_being_formatted
 1358                    .insert(buffer.read(cx).remote_id())
 1359            });
 1360        })?;
 1361        let _cleanup = defer({
 1362            let this = lsp_store.clone();
 1363            let mut cx = cx.clone();
 1364            let buffers = &buffers;
 1365            move || {
 1366                this.update(&mut cx, |this, cx| {
 1367                    let this = this.as_local_mut().unwrap();
 1368                    for buffer in buffers {
 1369                        this.buffers_being_formatted
 1370                            .remove(&buffer.read(cx).remote_id());
 1371                    }
 1372                })
 1373                .ok();
 1374            }
 1375        });
 1376        let mut project_transaction = ProjectTransaction::default();
 1377
 1378        for buffer in &buffers {
 1379            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1380                buffer.update(cx, |buffer, cx| {
 1381                    lsp_store
 1382                        .as_local()
 1383                        .unwrap()
 1384                        .language_servers_for_buffer(buffer, cx)
 1385                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1386                        .collect::<Vec<_>>()
 1387                })
 1388            })?;
 1389            for (_, language_server) in adapters_and_servers.iter() {
 1390                let actions = Self::get_server_code_actions_from_action_kinds(
 1391                    &lsp_store,
 1392                    language_server.server_id(),
 1393                    vec![kind.clone()],
 1394                    buffer,
 1395                    cx,
 1396                )
 1397                .await?;
 1398                Self::execute_code_actions_on_server(
 1399                    &lsp_store,
 1400                    language_server,
 1401                    actions,
 1402                    push_to_history,
 1403                    &mut project_transaction,
 1404                    cx,
 1405                )
 1406                .await?;
 1407            }
 1408        }
 1409        Ok(project_transaction)
 1410    }
 1411
 1412    async fn format_locally(
 1413        lsp_store: WeakEntity<LspStore>,
 1414        mut buffers: Vec<FormattableBuffer>,
 1415        push_to_history: bool,
 1416        trigger: FormatTrigger,
 1417        logger: zlog::Logger,
 1418        cx: &mut AsyncApp,
 1419    ) -> anyhow::Result<ProjectTransaction> {
 1420        // Do not allow multiple concurrent formatting requests for the
 1421        // same buffer.
 1422        lsp_store.update(cx, |this, cx| {
 1423            let this = this.as_local_mut().unwrap();
 1424            buffers.retain(|buffer| {
 1425                this.buffers_being_formatted
 1426                    .insert(buffer.handle.read(cx).remote_id())
 1427            });
 1428        })?;
 1429
 1430        let _cleanup = defer({
 1431            let this = lsp_store.clone();
 1432            let mut cx = cx.clone();
 1433            let buffers = &buffers;
 1434            move || {
 1435                this.update(&mut cx, |this, cx| {
 1436                    let this = this.as_local_mut().unwrap();
 1437                    for buffer in buffers {
 1438                        this.buffers_being_formatted
 1439                            .remove(&buffer.handle.read(cx).remote_id());
 1440                    }
 1441                })
 1442                .ok();
 1443            }
 1444        });
 1445
 1446        let mut project_transaction = ProjectTransaction::default();
 1447
 1448        for buffer in &buffers {
 1449            zlog::debug!(
 1450                logger =>
 1451                "formatting buffer '{:?}'",
 1452                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1453            );
 1454            // Create an empty transaction to hold all of the formatting edits.
 1455            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1456                // ensure no transactions created while formatting are
 1457                // grouped with the previous transaction in the history
 1458                // based on the transaction group interval
 1459                buffer.finalize_last_transaction();
 1460                buffer
 1461                    .start_transaction()
 1462                    .context("transaction already open")?;
 1463                buffer.end_transaction(cx);
 1464                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1465                buffer.finalize_last_transaction();
 1466                anyhow::Ok(transaction_id)
 1467            })?;
 1468
 1469            let result = Self::format_buffer_locally(
 1470                lsp_store.clone(),
 1471                buffer,
 1472                formatting_transaction_id,
 1473                trigger,
 1474                logger,
 1475                cx,
 1476            )
 1477            .await;
 1478
 1479            buffer.handle.update(cx, |buffer, cx| {
 1480                let Some(formatting_transaction) =
 1481                    buffer.get_transaction(formatting_transaction_id).cloned()
 1482                else {
 1483                    zlog::warn!(logger => "no formatting transaction");
 1484                    return;
 1485                };
 1486                if formatting_transaction.edit_ids.is_empty() {
 1487                    zlog::debug!(logger => "no changes made while formatting");
 1488                    buffer.forget_transaction(formatting_transaction_id);
 1489                    return;
 1490                }
 1491                if !push_to_history {
 1492                    zlog::trace!(logger => "forgetting format transaction");
 1493                    buffer.forget_transaction(formatting_transaction.id);
 1494                }
 1495                project_transaction
 1496                    .0
 1497                    .insert(cx.entity(), formatting_transaction);
 1498            });
 1499
 1500            result?;
 1501        }
 1502
 1503        Ok(project_transaction)
 1504    }
 1505
 1506    async fn format_buffer_locally(
 1507        lsp_store: WeakEntity<LspStore>,
 1508        buffer: &FormattableBuffer,
 1509        formatting_transaction_id: clock::Lamport,
 1510        trigger: FormatTrigger,
 1511        logger: zlog::Logger,
 1512        cx: &mut AsyncApp,
 1513    ) -> Result<()> {
 1514        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1515            buffer.handle.update(cx, |buffer, cx| {
 1516                let adapters_and_servers = lsp_store
 1517                    .as_local()
 1518                    .unwrap()
 1519                    .language_servers_for_buffer(buffer, cx)
 1520                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1521                    .collect::<Vec<_>>();
 1522                let settings =
 1523                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1524                        .into_owned();
 1525                (adapters_and_servers, settings)
 1526            })
 1527        })?;
 1528
 1529        /// Apply edits to the buffer that will become part of the formatting transaction.
 1530        /// Fails if the buffer has been edited since the start of that transaction.
 1531        fn extend_formatting_transaction(
 1532            buffer: &FormattableBuffer,
 1533            formatting_transaction_id: text::TransactionId,
 1534            cx: &mut AsyncApp,
 1535            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1536        ) -> anyhow::Result<()> {
 1537            buffer.handle.update(cx, |buffer, cx| {
 1538                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1539                if last_transaction_id != Some(formatting_transaction_id) {
 1540                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1541                }
 1542                buffer.start_transaction();
 1543                operation(buffer, cx);
 1544                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1545                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1546                }
 1547                Ok(())
 1548            })
 1549        }
 1550
 1551        // handle whitespace formatting
 1552        if settings.remove_trailing_whitespace_on_save {
 1553            zlog::trace!(logger => "removing trailing whitespace");
 1554            let diff = buffer
 1555                .handle
 1556                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))
 1557                .await;
 1558            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1559                buffer.apply_diff(diff, cx);
 1560            })?;
 1561        }
 1562
 1563        if settings.ensure_final_newline_on_save {
 1564            zlog::trace!(logger => "ensuring final newline");
 1565            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1566                buffer.ensure_final_newline(cx);
 1567            })?;
 1568        }
 1569
 1570        // Formatter for `code_actions_on_format` that runs before
 1571        // the rest of the formatters
 1572        let mut code_actions_on_format_formatters = None;
 1573        let should_run_code_actions_on_format = !matches!(
 1574            (trigger, &settings.format_on_save),
 1575            (FormatTrigger::Save, &FormatOnSave::Off)
 1576        );
 1577        if should_run_code_actions_on_format {
 1578            let have_code_actions_to_run_on_format = settings
 1579                .code_actions_on_format
 1580                .values()
 1581                .any(|enabled| *enabled);
 1582            if have_code_actions_to_run_on_format {
 1583                zlog::trace!(logger => "going to run code actions on format");
 1584                code_actions_on_format_formatters = Some(
 1585                    settings
 1586                        .code_actions_on_format
 1587                        .iter()
 1588                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1589                        .cloned()
 1590                        .map(Formatter::CodeAction)
 1591                        .collect::<Vec<_>>(),
 1592                );
 1593            }
 1594        }
 1595
 1596        let formatters = match (trigger, &settings.format_on_save) {
 1597            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1598            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1599                settings.formatter.as_ref()
 1600            }
 1601        };
 1602
 1603        let formatters = code_actions_on_format_formatters
 1604            .iter()
 1605            .flatten()
 1606            .chain(formatters);
 1607
 1608        for formatter in formatters {
 1609            let formatter = if formatter == &Formatter::Auto {
 1610                if settings.prettier.allowed {
 1611                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1612                    &Formatter::Prettier
 1613                } else {
 1614                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1615                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1616                }
 1617            } else {
 1618                formatter
 1619            };
 1620            match formatter {
 1621                Formatter::Auto => unreachable!("Auto resolved above"),
 1622                Formatter::Prettier => {
 1623                    let logger = zlog::scoped!(logger => "prettier");
 1624                    zlog::trace!(logger => "formatting");
 1625                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1626
 1627                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1628                        lsp_store.prettier_store().unwrap().downgrade()
 1629                    })?;
 1630                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1631                        .await
 1632                        .transpose()?;
 1633                    let Some(diff) = diff else {
 1634                        zlog::trace!(logger => "No changes");
 1635                        continue;
 1636                    };
 1637
 1638                    extend_formatting_transaction(
 1639                        buffer,
 1640                        formatting_transaction_id,
 1641                        cx,
 1642                        |buffer, cx| {
 1643                            buffer.apply_diff(diff, cx);
 1644                        },
 1645                    )?;
 1646                }
 1647                Formatter::External { command, arguments } => {
 1648                    let logger = zlog::scoped!(logger => "command");
 1649                    zlog::trace!(logger => "formatting");
 1650                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1651
 1652                    let diff = Self::format_via_external_command(
 1653                        buffer,
 1654                        &command,
 1655                        arguments.as_deref(),
 1656                        cx,
 1657                    )
 1658                    .await
 1659                    .with_context(|| {
 1660                        format!("Failed to format buffer via external command: {}", command)
 1661                    })?;
 1662                    let Some(diff) = diff else {
 1663                        zlog::trace!(logger => "No changes");
 1664                        continue;
 1665                    };
 1666
 1667                    extend_formatting_transaction(
 1668                        buffer,
 1669                        formatting_transaction_id,
 1670                        cx,
 1671                        |buffer, cx| {
 1672                            buffer.apply_diff(diff, cx);
 1673                        },
 1674                    )?;
 1675                }
 1676                Formatter::LanguageServer(specifier) => {
 1677                    let logger = zlog::scoped!(logger => "language-server");
 1678                    zlog::trace!(logger => "formatting");
 1679                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1680
 1681                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1682                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1683                        continue;
 1684                    };
 1685
 1686                    let language_server = match specifier {
 1687                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1688                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1689                                if adapter.name.0.as_ref() == name {
 1690                                    Some(server.clone())
 1691                                } else {
 1692                                    None
 1693                                }
 1694                            })
 1695                        }
 1696                        settings::LanguageServerFormatterSpecifier::Current => {
 1697                            adapters_and_servers.first().map(|e| e.1.clone())
 1698                        }
 1699                    };
 1700
 1701                    let Some(language_server) = language_server else {
 1702                        log::debug!(
 1703                            "No language server found to format buffer '{:?}'. Skipping",
 1704                            buffer_path_abs.as_path().to_string_lossy()
 1705                        );
 1706                        continue;
 1707                    };
 1708
 1709                    zlog::trace!(
 1710                        logger =>
 1711                        "Formatting buffer '{:?}' using language server '{:?}'",
 1712                        buffer_path_abs.as_path().to_string_lossy(),
 1713                        language_server.name()
 1714                    );
 1715
 1716                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1717                        zlog::trace!(logger => "formatting ranges");
 1718                        Self::format_ranges_via_lsp(
 1719                            &lsp_store,
 1720                            &buffer.handle,
 1721                            ranges,
 1722                            buffer_path_abs,
 1723                            &language_server,
 1724                            &settings,
 1725                            cx,
 1726                        )
 1727                        .await
 1728                        .context("Failed to format ranges via language server")?
 1729                    } else {
 1730                        zlog::trace!(logger => "formatting full");
 1731                        Self::format_via_lsp(
 1732                            &lsp_store,
 1733                            &buffer.handle,
 1734                            buffer_path_abs,
 1735                            &language_server,
 1736                            &settings,
 1737                            cx,
 1738                        )
 1739                        .await
 1740                        .context("failed to format via language server")?
 1741                    };
 1742
 1743                    if edits.is_empty() {
 1744                        zlog::trace!(logger => "No changes");
 1745                        continue;
 1746                    }
 1747                    extend_formatting_transaction(
 1748                        buffer,
 1749                        formatting_transaction_id,
 1750                        cx,
 1751                        |buffer, cx| {
 1752                            buffer.edit(edits, None, cx);
 1753                        },
 1754                    )?;
 1755                }
 1756                Formatter::CodeAction(code_action_name) => {
 1757                    let logger = zlog::scoped!(logger => "code-actions");
 1758                    zlog::trace!(logger => "formatting");
 1759                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1760
 1761                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1762                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1763                        continue;
 1764                    };
 1765
 1766                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1767                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1768
 1769                    let mut actions_and_servers = Vec::new();
 1770
 1771                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1772                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1773                            &lsp_store,
 1774                            language_server.server_id(),
 1775                            vec![code_action_kind.clone()],
 1776                            &buffer.handle,
 1777                            cx,
 1778                        )
 1779                        .await
 1780                        .with_context(|| {
 1781                            format!(
 1782                                "Failed to resolve code action {:?} with language server {}",
 1783                                code_action_kind,
 1784                                language_server.name()
 1785                            )
 1786                        });
 1787                        let Ok(actions) = actions_result else {
 1788                            // note: it may be better to set result to the error and break formatters here
 1789                            // but for now we try to execute the actions that we can resolve and skip the rest
 1790                            zlog::error!(
 1791                                logger =>
 1792                                "Failed to resolve code action {:?} with language server {}",
 1793                                code_action_kind,
 1794                                language_server.name()
 1795                            );
 1796                            continue;
 1797                        };
 1798                        for action in actions {
 1799                            actions_and_servers.push((action, index));
 1800                        }
 1801                    }
 1802
 1803                    if actions_and_servers.is_empty() {
 1804                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1805                        continue;
 1806                    }
 1807
 1808                    'actions: for (mut action, server_index) in actions_and_servers {
 1809                        let server = &adapters_and_servers[server_index].1;
 1810
 1811                        let describe_code_action = |action: &CodeAction| {
 1812                            format!(
 1813                                "code action '{}' with title \"{}\" on server {}",
 1814                                action
 1815                                    .lsp_action
 1816                                    .action_kind()
 1817                                    .unwrap_or("unknown".into())
 1818                                    .as_str(),
 1819                                action.lsp_action.title(),
 1820                                server.name(),
 1821                            )
 1822                        };
 1823
 1824                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1825
 1826                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1827                            zlog::error!(
 1828                                logger =>
 1829                                "Failed to resolve {}. Error: {}",
 1830                                describe_code_action(&action),
 1831                                err
 1832                            );
 1833                            continue;
 1834                        }
 1835
 1836                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1837                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1838                            // but filters out and logs warnings for code actions that require unreasonably
 1839                            // difficult handling on our part, such as:
 1840                            // - applying edits that call commands
 1841                            //   which can result in arbitrary workspace edits being sent from the server that
 1842                            //   have no way of being tied back to the command that initiated them (i.e. we
 1843                            //   can't know which edits are part of the format request, or if the server is done sending
 1844                            //   actions in response to the command)
 1845                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1846                            //   as we then would need to handle such changes correctly in the local history as well
 1847                            //   as the remote history through the ProjectTransaction
 1848                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1849                            // Supporting these actions is not impossible, but not supported as of yet.
 1850                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1851                                zlog::trace!(
 1852                                    logger =>
 1853                                    "No changes for code action. Skipping {}",
 1854                                    describe_code_action(&action),
 1855                                );
 1856                                continue;
 1857                            }
 1858
 1859                            let mut operations = Vec::new();
 1860                            if let Some(document_changes) = edit.document_changes {
 1861                                match document_changes {
 1862                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1863                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1864                                    ),
 1865                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1866                                }
 1867                            } else if let Some(changes) = edit.changes {
 1868                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1869                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1870                                        text_document:
 1871                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1872                                                uri,
 1873                                                version: None,
 1874                                            },
 1875                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1876                                    })
 1877                                }));
 1878                            }
 1879
 1880                            let mut edits = Vec::with_capacity(operations.len());
 1881
 1882                            if operations.is_empty() {
 1883                                zlog::trace!(
 1884                                    logger =>
 1885                                    "No changes for code action. Skipping {}",
 1886                                    describe_code_action(&action),
 1887                                );
 1888                                continue;
 1889                            }
 1890                            for operation in operations {
 1891                                let op = match operation {
 1892                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1893                                    lsp::DocumentChangeOperation::Op(_) => {
 1894                                        zlog::warn!(
 1895                                            logger =>
 1896                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1897                                            describe_code_action(&action),
 1898                                        );
 1899                                        continue 'actions;
 1900                                    }
 1901                                };
 1902                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1903                                    zlog::warn!(
 1904                                        logger =>
 1905                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1906                                        &op.text_document.uri,
 1907                                        describe_code_action(&action),
 1908                                    );
 1909                                    continue 'actions;
 1910                                };
 1911                                if &file_path != buffer_path_abs {
 1912                                    zlog::warn!(
 1913                                        logger =>
 1914                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1915                                        file_path,
 1916                                        buffer_path_abs,
 1917                                        describe_code_action(&action),
 1918                                    );
 1919                                    continue 'actions;
 1920                                }
 1921
 1922                                let mut lsp_edits = Vec::new();
 1923                                for edit in op.edits {
 1924                                    match edit {
 1925                                        Edit::Plain(edit) => {
 1926                                            if !lsp_edits.contains(&edit) {
 1927                                                lsp_edits.push(edit);
 1928                                            }
 1929                                        }
 1930                                        Edit::Annotated(edit) => {
 1931                                            if !lsp_edits.contains(&edit.text_edit) {
 1932                                                lsp_edits.push(edit.text_edit);
 1933                                            }
 1934                                        }
 1935                                        Edit::Snippet(_) => {
 1936                                            zlog::warn!(
 1937                                                logger =>
 1938                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1939                                                describe_code_action(&action),
 1940                                            );
 1941                                            continue 'actions;
 1942                                        }
 1943                                    }
 1944                                }
 1945                                let edits_result = lsp_store
 1946                                    .update(cx, |lsp_store, cx| {
 1947                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1948                                            &buffer.handle,
 1949                                            lsp_edits,
 1950                                            server.server_id(),
 1951                                            op.text_document.version,
 1952                                            cx,
 1953                                        )
 1954                                    })?
 1955                                    .await;
 1956                                let Ok(resolved_edits) = edits_result else {
 1957                                    zlog::warn!(
 1958                                        logger =>
 1959                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1960                                        buffer_path_abs.as_path(),
 1961                                        describe_code_action(&action),
 1962                                    );
 1963                                    continue 'actions;
 1964                                };
 1965                                edits.extend(resolved_edits);
 1966                            }
 1967
 1968                            if edits.is_empty() {
 1969                                zlog::warn!(logger => "No edits resolved from LSP");
 1970                                continue;
 1971                            }
 1972
 1973                            extend_formatting_transaction(
 1974                                buffer,
 1975                                formatting_transaction_id,
 1976                                cx,
 1977                                |buffer, cx| {
 1978                                    zlog::info!(
 1979                                        "Applying edits {edits:?}. Content: {:?}",
 1980                                        buffer.text()
 1981                                    );
 1982                                    buffer.edit(edits, None, cx);
 1983                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 1984                                },
 1985                            )?;
 1986                        }
 1987
 1988                        if let Some(command) = action.lsp_action.command() {
 1989                            zlog::warn!(
 1990                                logger =>
 1991                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1992                                &command.command,
 1993                            );
 1994
 1995                            // bail early if command is invalid
 1996                            let server_capabilities = server.capabilities();
 1997                            let available_commands = server_capabilities
 1998                                .execute_command_provider
 1999                                .as_ref()
 2000                                .map(|options| options.commands.as_slice())
 2001                                .unwrap_or_default();
 2002                            if !available_commands.contains(&command.command) {
 2003                                zlog::warn!(
 2004                                    logger =>
 2005                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 2006                                    command.command,
 2007                                    server.name(),
 2008                                );
 2009                                continue;
 2010                            }
 2011
 2012                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 2013                            extend_formatting_transaction(
 2014                                buffer,
 2015                                formatting_transaction_id,
 2016                                cx,
 2017                                |_, _| {},
 2018                            )?;
 2019                            zlog::info!(logger => "Executing command {}", &command.command);
 2020
 2021                            lsp_store.update(cx, |this, _| {
 2022                                this.as_local_mut()
 2023                                    .unwrap()
 2024                                    .last_workspace_edits_by_language_server
 2025                                    .remove(&server.server_id());
 2026                            })?;
 2027
 2028                            let execute_command_result = server
 2029                                .request::<lsp::request::ExecuteCommand>(
 2030                                    lsp::ExecuteCommandParams {
 2031                                        command: command.command.clone(),
 2032                                        arguments: command.arguments.clone().unwrap_or_default(),
 2033                                        ..Default::default()
 2034                                    },
 2035                                )
 2036                                .await
 2037                                .into_response();
 2038
 2039                            if execute_command_result.is_err() {
 2040                                zlog::error!(
 2041                                    logger =>
 2042                                    "Failed to execute command '{}' as part of {}",
 2043                                    &command.command,
 2044                                    describe_code_action(&action),
 2045                                );
 2046                                continue 'actions;
 2047                            }
 2048
 2049                            let mut project_transaction_command =
 2050                                lsp_store.update(cx, |this, _| {
 2051                                    this.as_local_mut()
 2052                                        .unwrap()
 2053                                        .last_workspace_edits_by_language_server
 2054                                        .remove(&server.server_id())
 2055                                        .unwrap_or_default()
 2056                                })?;
 2057
 2058                            if let Some(transaction) =
 2059                                project_transaction_command.0.remove(&buffer.handle)
 2060                            {
 2061                                zlog::trace!(
 2062                                    logger =>
 2063                                    "Successfully captured {} edits that resulted from command {}",
 2064                                    transaction.edit_ids.len(),
 2065                                    &command.command,
 2066                                );
 2067                                let transaction_id_project_transaction = transaction.id;
 2068                                buffer.handle.update(cx, |buffer, _| {
 2069                                    // it may have been removed from history if push_to_history was
 2070                                    // false in deserialize_workspace_edit. If so push it so we
 2071                                    // can merge it with the format transaction
 2072                                    // and pop the combined transaction off the history stack
 2073                                    // later if push_to_history is false
 2074                                    if buffer.get_transaction(transaction.id).is_none() {
 2075                                        buffer.push_transaction(transaction, Instant::now());
 2076                                    }
 2077                                    buffer.merge_transactions(
 2078                                        transaction_id_project_transaction,
 2079                                        formatting_transaction_id,
 2080                                    );
 2081                                });
 2082                            }
 2083
 2084                            if !project_transaction_command.0.is_empty() {
 2085                                let mut extra_buffers = String::new();
 2086                                for buffer in project_transaction_command.0.keys() {
 2087                                    buffer.read_with(cx, |b, cx| {
 2088                                        if let Some(path) = b.project_path(cx) {
 2089                                            if !extra_buffers.is_empty() {
 2090                                                extra_buffers.push_str(", ");
 2091                                            }
 2092                                            extra_buffers.push_str(path.path.as_unix_str());
 2093                                        }
 2094                                    });
 2095                                }
 2096                                zlog::warn!(
 2097                                    logger =>
 2098                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 2099                                    &command.command,
 2100                                    extra_buffers,
 2101                                );
 2102                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 2103                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 2104                                // add it so it's included, and merge it into the format transaction when its created later
 2105                            }
 2106                        }
 2107                    }
 2108                }
 2109            }
 2110        }
 2111
 2112        Ok(())
 2113    }
 2114
 2115    pub async fn format_ranges_via_lsp(
 2116        this: &WeakEntity<LspStore>,
 2117        buffer_handle: &Entity<Buffer>,
 2118        ranges: &[Range<Anchor>],
 2119        abs_path: &Path,
 2120        language_server: &Arc<LanguageServer>,
 2121        settings: &LanguageSettings,
 2122        cx: &mut AsyncApp,
 2123    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2124        let capabilities = &language_server.capabilities();
 2125        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2126        if range_formatting_provider == Some(&OneOf::Left(false)) {
 2127            anyhow::bail!(
 2128                "{} language server does not support range formatting",
 2129                language_server.name()
 2130            );
 2131        }
 2132
 2133        let uri = file_path_to_lsp_url(abs_path)?;
 2134        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2135
 2136        let lsp_edits = {
 2137            let mut lsp_ranges = Vec::new();
 2138            this.update(cx, |_this, cx| {
 2139                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 2140                // not have been sent to the language server. This seems like a fairly systemic
 2141                // issue, though, the resolution probably is not specific to formatting.
 2142                //
 2143                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 2144                // LSP.
 2145                let snapshot = buffer_handle.read(cx).snapshot();
 2146                for range in ranges {
 2147                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 2148                }
 2149                anyhow::Ok(())
 2150            })??;
 2151
 2152            let mut edits = None;
 2153            for range in lsp_ranges {
 2154                if let Some(mut edit) = language_server
 2155                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2156                        text_document: text_document.clone(),
 2157                        range,
 2158                        options: lsp_command::lsp_formatting_options(settings),
 2159                        work_done_progress_params: Default::default(),
 2160                    })
 2161                    .await
 2162                    .into_response()?
 2163                {
 2164                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2165                }
 2166            }
 2167            edits
 2168        };
 2169
 2170        if let Some(lsp_edits) = lsp_edits {
 2171            this.update(cx, |this, cx| {
 2172                this.as_local_mut().unwrap().edits_from_lsp(
 2173                    buffer_handle,
 2174                    lsp_edits,
 2175                    language_server.server_id(),
 2176                    None,
 2177                    cx,
 2178                )
 2179            })?
 2180            .await
 2181        } else {
 2182            Ok(Vec::with_capacity(0))
 2183        }
 2184    }
 2185
 2186    async fn format_via_lsp(
 2187        this: &WeakEntity<LspStore>,
 2188        buffer: &Entity<Buffer>,
 2189        abs_path: &Path,
 2190        language_server: &Arc<LanguageServer>,
 2191        settings: &LanguageSettings,
 2192        cx: &mut AsyncApp,
 2193    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2194        let logger = zlog::scoped!("lsp_format");
 2195        zlog::debug!(logger => "Formatting via LSP");
 2196
 2197        let uri = file_path_to_lsp_url(abs_path)?;
 2198        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2199        let capabilities = &language_server.capabilities();
 2200
 2201        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2202        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2203
 2204        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2205            let _timer = zlog::time!(logger => "format-full");
 2206            language_server
 2207                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 2208                    text_document,
 2209                    options: lsp_command::lsp_formatting_options(settings),
 2210                    work_done_progress_params: Default::default(),
 2211                })
 2212                .await
 2213                .into_response()?
 2214        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2215            let _timer = zlog::time!(logger => "format-range");
 2216            let buffer_start = lsp::Position::new(0, 0);
 2217            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()));
 2218            language_server
 2219                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2220                    text_document: text_document.clone(),
 2221                    range: lsp::Range::new(buffer_start, buffer_end),
 2222                    options: lsp_command::lsp_formatting_options(settings),
 2223                    work_done_progress_params: Default::default(),
 2224                })
 2225                .await
 2226                .into_response()?
 2227        } else {
 2228            None
 2229        };
 2230
 2231        if let Some(lsp_edits) = lsp_edits {
 2232            this.update(cx, |this, cx| {
 2233                this.as_local_mut().unwrap().edits_from_lsp(
 2234                    buffer,
 2235                    lsp_edits,
 2236                    language_server.server_id(),
 2237                    None,
 2238                    cx,
 2239                )
 2240            })?
 2241            .await
 2242        } else {
 2243            Ok(Vec::with_capacity(0))
 2244        }
 2245    }
 2246
 2247    async fn format_via_external_command(
 2248        buffer: &FormattableBuffer,
 2249        command: &str,
 2250        arguments: Option<&[String]>,
 2251        cx: &mut AsyncApp,
 2252    ) -> Result<Option<Diff>> {
 2253        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2254            let file = File::from_dyn(buffer.file())?;
 2255            let worktree = file.worktree.read(cx);
 2256            let mut worktree_path = worktree.abs_path().to_path_buf();
 2257            if worktree.root_entry()?.is_file() {
 2258                worktree_path.pop();
 2259            }
 2260            Some(worktree_path)
 2261        });
 2262
 2263        let mut child = util::command::new_smol_command(command);
 2264
 2265        if let Some(buffer_env) = buffer.env.as_ref() {
 2266            child.envs(buffer_env);
 2267        }
 2268
 2269        if let Some(working_dir_path) = working_dir_path {
 2270            child.current_dir(working_dir_path);
 2271        }
 2272
 2273        if let Some(arguments) = arguments {
 2274            child.args(arguments.iter().map(|arg| {
 2275                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2276                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2277                } else {
 2278                    arg.replace("{buffer_path}", "Untitled")
 2279                }
 2280            }));
 2281        }
 2282
 2283        let mut child = child
 2284            .stdin(smol::process::Stdio::piped())
 2285            .stdout(smol::process::Stdio::piped())
 2286            .stderr(smol::process::Stdio::piped())
 2287            .spawn()?;
 2288
 2289        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2290        let text = buffer
 2291            .handle
 2292            .read_with(cx, |buffer, _| buffer.as_rope().clone());
 2293        for chunk in text.chunks() {
 2294            stdin.write_all(chunk.as_bytes()).await?;
 2295        }
 2296        stdin.flush().await?;
 2297
 2298        let output = child.output().await?;
 2299        anyhow::ensure!(
 2300            output.status.success(),
 2301            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2302            output.status.code(),
 2303            String::from_utf8_lossy(&output.stdout),
 2304            String::from_utf8_lossy(&output.stderr),
 2305        );
 2306
 2307        let stdout = String::from_utf8(output.stdout)?;
 2308        Ok(Some(
 2309            buffer
 2310                .handle
 2311                .update(cx, |buffer, cx| buffer.diff(stdout, cx))
 2312                .await,
 2313        ))
 2314    }
 2315
 2316    async fn try_resolve_code_action(
 2317        lang_server: &LanguageServer,
 2318        action: &mut CodeAction,
 2319    ) -> anyhow::Result<()> {
 2320        match &mut action.lsp_action {
 2321            LspAction::Action(lsp_action) => {
 2322                if !action.resolved
 2323                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2324                    && lsp_action.data.is_some()
 2325                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2326                {
 2327                    **lsp_action = lang_server
 2328                        .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2329                        .await
 2330                        .into_response()?;
 2331                }
 2332            }
 2333            LspAction::CodeLens(lens) => {
 2334                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2335                    *lens = lang_server
 2336                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2337                        .await
 2338                        .into_response()?;
 2339                }
 2340            }
 2341            LspAction::Command(_) => {}
 2342        }
 2343
 2344        action.resolved = true;
 2345        anyhow::Ok(())
 2346    }
 2347
 2348    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2349        let buffer = buffer_handle.read(cx);
 2350
 2351        let file = buffer.file().cloned();
 2352
 2353        let Some(file) = File::from_dyn(file.as_ref()) else {
 2354            return;
 2355        };
 2356        if !file.is_local() {
 2357            return;
 2358        }
 2359        let path = ProjectPath::from_file(file, cx);
 2360        let worktree_id = file.worktree_id(cx);
 2361        let language = buffer.language().cloned();
 2362
 2363        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2364            for (server_id, diagnostics) in
 2365                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2366            {
 2367                self.update_buffer_diagnostics(
 2368                    buffer_handle,
 2369                    server_id,
 2370                    None,
 2371                    None,
 2372                    None,
 2373                    Vec::new(),
 2374                    diagnostics,
 2375                    cx,
 2376                )
 2377                .log_err();
 2378            }
 2379        }
 2380        let Some(language) = language else {
 2381            return;
 2382        };
 2383        let Some(snapshot) = self
 2384            .worktree_store
 2385            .read(cx)
 2386            .worktree_for_id(worktree_id, cx)
 2387            .map(|worktree| worktree.read(cx).snapshot())
 2388        else {
 2389            return;
 2390        };
 2391        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2392
 2393        for server_id in
 2394            self.lsp_tree
 2395                .get(path, language.name(), language.manifest(), &delegate, cx)
 2396        {
 2397            let server = self
 2398                .language_servers
 2399                .get(&server_id)
 2400                .and_then(|server_state| {
 2401                    if let LanguageServerState::Running { server, .. } = server_state {
 2402                        Some(server.clone())
 2403                    } else {
 2404                        None
 2405                    }
 2406                });
 2407            let server = match server {
 2408                Some(server) => server,
 2409                None => continue,
 2410            };
 2411
 2412            buffer_handle.update(cx, |buffer, cx| {
 2413                buffer.set_completion_triggers(
 2414                    server.server_id(),
 2415                    server
 2416                        .capabilities()
 2417                        .completion_provider
 2418                        .as_ref()
 2419                        .and_then(|provider| {
 2420                            provider
 2421                                .trigger_characters
 2422                                .as_ref()
 2423                                .map(|characters| characters.iter().cloned().collect())
 2424                        })
 2425                        .unwrap_or_default(),
 2426                    cx,
 2427                );
 2428            });
 2429        }
 2430    }
 2431
 2432    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2433        buffer.update(cx, |buffer, cx| {
 2434            let Some(language) = buffer.language() else {
 2435                return;
 2436            };
 2437            let path = ProjectPath {
 2438                worktree_id: old_file.worktree_id(cx),
 2439                path: old_file.path.clone(),
 2440            };
 2441            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2442                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2443                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2444            }
 2445        });
 2446    }
 2447
 2448    fn update_buffer_diagnostics(
 2449        &mut self,
 2450        buffer: &Entity<Buffer>,
 2451        server_id: LanguageServerId,
 2452        registration_id: Option<Option<SharedString>>,
 2453        result_id: Option<SharedString>,
 2454        version: Option<i32>,
 2455        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2456        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2457        cx: &mut Context<LspStore>,
 2458    ) -> Result<()> {
 2459        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2460            Ordering::Equal
 2461                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2462                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2463                .then_with(|| a.severity.cmp(&b.severity))
 2464                .then_with(|| a.message.cmp(&b.message))
 2465        }
 2466
 2467        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2468        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2469        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2470
 2471        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2472            Ordering::Equal
 2473                .then_with(|| a.range.start.cmp(&b.range.start))
 2474                .then_with(|| b.range.end.cmp(&a.range.end))
 2475                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2476        });
 2477
 2478        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2479
 2480        let edits_since_save = std::cell::LazyCell::new(|| {
 2481            let saved_version = buffer.read(cx).saved_version();
 2482            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2483        });
 2484
 2485        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2486
 2487        for (new_diagnostic, entry) in diagnostics {
 2488            let start;
 2489            let end;
 2490            if new_diagnostic && entry.diagnostic.is_disk_based {
 2491                // Some diagnostics are based on files on disk instead of buffers'
 2492                // current contents. Adjust these diagnostics' ranges to reflect
 2493                // any unsaved edits.
 2494                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2495                // and were properly adjusted on reuse.
 2496                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2497                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2498            } else {
 2499                start = entry.range.start;
 2500                end = entry.range.end;
 2501            }
 2502
 2503            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2504                ..snapshot.clip_point_utf16(end, Bias::Right);
 2505
 2506            // Expand empty ranges by one codepoint
 2507            if range.start == range.end {
 2508                // This will be go to the next boundary when being clipped
 2509                range.end.column += 1;
 2510                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2511                if range.start == range.end && range.end.column > 0 {
 2512                    range.start.column -= 1;
 2513                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2514                }
 2515            }
 2516
 2517            sanitized_diagnostics.push(DiagnosticEntry {
 2518                range,
 2519                diagnostic: entry.diagnostic,
 2520            });
 2521        }
 2522        drop(edits_since_save);
 2523
 2524        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2525        buffer.update(cx, |buffer, cx| {
 2526            if let Some(registration_id) = registration_id {
 2527                if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2528                    self.buffer_pull_diagnostics_result_ids
 2529                        .entry(server_id)
 2530                        .or_default()
 2531                        .entry(registration_id)
 2532                        .or_default()
 2533                        .insert(abs_path, result_id);
 2534                }
 2535            }
 2536
 2537            buffer.update_diagnostics(server_id, set, cx)
 2538        });
 2539
 2540        Ok(())
 2541    }
 2542
 2543    fn register_language_server_for_invisible_worktree(
 2544        &mut self,
 2545        worktree: &Entity<Worktree>,
 2546        language_server_id: LanguageServerId,
 2547        cx: &mut App,
 2548    ) {
 2549        let worktree = worktree.read(cx);
 2550        let worktree_id = worktree.id();
 2551        debug_assert!(!worktree.is_visible());
 2552        let Some(mut origin_seed) = self
 2553            .language_server_ids
 2554            .iter()
 2555            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2556        else {
 2557            return;
 2558        };
 2559        origin_seed.worktree_id = worktree_id;
 2560        self.language_server_ids
 2561            .entry(origin_seed)
 2562            .or_insert_with(|| UnifiedLanguageServer {
 2563                id: language_server_id,
 2564                project_roots: Default::default(),
 2565            });
 2566    }
 2567
 2568    fn register_buffer_with_language_servers(
 2569        &mut self,
 2570        buffer_handle: &Entity<Buffer>,
 2571        only_register_servers: HashSet<LanguageServerSelector>,
 2572        cx: &mut Context<LspStore>,
 2573    ) {
 2574        let buffer = buffer_handle.read(cx);
 2575        let buffer_id = buffer.remote_id();
 2576
 2577        let Some(file) = File::from_dyn(buffer.file()) else {
 2578            return;
 2579        };
 2580        if !file.is_local() {
 2581            return;
 2582        }
 2583
 2584        let abs_path = file.abs_path(cx);
 2585        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2586            return;
 2587        };
 2588        let initial_snapshot = buffer.text_snapshot();
 2589        let worktree_id = file.worktree_id(cx);
 2590
 2591        let Some(language) = buffer.language().cloned() else {
 2592            return;
 2593        };
 2594        let path: Arc<RelPath> = file
 2595            .path()
 2596            .parent()
 2597            .map(Arc::from)
 2598            .unwrap_or_else(|| file.path().clone());
 2599        let Some(worktree) = self
 2600            .worktree_store
 2601            .read(cx)
 2602            .worktree_for_id(worktree_id, cx)
 2603        else {
 2604            return;
 2605        };
 2606        let language_name = language.name();
 2607        let (reused, delegate, servers) = self
 2608            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2609            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2610            .unwrap_or_else(|| {
 2611                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2612                let delegate: Arc<dyn ManifestDelegate> =
 2613                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2614
 2615                let servers = self
 2616                    .lsp_tree
 2617                    .walk(
 2618                        ProjectPath { worktree_id, path },
 2619                        language.name(),
 2620                        language.manifest(),
 2621                        &delegate,
 2622                        cx,
 2623                    )
 2624                    .collect::<Vec<_>>();
 2625                (false, lsp_delegate, servers)
 2626            });
 2627        let servers_and_adapters = servers
 2628            .into_iter()
 2629            .filter_map(|server_node| {
 2630                if reused && server_node.server_id().is_none() {
 2631                    return None;
 2632                }
 2633                if !only_register_servers.is_empty() {
 2634                    if let Some(server_id) = server_node.server_id()
 2635                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2636                    {
 2637                        return None;
 2638                    }
 2639                    if let Some(name) = server_node.name()
 2640                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2641                    {
 2642                        return None;
 2643                    }
 2644                }
 2645
 2646                let server_id = server_node.server_id_or_init(|disposition| {
 2647                    let path = &disposition.path;
 2648
 2649                    {
 2650                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2651
 2652                        let server_id = self.get_or_insert_language_server(
 2653                            &worktree,
 2654                            delegate.clone(),
 2655                            disposition,
 2656                            &language_name,
 2657                            cx,
 2658                        );
 2659
 2660                        if let Some(state) = self.language_servers.get(&server_id)
 2661                            && let Ok(uri) = uri
 2662                        {
 2663                            state.add_workspace_folder(uri);
 2664                        };
 2665                        server_id
 2666                    }
 2667                })?;
 2668                let server_state = self.language_servers.get(&server_id)?;
 2669                if let LanguageServerState::Running {
 2670                    server, adapter, ..
 2671                } = server_state
 2672                {
 2673                    Some((server.clone(), adapter.clone()))
 2674                } else {
 2675                    None
 2676                }
 2677            })
 2678            .collect::<Vec<_>>();
 2679        for (server, adapter) in servers_and_adapters {
 2680            buffer_handle.update(cx, |buffer, cx| {
 2681                buffer.set_completion_triggers(
 2682                    server.server_id(),
 2683                    server
 2684                        .capabilities()
 2685                        .completion_provider
 2686                        .as_ref()
 2687                        .and_then(|provider| {
 2688                            provider
 2689                                .trigger_characters
 2690                                .as_ref()
 2691                                .map(|characters| characters.iter().cloned().collect())
 2692                        })
 2693                        .unwrap_or_default(),
 2694                    cx,
 2695                );
 2696            });
 2697
 2698            let snapshot = LspBufferSnapshot {
 2699                version: 0,
 2700                snapshot: initial_snapshot.clone(),
 2701            };
 2702
 2703            let mut registered = false;
 2704            self.buffer_snapshots
 2705                .entry(buffer_id)
 2706                .or_default()
 2707                .entry(server.server_id())
 2708                .or_insert_with(|| {
 2709                    registered = true;
 2710                    server.register_buffer(
 2711                        uri.clone(),
 2712                        adapter.language_id(&language.name()),
 2713                        0,
 2714                        initial_snapshot.text(),
 2715                    );
 2716
 2717                    vec![snapshot]
 2718                });
 2719
 2720            self.buffers_opened_in_servers
 2721                .entry(buffer_id)
 2722                .or_default()
 2723                .insert(server.server_id());
 2724            if registered {
 2725                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2726                    language_server_id: server.server_id(),
 2727                    name: None,
 2728                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2729                        proto::RegisteredForBuffer {
 2730                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2731                            buffer_id: buffer_id.to_proto(),
 2732                        },
 2733                    ),
 2734                });
 2735            }
 2736        }
 2737    }
 2738
 2739    fn reuse_existing_language_server<'lang_name>(
 2740        &self,
 2741        server_tree: &LanguageServerTree,
 2742        worktree: &Entity<Worktree>,
 2743        language_name: &'lang_name LanguageName,
 2744        cx: &mut App,
 2745    ) -> Option<(
 2746        Arc<LocalLspAdapterDelegate>,
 2747        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2748    )> {
 2749        if worktree.read(cx).is_visible() {
 2750            return None;
 2751        }
 2752
 2753        let worktree_store = self.worktree_store.read(cx);
 2754        let servers = server_tree
 2755            .instances
 2756            .iter()
 2757            .filter(|(worktree_id, _)| {
 2758                worktree_store
 2759                    .worktree_for_id(**worktree_id, cx)
 2760                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2761            })
 2762            .flat_map(|(worktree_id, servers)| {
 2763                servers
 2764                    .roots
 2765                    .iter()
 2766                    .flat_map(|(_, language_servers)| language_servers)
 2767                    .map(move |(_, (server_node, server_languages))| {
 2768                        (worktree_id, server_node, server_languages)
 2769                    })
 2770                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2771                    .map(|(worktree_id, server_node, _)| {
 2772                        (
 2773                            *worktree_id,
 2774                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2775                        )
 2776                    })
 2777            })
 2778            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2779                acc.entry(worktree_id)
 2780                    .or_insert_with(Vec::new)
 2781                    .push(server_node);
 2782                acc
 2783            })
 2784            .into_values()
 2785            .max_by_key(|servers| servers.len())?;
 2786
 2787        let worktree_id = worktree.read(cx).id();
 2788        let apply = move |tree: &mut LanguageServerTree| {
 2789            for server_node in &servers {
 2790                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2791            }
 2792            servers
 2793        };
 2794
 2795        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2796        Some((delegate, apply))
 2797    }
 2798
 2799    pub(crate) fn unregister_old_buffer_from_language_servers(
 2800        &mut self,
 2801        buffer: &Entity<Buffer>,
 2802        old_file: &File,
 2803        cx: &mut App,
 2804    ) {
 2805        let old_path = match old_file.as_local() {
 2806            Some(local) => local.abs_path(cx),
 2807            None => return,
 2808        };
 2809
 2810        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2811            debug_panic!("{old_path:?} is not parseable as an URI");
 2812            return;
 2813        };
 2814        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2815    }
 2816
 2817    pub(crate) fn unregister_buffer_from_language_servers(
 2818        &mut self,
 2819        buffer: &Entity<Buffer>,
 2820        file_url: &lsp::Uri,
 2821        cx: &mut App,
 2822    ) {
 2823        buffer.update(cx, |buffer, cx| {
 2824            let mut snapshots = self.buffer_snapshots.remove(&buffer.remote_id());
 2825
 2826            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2827                if snapshots
 2828                    .as_mut()
 2829                    .is_some_and(|map| map.remove(&language_server.server_id()).is_some())
 2830                {
 2831                    language_server.unregister_buffer(file_url.clone());
 2832                }
 2833            }
 2834        });
 2835    }
 2836
 2837    fn buffer_snapshot_for_lsp_version(
 2838        &mut self,
 2839        buffer: &Entity<Buffer>,
 2840        server_id: LanguageServerId,
 2841        version: Option<i32>,
 2842        cx: &App,
 2843    ) -> Result<TextBufferSnapshot> {
 2844        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2845
 2846        if let Some(version) = version {
 2847            let buffer_id = buffer.read(cx).remote_id();
 2848            let snapshots = if let Some(snapshots) = self
 2849                .buffer_snapshots
 2850                .get_mut(&buffer_id)
 2851                .and_then(|m| m.get_mut(&server_id))
 2852            {
 2853                snapshots
 2854            } else if version == 0 {
 2855                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2856                // We detect this case and treat it as if the version was `None`.
 2857                return Ok(buffer.read(cx).text_snapshot());
 2858            } else {
 2859                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2860            };
 2861
 2862            let found_snapshot = snapshots
 2863                    .binary_search_by_key(&version, |e| e.version)
 2864                    .map(|ix| snapshots[ix].snapshot.clone())
 2865                    .map_err(|_| {
 2866                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2867                    })?;
 2868
 2869            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2870            Ok(found_snapshot)
 2871        } else {
 2872            Ok((buffer.read(cx)).text_snapshot())
 2873        }
 2874    }
 2875
 2876    async fn get_server_code_actions_from_action_kinds(
 2877        lsp_store: &WeakEntity<LspStore>,
 2878        language_server_id: LanguageServerId,
 2879        code_action_kinds: Vec<lsp::CodeActionKind>,
 2880        buffer: &Entity<Buffer>,
 2881        cx: &mut AsyncApp,
 2882    ) -> Result<Vec<CodeAction>> {
 2883        let actions = lsp_store
 2884            .update(cx, move |this, cx| {
 2885                let request = GetCodeActions {
 2886                    range: text::Anchor::min_max_range_for_buffer(buffer.read(cx).remote_id()),
 2887                    kinds: Some(code_action_kinds),
 2888                };
 2889                let server = LanguageServerToQuery::Other(language_server_id);
 2890                this.request_lsp(buffer.clone(), server, request, cx)
 2891            })?
 2892            .await?;
 2893        Ok(actions)
 2894    }
 2895
 2896    pub async fn execute_code_actions_on_server(
 2897        lsp_store: &WeakEntity<LspStore>,
 2898        language_server: &Arc<LanguageServer>,
 2899
 2900        actions: Vec<CodeAction>,
 2901        push_to_history: bool,
 2902        project_transaction: &mut ProjectTransaction,
 2903        cx: &mut AsyncApp,
 2904    ) -> anyhow::Result<()> {
 2905        for mut action in actions {
 2906            Self::try_resolve_code_action(language_server, &mut action)
 2907                .await
 2908                .context("resolving a formatting code action")?;
 2909
 2910            if let Some(edit) = action.lsp_action.edit() {
 2911                if edit.changes.is_none() && edit.document_changes.is_none() {
 2912                    continue;
 2913                }
 2914
 2915                let new = Self::deserialize_workspace_edit(
 2916                    lsp_store.upgrade().context("project dropped")?,
 2917                    edit.clone(),
 2918                    push_to_history,
 2919                    language_server.clone(),
 2920                    cx,
 2921                )
 2922                .await?;
 2923                project_transaction.0.extend(new.0);
 2924            }
 2925
 2926            if let Some(command) = action.lsp_action.command() {
 2927                let server_capabilities = language_server.capabilities();
 2928                let available_commands = server_capabilities
 2929                    .execute_command_provider
 2930                    .as_ref()
 2931                    .map(|options| options.commands.as_slice())
 2932                    .unwrap_or_default();
 2933                if available_commands.contains(&command.command) {
 2934                    lsp_store.update(cx, |lsp_store, _| {
 2935                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2936                            mode.last_workspace_edits_by_language_server
 2937                                .remove(&language_server.server_id());
 2938                        }
 2939                    })?;
 2940
 2941                    language_server
 2942                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2943                            command: command.command.clone(),
 2944                            arguments: command.arguments.clone().unwrap_or_default(),
 2945                            ..Default::default()
 2946                        })
 2947                        .await
 2948                        .into_response()
 2949                        .context("execute command")?;
 2950
 2951                    lsp_store.update(cx, |this, _| {
 2952                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2953                            project_transaction.0.extend(
 2954                                mode.last_workspace_edits_by_language_server
 2955                                    .remove(&language_server.server_id())
 2956                                    .unwrap_or_default()
 2957                                    .0,
 2958                            )
 2959                        }
 2960                    })?;
 2961                } else {
 2962                    log::warn!(
 2963                        "Cannot execute a command {} not listed in the language server capabilities",
 2964                        command.command
 2965                    )
 2966                }
 2967            }
 2968        }
 2969        Ok(())
 2970    }
 2971
 2972    pub async fn deserialize_text_edits(
 2973        this: Entity<LspStore>,
 2974        buffer_to_edit: Entity<Buffer>,
 2975        edits: Vec<lsp::TextEdit>,
 2976        push_to_history: bool,
 2977        _: Arc<CachedLspAdapter>,
 2978        language_server: Arc<LanguageServer>,
 2979        cx: &mut AsyncApp,
 2980    ) -> Result<Option<Transaction>> {
 2981        let edits = this
 2982            .update(cx, |this, cx| {
 2983                this.as_local_mut().unwrap().edits_from_lsp(
 2984                    &buffer_to_edit,
 2985                    edits,
 2986                    language_server.server_id(),
 2987                    None,
 2988                    cx,
 2989                )
 2990            })
 2991            .await?;
 2992
 2993        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2994            buffer.finalize_last_transaction();
 2995            buffer.start_transaction();
 2996            for (range, text) in edits {
 2997                buffer.edit([(range, text)], None, cx);
 2998            }
 2999
 3000            if buffer.end_transaction(cx).is_some() {
 3001                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 3002                if !push_to_history {
 3003                    buffer.forget_transaction(transaction.id);
 3004                }
 3005                Some(transaction)
 3006            } else {
 3007                None
 3008            }
 3009        });
 3010
 3011        Ok(transaction)
 3012    }
 3013
 3014    #[allow(clippy::type_complexity)]
 3015    pub fn edits_from_lsp(
 3016        &mut self,
 3017        buffer: &Entity<Buffer>,
 3018        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 3019        server_id: LanguageServerId,
 3020        version: Option<i32>,
 3021        cx: &mut Context<LspStore>,
 3022    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 3023        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 3024        cx.background_spawn(async move {
 3025            let snapshot = snapshot?;
 3026            let mut lsp_edits = lsp_edits
 3027                .into_iter()
 3028                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 3029                .collect::<Vec<_>>();
 3030
 3031            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 3032
 3033            let mut lsp_edits = lsp_edits.into_iter().peekable();
 3034            let mut edits = Vec::new();
 3035            while let Some((range, mut new_text)) = lsp_edits.next() {
 3036                // Clip invalid ranges provided by the language server.
 3037                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 3038                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 3039
 3040                // Combine any LSP edits that are adjacent.
 3041                //
 3042                // Also, combine LSP edits that are separated from each other by only
 3043                // a newline. This is important because for some code actions,
 3044                // Rust-analyzer rewrites the entire buffer via a series of edits that
 3045                // are separated by unchanged newline characters.
 3046                //
 3047                // In order for the diffing logic below to work properly, any edits that
 3048                // cancel each other out must be combined into one.
 3049                while let Some((next_range, next_text)) = lsp_edits.peek() {
 3050                    if next_range.start.0 > range.end {
 3051                        if next_range.start.0.row > range.end.row + 1
 3052                            || next_range.start.0.column > 0
 3053                            || snapshot.clip_point_utf16(
 3054                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 3055                                Bias::Left,
 3056                            ) > range.end
 3057                        {
 3058                            break;
 3059                        }
 3060                        new_text.push('\n');
 3061                    }
 3062                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 3063                    new_text.push_str(next_text);
 3064                    lsp_edits.next();
 3065                }
 3066
 3067                // For multiline edits, perform a diff of the old and new text so that
 3068                // we can identify the changes more precisely, preserving the locations
 3069                // of any anchors positioned in the unchanged regions.
 3070                if range.end.row > range.start.row {
 3071                    let offset = range.start.to_offset(&snapshot);
 3072                    let old_text = snapshot.text_for_range(range).collect::<String>();
 3073                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 3074                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 3075                        (
 3076                            snapshot.anchor_after(offset + range.start)
 3077                                ..snapshot.anchor_before(offset + range.end),
 3078                            replacement,
 3079                        )
 3080                    }));
 3081                } else if range.end == range.start {
 3082                    let anchor = snapshot.anchor_after(range.start);
 3083                    edits.push((anchor..anchor, new_text.into()));
 3084                } else {
 3085                    let edit_start = snapshot.anchor_after(range.start);
 3086                    let edit_end = snapshot.anchor_before(range.end);
 3087                    edits.push((edit_start..edit_end, new_text.into()));
 3088                }
 3089            }
 3090
 3091            Ok(edits)
 3092        })
 3093    }
 3094
 3095    pub(crate) async fn deserialize_workspace_edit(
 3096        this: Entity<LspStore>,
 3097        edit: lsp::WorkspaceEdit,
 3098        push_to_history: bool,
 3099        language_server: Arc<LanguageServer>,
 3100        cx: &mut AsyncApp,
 3101    ) -> Result<ProjectTransaction> {
 3102        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone());
 3103
 3104        let mut operations = Vec::new();
 3105        if let Some(document_changes) = edit.document_changes {
 3106            match document_changes {
 3107                lsp::DocumentChanges::Edits(edits) => {
 3108                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 3109                }
 3110                lsp::DocumentChanges::Operations(ops) => operations = ops,
 3111            }
 3112        } else if let Some(changes) = edit.changes {
 3113            operations.extend(changes.into_iter().map(|(uri, edits)| {
 3114                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 3115                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 3116                        uri,
 3117                        version: None,
 3118                    },
 3119                    edits: edits.into_iter().map(Edit::Plain).collect(),
 3120                })
 3121            }));
 3122        }
 3123
 3124        let mut project_transaction = ProjectTransaction::default();
 3125        for operation in operations {
 3126            match operation {
 3127                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 3128                    let abs_path = op
 3129                        .uri
 3130                        .to_file_path()
 3131                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3132
 3133                    if let Some(parent_path) = abs_path.parent() {
 3134                        fs.create_dir(parent_path).await?;
 3135                    }
 3136                    if abs_path.ends_with("/") {
 3137                        fs.create_dir(&abs_path).await?;
 3138                    } else {
 3139                        fs.create_file(
 3140                            &abs_path,
 3141                            op.options
 3142                                .map(|options| fs::CreateOptions {
 3143                                    overwrite: options.overwrite.unwrap_or(false),
 3144                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3145                                })
 3146                                .unwrap_or_default(),
 3147                        )
 3148                        .await?;
 3149                    }
 3150                }
 3151
 3152                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 3153                    let source_abs_path = op
 3154                        .old_uri
 3155                        .to_file_path()
 3156                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3157                    let target_abs_path = op
 3158                        .new_uri
 3159                        .to_file_path()
 3160                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3161
 3162                    let options = fs::RenameOptions {
 3163                        overwrite: op
 3164                            .options
 3165                            .as_ref()
 3166                            .and_then(|options| options.overwrite)
 3167                            .unwrap_or(false),
 3168                        ignore_if_exists: op
 3169                            .options
 3170                            .as_ref()
 3171                            .and_then(|options| options.ignore_if_exists)
 3172                            .unwrap_or(false),
 3173                        create_parents: true,
 3174                    };
 3175
 3176                    fs.rename(&source_abs_path, &target_abs_path, options)
 3177                        .await?;
 3178                }
 3179
 3180                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3181                    let abs_path = op
 3182                        .uri
 3183                        .to_file_path()
 3184                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3185                    let options = op
 3186                        .options
 3187                        .map(|options| fs::RemoveOptions {
 3188                            recursive: options.recursive.unwrap_or(false),
 3189                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3190                        })
 3191                        .unwrap_or_default();
 3192                    if abs_path.ends_with("/") {
 3193                        fs.remove_dir(&abs_path, options).await?;
 3194                    } else {
 3195                        fs.remove_file(&abs_path, options).await?;
 3196                    }
 3197                }
 3198
 3199                lsp::DocumentChangeOperation::Edit(op) => {
 3200                    let buffer_to_edit = this
 3201                        .update(cx, |this, cx| {
 3202                            this.open_local_buffer_via_lsp(
 3203                                op.text_document.uri.clone(),
 3204                                language_server.server_id(),
 3205                                cx,
 3206                            )
 3207                        })
 3208                        .await?;
 3209
 3210                    let edits = this
 3211                        .update(cx, |this, cx| {
 3212                            let path = buffer_to_edit.read(cx).project_path(cx);
 3213                            let active_entry = this.active_entry;
 3214                            let is_active_entry = path.is_some_and(|project_path| {
 3215                                this.worktree_store
 3216                                    .read(cx)
 3217                                    .entry_for_path(&project_path, cx)
 3218                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3219                            });
 3220                            let local = this.as_local_mut().unwrap();
 3221
 3222                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3223                            for edit in op.edits {
 3224                                match edit {
 3225                                    Edit::Plain(edit) => {
 3226                                        if !edits.contains(&edit) {
 3227                                            edits.push(edit)
 3228                                        }
 3229                                    }
 3230                                    Edit::Annotated(edit) => {
 3231                                        if !edits.contains(&edit.text_edit) {
 3232                                            edits.push(edit.text_edit)
 3233                                        }
 3234                                    }
 3235                                    Edit::Snippet(edit) => {
 3236                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3237                                        else {
 3238                                            continue;
 3239                                        };
 3240
 3241                                        if is_active_entry {
 3242                                            snippet_edits.push((edit.range, snippet));
 3243                                        } else {
 3244                                            // Since this buffer is not focused, apply a normal edit.
 3245                                            let new_edit = TextEdit {
 3246                                                range: edit.range,
 3247                                                new_text: snippet.text,
 3248                                            };
 3249                                            if !edits.contains(&new_edit) {
 3250                                                edits.push(new_edit);
 3251                                            }
 3252                                        }
 3253                                    }
 3254                                }
 3255                            }
 3256                            if !snippet_edits.is_empty() {
 3257                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3258                                let version = if let Some(buffer_version) = op.text_document.version
 3259                                {
 3260                                    local
 3261                                        .buffer_snapshot_for_lsp_version(
 3262                                            &buffer_to_edit,
 3263                                            language_server.server_id(),
 3264                                            Some(buffer_version),
 3265                                            cx,
 3266                                        )
 3267                                        .ok()
 3268                                        .map(|snapshot| snapshot.version)
 3269                                } else {
 3270                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3271                                };
 3272
 3273                                let most_recent_edit =
 3274                                    version.and_then(|version| version.most_recent());
 3275                                // Check if the edit that triggered that edit has been made by this participant.
 3276
 3277                                if let Some(most_recent_edit) = most_recent_edit {
 3278                                    cx.emit(LspStoreEvent::SnippetEdit {
 3279                                        buffer_id,
 3280                                        edits: snippet_edits,
 3281                                        most_recent_edit,
 3282                                    });
 3283                                }
 3284                            }
 3285
 3286                            local.edits_from_lsp(
 3287                                &buffer_to_edit,
 3288                                edits,
 3289                                language_server.server_id(),
 3290                                op.text_document.version,
 3291                                cx,
 3292                            )
 3293                        })
 3294                        .await?;
 3295
 3296                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3297                        buffer.finalize_last_transaction();
 3298                        buffer.start_transaction();
 3299                        for (range, text) in edits {
 3300                            buffer.edit([(range, text)], None, cx);
 3301                        }
 3302
 3303                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3304                            if push_to_history {
 3305                                buffer.finalize_last_transaction();
 3306                                buffer.get_transaction(transaction_id).cloned()
 3307                            } else {
 3308                                buffer.forget_transaction(transaction_id)
 3309                            }
 3310                        })
 3311                    });
 3312                    if let Some(transaction) = transaction {
 3313                        project_transaction.0.insert(buffer_to_edit, transaction);
 3314                    }
 3315                }
 3316            }
 3317        }
 3318
 3319        Ok(project_transaction)
 3320    }
 3321
 3322    async fn on_lsp_workspace_edit(
 3323        this: WeakEntity<LspStore>,
 3324        params: lsp::ApplyWorkspaceEditParams,
 3325        server_id: LanguageServerId,
 3326        cx: &mut AsyncApp,
 3327    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3328        let this = this.upgrade().context("project project closed")?;
 3329        let language_server = this
 3330            .read_with(cx, |this, _| this.language_server_for_id(server_id))
 3331            .context("language server not found")?;
 3332        let transaction = Self::deserialize_workspace_edit(
 3333            this.clone(),
 3334            params.edit,
 3335            true,
 3336            language_server.clone(),
 3337            cx,
 3338        )
 3339        .await
 3340        .log_err();
 3341        this.update(cx, |this, cx| {
 3342            if let Some(transaction) = transaction {
 3343                cx.emit(LspStoreEvent::WorkspaceEditApplied(transaction.clone()));
 3344
 3345                this.as_local_mut()
 3346                    .unwrap()
 3347                    .last_workspace_edits_by_language_server
 3348                    .insert(server_id, transaction);
 3349            }
 3350        });
 3351        Ok(lsp::ApplyWorkspaceEditResponse {
 3352            applied: true,
 3353            failed_change: None,
 3354            failure_reason: None,
 3355        })
 3356    }
 3357
 3358    fn remove_worktree(
 3359        &mut self,
 3360        id_to_remove: WorktreeId,
 3361        cx: &mut Context<LspStore>,
 3362    ) -> Vec<LanguageServerId> {
 3363        self.restricted_worktrees_tasks.remove(&id_to_remove);
 3364        self.diagnostics.remove(&id_to_remove);
 3365        self.prettier_store.update(cx, |prettier_store, cx| {
 3366            prettier_store.remove_worktree(id_to_remove, cx);
 3367        });
 3368
 3369        let mut servers_to_remove = BTreeSet::default();
 3370        let mut servers_to_preserve = HashSet::default();
 3371        for (seed, state) in &self.language_server_ids {
 3372            if seed.worktree_id == id_to_remove {
 3373                servers_to_remove.insert(state.id);
 3374            } else {
 3375                servers_to_preserve.insert(state.id);
 3376            }
 3377        }
 3378        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3379        self.language_server_ids
 3380            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3381        for server_id_to_remove in &servers_to_remove {
 3382            self.language_server_watched_paths
 3383                .remove(server_id_to_remove);
 3384            self.language_server_paths_watched_for_rename
 3385                .remove(server_id_to_remove);
 3386            self.last_workspace_edits_by_language_server
 3387                .remove(server_id_to_remove);
 3388            self.language_servers.remove(server_id_to_remove);
 3389            self.buffer_pull_diagnostics_result_ids
 3390                .remove(server_id_to_remove);
 3391            self.workspace_pull_diagnostics_result_ids
 3392                .remove(server_id_to_remove);
 3393            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3394                buffer_servers.remove(server_id_to_remove);
 3395            }
 3396            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3397        }
 3398        servers_to_remove.into_iter().collect()
 3399    }
 3400
 3401    fn rebuild_watched_paths_inner<'a>(
 3402        &'a self,
 3403        language_server_id: LanguageServerId,
 3404        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3405        cx: &mut Context<LspStore>,
 3406    ) -> LanguageServerWatchedPathsBuilder {
 3407        let worktrees = self
 3408            .worktree_store
 3409            .read(cx)
 3410            .worktrees()
 3411            .filter_map(|worktree| {
 3412                self.language_servers_for_worktree(worktree.read(cx).id())
 3413                    .find(|server| server.server_id() == language_server_id)
 3414                    .map(|_| worktree)
 3415            })
 3416            .collect::<Vec<_>>();
 3417
 3418        let mut worktree_globs = HashMap::default();
 3419        let mut abs_globs = HashMap::default();
 3420        log::trace!(
 3421            "Processing new watcher paths for language server with id {}",
 3422            language_server_id
 3423        );
 3424
 3425        for watcher in watchers {
 3426            if let Some((worktree, literal_prefix, pattern)) =
 3427                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3428            {
 3429                worktree.update(cx, |worktree, _| {
 3430                    if let Some((tree, glob)) =
 3431                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3432                    {
 3433                        tree.add_path_prefix_to_scan(literal_prefix);
 3434                        worktree_globs
 3435                            .entry(tree.id())
 3436                            .or_insert_with(GlobSetBuilder::new)
 3437                            .add(glob);
 3438                    }
 3439                });
 3440            } else {
 3441                let (path, pattern) = match &watcher.glob_pattern {
 3442                    lsp::GlobPattern::String(s) => {
 3443                        let watcher_path = SanitizedPath::new(s);
 3444                        let path = glob_literal_prefix(watcher_path.as_path());
 3445                        let pattern = watcher_path
 3446                            .as_path()
 3447                            .strip_prefix(&path)
 3448                            .map(|p| p.to_string_lossy().into_owned())
 3449                            .unwrap_or_else(|e| {
 3450                                debug_panic!(
 3451                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3452                                    s,
 3453                                    path.display(),
 3454                                    e
 3455                                );
 3456                                watcher_path.as_path().to_string_lossy().into_owned()
 3457                            });
 3458                        (path, pattern)
 3459                    }
 3460                    lsp::GlobPattern::Relative(rp) => {
 3461                        let Ok(mut base_uri) = match &rp.base_uri {
 3462                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3463                            lsp::OneOf::Right(base_uri) => base_uri,
 3464                        }
 3465                        .to_file_path() else {
 3466                            continue;
 3467                        };
 3468
 3469                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3470                        let pattern = Path::new(&rp.pattern)
 3471                            .strip_prefix(&path)
 3472                            .map(|p| p.to_string_lossy().into_owned())
 3473                            .unwrap_or_else(|e| {
 3474                                debug_panic!(
 3475                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3476                                    rp.pattern,
 3477                                    path.display(),
 3478                                    e
 3479                                );
 3480                                rp.pattern.clone()
 3481                            });
 3482                        base_uri.push(path);
 3483                        (base_uri, pattern)
 3484                    }
 3485                };
 3486
 3487                if let Some(glob) = Glob::new(&pattern).log_err() {
 3488                    if !path
 3489                        .components()
 3490                        .any(|c| matches!(c, path::Component::Normal(_)))
 3491                    {
 3492                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3493                        // rather than adding a new watcher for `/`.
 3494                        for worktree in &worktrees {
 3495                            worktree_globs
 3496                                .entry(worktree.read(cx).id())
 3497                                .or_insert_with(GlobSetBuilder::new)
 3498                                .add(glob.clone());
 3499                        }
 3500                    } else {
 3501                        abs_globs
 3502                            .entry(path.into())
 3503                            .or_insert_with(GlobSetBuilder::new)
 3504                            .add(glob);
 3505                    }
 3506                }
 3507            }
 3508        }
 3509
 3510        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3511        for (worktree_id, builder) in worktree_globs {
 3512            if let Ok(globset) = builder.build() {
 3513                watch_builder.watch_worktree(worktree_id, globset);
 3514            }
 3515        }
 3516        for (abs_path, builder) in abs_globs {
 3517            if let Ok(globset) = builder.build() {
 3518                watch_builder.watch_abs_path(abs_path, globset);
 3519            }
 3520        }
 3521        watch_builder
 3522    }
 3523
 3524    fn worktree_and_path_for_file_watcher(
 3525        worktrees: &[Entity<Worktree>],
 3526        watcher: &FileSystemWatcher,
 3527        cx: &App,
 3528    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3529        worktrees.iter().find_map(|worktree| {
 3530            let tree = worktree.read(cx);
 3531            let worktree_root_path = tree.abs_path();
 3532            let path_style = tree.path_style();
 3533            match &watcher.glob_pattern {
 3534                lsp::GlobPattern::String(s) => {
 3535                    let watcher_path = SanitizedPath::new(s);
 3536                    let relative = watcher_path
 3537                        .as_path()
 3538                        .strip_prefix(&worktree_root_path)
 3539                        .ok()?;
 3540                    let literal_prefix = glob_literal_prefix(relative);
 3541                    Some((
 3542                        worktree.clone(),
 3543                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3544                        relative.to_string_lossy().into_owned(),
 3545                    ))
 3546                }
 3547                lsp::GlobPattern::Relative(rp) => {
 3548                    let base_uri = match &rp.base_uri {
 3549                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3550                        lsp::OneOf::Right(base_uri) => base_uri,
 3551                    }
 3552                    .to_file_path()
 3553                    .ok()?;
 3554                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3555                    let mut literal_prefix = relative.to_owned();
 3556                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3557                    Some((
 3558                        worktree.clone(),
 3559                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3560                        rp.pattern.clone(),
 3561                    ))
 3562                }
 3563            }
 3564        })
 3565    }
 3566
 3567    fn rebuild_watched_paths(
 3568        &mut self,
 3569        language_server_id: LanguageServerId,
 3570        cx: &mut Context<LspStore>,
 3571    ) {
 3572        let Some(registrations) = self
 3573            .language_server_dynamic_registrations
 3574            .get(&language_server_id)
 3575        else {
 3576            return;
 3577        };
 3578
 3579        let watch_builder = self.rebuild_watched_paths_inner(
 3580            language_server_id,
 3581            registrations.did_change_watched_files.values().flatten(),
 3582            cx,
 3583        );
 3584        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3585        self.language_server_watched_paths
 3586            .insert(language_server_id, watcher);
 3587
 3588        cx.notify();
 3589    }
 3590
 3591    fn on_lsp_did_change_watched_files(
 3592        &mut self,
 3593        language_server_id: LanguageServerId,
 3594        registration_id: &str,
 3595        params: DidChangeWatchedFilesRegistrationOptions,
 3596        cx: &mut Context<LspStore>,
 3597    ) {
 3598        let registrations = self
 3599            .language_server_dynamic_registrations
 3600            .entry(language_server_id)
 3601            .or_default();
 3602
 3603        registrations
 3604            .did_change_watched_files
 3605            .insert(registration_id.to_string(), params.watchers);
 3606
 3607        self.rebuild_watched_paths(language_server_id, cx);
 3608    }
 3609
 3610    fn on_lsp_unregister_did_change_watched_files(
 3611        &mut self,
 3612        language_server_id: LanguageServerId,
 3613        registration_id: &str,
 3614        cx: &mut Context<LspStore>,
 3615    ) {
 3616        let registrations = self
 3617            .language_server_dynamic_registrations
 3618            .entry(language_server_id)
 3619            .or_default();
 3620
 3621        if registrations
 3622            .did_change_watched_files
 3623            .remove(registration_id)
 3624            .is_some()
 3625        {
 3626            log::info!(
 3627                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3628                language_server_id,
 3629                registration_id
 3630            );
 3631        } else {
 3632            log::warn!(
 3633                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3634                language_server_id,
 3635                registration_id
 3636            );
 3637        }
 3638
 3639        self.rebuild_watched_paths(language_server_id, cx);
 3640    }
 3641
 3642    async fn initialization_options_for_adapter(
 3643        adapter: Arc<dyn LspAdapter>,
 3644        delegate: &Arc<dyn LspAdapterDelegate>,
 3645    ) -> Result<Option<serde_json::Value>> {
 3646        let Some(mut initialization_config) =
 3647            adapter.clone().initialization_options(delegate).await?
 3648        else {
 3649            return Ok(None);
 3650        };
 3651
 3652        for other_adapter in delegate.registered_lsp_adapters() {
 3653            if other_adapter.name() == adapter.name() {
 3654                continue;
 3655            }
 3656            if let Ok(Some(target_config)) = other_adapter
 3657                .clone()
 3658                .additional_initialization_options(adapter.name(), delegate)
 3659                .await
 3660            {
 3661                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3662            }
 3663        }
 3664
 3665        Ok(Some(initialization_config))
 3666    }
 3667
 3668    async fn workspace_configuration_for_adapter(
 3669        adapter: Arc<dyn LspAdapter>,
 3670        delegate: &Arc<dyn LspAdapterDelegate>,
 3671        toolchain: Option<Toolchain>,
 3672        requested_uri: Option<Uri>,
 3673        cx: &mut AsyncApp,
 3674    ) -> Result<serde_json::Value> {
 3675        let mut workspace_config = adapter
 3676            .clone()
 3677            .workspace_configuration(delegate, toolchain, requested_uri, cx)
 3678            .await?;
 3679
 3680        for other_adapter in delegate.registered_lsp_adapters() {
 3681            if other_adapter.name() == adapter.name() {
 3682                continue;
 3683            }
 3684            if let Ok(Some(target_config)) = other_adapter
 3685                .clone()
 3686                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3687                .await
 3688            {
 3689                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3690            }
 3691        }
 3692
 3693        Ok(workspace_config)
 3694    }
 3695
 3696    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3697        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3698            Some(server.clone())
 3699        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3700            Some(Arc::clone(server))
 3701        } else {
 3702            None
 3703        }
 3704    }
 3705}
 3706
 3707fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3708    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3709        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3710            language_server_id: server.server_id(),
 3711            name: Some(server.name()),
 3712            message: proto::update_language_server::Variant::MetadataUpdated(
 3713                proto::ServerMetadataUpdated {
 3714                    capabilities: Some(capabilities),
 3715                    binary: Some(proto::LanguageServerBinaryInfo {
 3716                        path: server.binary().path.to_string_lossy().into_owned(),
 3717                        arguments: server
 3718                            .binary()
 3719                            .arguments
 3720                            .iter()
 3721                            .map(|arg| arg.to_string_lossy().into_owned())
 3722                            .collect(),
 3723                    }),
 3724                    configuration: serde_json::to_string(server.configuration()).ok(),
 3725                    workspace_folders: server
 3726                        .workspace_folders()
 3727                        .iter()
 3728                        .map(|uri| uri.to_string())
 3729                        .collect(),
 3730                },
 3731            ),
 3732        });
 3733    }
 3734}
 3735
 3736#[derive(Debug)]
 3737pub struct FormattableBuffer {
 3738    handle: Entity<Buffer>,
 3739    abs_path: Option<PathBuf>,
 3740    env: Option<HashMap<String, String>>,
 3741    ranges: Option<Vec<Range<Anchor>>>,
 3742}
 3743
 3744pub struct RemoteLspStore {
 3745    upstream_client: Option<AnyProtoClient>,
 3746    upstream_project_id: u64,
 3747}
 3748
 3749pub(crate) enum LspStoreMode {
 3750    Local(LocalLspStore),   // ssh host and collab host
 3751    Remote(RemoteLspStore), // collab guest
 3752}
 3753
 3754impl LspStoreMode {
 3755    fn is_local(&self) -> bool {
 3756        matches!(self, LspStoreMode::Local(_))
 3757    }
 3758}
 3759
 3760pub struct LspStore {
 3761    mode: LspStoreMode,
 3762    last_formatting_failure: Option<String>,
 3763    downstream_client: Option<(AnyProtoClient, u64)>,
 3764    nonce: u128,
 3765    buffer_store: Entity<BufferStore>,
 3766    worktree_store: Entity<WorktreeStore>,
 3767    pub languages: Arc<LanguageRegistry>,
 3768    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3769    active_entry: Option<ProjectEntryId>,
 3770    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3771    _maintain_buffer_languages: Task<()>,
 3772    diagnostic_summaries:
 3773        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3774    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3775    lsp_data: HashMap<BufferId, BufferLspData>,
 3776    next_hint_id: Arc<AtomicUsize>,
 3777}
 3778
 3779#[derive(Debug)]
 3780pub struct BufferLspData {
 3781    buffer_version: Global,
 3782    document_colors: Option<DocumentColorData>,
 3783    code_lens: Option<CodeLensData>,
 3784    inlay_hints: BufferInlayHints,
 3785    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3786    chunk_lsp_requests: HashMap<LspKey, HashMap<RowChunk, LspRequestId>>,
 3787}
 3788
 3789#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3790struct LspKey {
 3791    request_type: TypeId,
 3792    server_queried: Option<LanguageServerId>,
 3793}
 3794
 3795impl BufferLspData {
 3796    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3797        Self {
 3798            buffer_version: buffer.read(cx).version(),
 3799            document_colors: None,
 3800            code_lens: None,
 3801            inlay_hints: BufferInlayHints::new(buffer, cx),
 3802            lsp_requests: HashMap::default(),
 3803            chunk_lsp_requests: HashMap::default(),
 3804        }
 3805    }
 3806
 3807    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3808        if let Some(document_colors) = &mut self.document_colors {
 3809            document_colors.colors.remove(&for_server);
 3810            document_colors.cache_version += 1;
 3811        }
 3812
 3813        if let Some(code_lens) = &mut self.code_lens {
 3814            code_lens.lens.remove(&for_server);
 3815        }
 3816
 3817        self.inlay_hints.remove_server_data(for_server);
 3818    }
 3819
 3820    #[cfg(any(test, feature = "test-support"))]
 3821    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3822        &self.inlay_hints
 3823    }
 3824}
 3825
 3826#[derive(Debug, Default, Clone)]
 3827pub struct DocumentColors {
 3828    pub colors: HashSet<DocumentColor>,
 3829    pub cache_version: Option<usize>,
 3830}
 3831
 3832type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3833type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3834
 3835#[derive(Debug, Default)]
 3836struct DocumentColorData {
 3837    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3838    cache_version: usize,
 3839    colors_update: Option<(Global, DocumentColorTask)>,
 3840}
 3841
 3842#[derive(Debug, Default)]
 3843struct CodeLensData {
 3844    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3845    update: Option<(Global, CodeLensTask)>,
 3846}
 3847
 3848#[derive(Debug)]
 3849pub enum LspStoreEvent {
 3850    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3851    LanguageServerRemoved(LanguageServerId),
 3852    LanguageServerUpdate {
 3853        language_server_id: LanguageServerId,
 3854        name: Option<LanguageServerName>,
 3855        message: proto::update_language_server::Variant,
 3856    },
 3857    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3858    LanguageServerPrompt(LanguageServerPromptRequest),
 3859    LanguageDetected {
 3860        buffer: Entity<Buffer>,
 3861        new_language: Option<Arc<Language>>,
 3862    },
 3863    Notification(String),
 3864    RefreshInlayHints {
 3865        server_id: LanguageServerId,
 3866        request_id: Option<usize>,
 3867    },
 3868    RefreshCodeLens,
 3869    DiagnosticsUpdated {
 3870        server_id: LanguageServerId,
 3871        paths: Vec<ProjectPath>,
 3872    },
 3873    DiskBasedDiagnosticsStarted {
 3874        language_server_id: LanguageServerId,
 3875    },
 3876    DiskBasedDiagnosticsFinished {
 3877        language_server_id: LanguageServerId,
 3878    },
 3879    SnippetEdit {
 3880        buffer_id: BufferId,
 3881        edits: Vec<(lsp::Range, Snippet)>,
 3882        most_recent_edit: clock::Lamport,
 3883    },
 3884    WorkspaceEditApplied(ProjectTransaction),
 3885}
 3886
 3887#[derive(Clone, Debug, Serialize)]
 3888pub struct LanguageServerStatus {
 3889    pub name: LanguageServerName,
 3890    pub server_version: Option<SharedString>,
 3891    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 3892    pub has_pending_diagnostic_updates: bool,
 3893    pub progress_tokens: HashSet<ProgressToken>,
 3894    pub worktree: Option<WorktreeId>,
 3895    pub binary: Option<LanguageServerBinary>,
 3896    pub configuration: Option<Value>,
 3897    pub workspace_folders: BTreeSet<Uri>,
 3898}
 3899
 3900#[derive(Clone, Debug)]
 3901struct CoreSymbol {
 3902    pub language_server_name: LanguageServerName,
 3903    pub source_worktree_id: WorktreeId,
 3904    pub source_language_server_id: LanguageServerId,
 3905    pub path: SymbolLocation,
 3906    pub name: String,
 3907    pub kind: lsp::SymbolKind,
 3908    pub range: Range<Unclipped<PointUtf16>>,
 3909}
 3910
 3911#[derive(Clone, Debug, PartialEq, Eq)]
 3912pub enum SymbolLocation {
 3913    InProject(ProjectPath),
 3914    OutsideProject {
 3915        abs_path: Arc<Path>,
 3916        signature: [u8; 32],
 3917    },
 3918}
 3919
 3920impl SymbolLocation {
 3921    fn file_name(&self) -> Option<&str> {
 3922        match self {
 3923            Self::InProject(path) => path.path.file_name(),
 3924            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3925        }
 3926    }
 3927}
 3928
 3929impl LspStore {
 3930    pub fn init(client: &AnyProtoClient) {
 3931        client.add_entity_request_handler(Self::handle_lsp_query);
 3932        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3933        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3934        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3935        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3936        client.add_entity_message_handler(Self::handle_start_language_server);
 3937        client.add_entity_message_handler(Self::handle_update_language_server);
 3938        client.add_entity_message_handler(Self::handle_language_server_log);
 3939        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3940        client.add_entity_request_handler(Self::handle_format_buffers);
 3941        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3942        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3943        client.add_entity_request_handler(Self::handle_apply_code_action);
 3944        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3945        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3946        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3947        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3948        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3949        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3950        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3951        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3952        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3953        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3954        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3955        client.add_entity_request_handler(Self::handle_lsp_get_completions);
 3956        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3957        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3958        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3959        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3960        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3961
 3962        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3963        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3964        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3965        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3966        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3967        client.add_entity_request_handler(
 3968            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3969        );
 3970        client.add_entity_request_handler(
 3971            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3972        );
 3973        client.add_entity_request_handler(
 3974            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3975        );
 3976    }
 3977
 3978    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3979        match &self.mode {
 3980            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3981            _ => None,
 3982        }
 3983    }
 3984
 3985    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3986        match &self.mode {
 3987            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3988            _ => None,
 3989        }
 3990    }
 3991
 3992    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3993        match &mut self.mode {
 3994            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3995            _ => None,
 3996        }
 3997    }
 3998
 3999    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 4000        match &self.mode {
 4001            LspStoreMode::Remote(RemoteLspStore {
 4002                upstream_client: Some(upstream_client),
 4003                upstream_project_id,
 4004                ..
 4005            }) => Some((upstream_client.clone(), *upstream_project_id)),
 4006
 4007            LspStoreMode::Remote(RemoteLspStore {
 4008                upstream_client: None,
 4009                ..
 4010            }) => None,
 4011            LspStoreMode::Local(_) => None,
 4012        }
 4013    }
 4014
 4015    pub fn new_local(
 4016        buffer_store: Entity<BufferStore>,
 4017        worktree_store: Entity<WorktreeStore>,
 4018        prettier_store: Entity<PrettierStore>,
 4019        toolchain_store: Entity<LocalToolchainStore>,
 4020        environment: Entity<ProjectEnvironment>,
 4021        manifest_tree: Entity<ManifestTree>,
 4022        languages: Arc<LanguageRegistry>,
 4023        http_client: Arc<dyn HttpClient>,
 4024        fs: Arc<dyn Fs>,
 4025        cx: &mut Context<Self>,
 4026    ) -> Self {
 4027        let yarn = YarnPathStore::new(fs.clone(), cx);
 4028        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4029            .detach();
 4030        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4031            .detach();
 4032        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 4033            .detach();
 4034        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 4035            .detach();
 4036        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 4037            .detach();
 4038        subscribe_to_binary_statuses(&languages, cx).detach();
 4039
 4040        let _maintain_workspace_config = {
 4041            let (sender, receiver) = watch::channel();
 4042            (Self::maintain_workspace_config(receiver, cx), sender)
 4043        };
 4044
 4045        Self {
 4046            mode: LspStoreMode::Local(LocalLspStore {
 4047                weak: cx.weak_entity(),
 4048                worktree_store: worktree_store.clone(),
 4049
 4050                supplementary_language_servers: Default::default(),
 4051                languages: languages.clone(),
 4052                language_server_ids: Default::default(),
 4053                language_servers: Default::default(),
 4054                last_workspace_edits_by_language_server: Default::default(),
 4055                language_server_watched_paths: Default::default(),
 4056                language_server_paths_watched_for_rename: Default::default(),
 4057                language_server_dynamic_registrations: Default::default(),
 4058                buffers_being_formatted: Default::default(),
 4059                buffers_to_refresh_hash_set: HashSet::default(),
 4060                buffers_to_refresh_queue: VecDeque::new(),
 4061                _background_diagnostics_worker: Task::ready(()).shared(),
 4062                buffer_snapshots: Default::default(),
 4063                prettier_store,
 4064                environment,
 4065                http_client,
 4066                fs,
 4067                yarn,
 4068                next_diagnostic_group_id: Default::default(),
 4069                diagnostics: Default::default(),
 4070                _subscription: cx.on_app_quit(|this, cx| {
 4071                    this.as_local_mut()
 4072                        .unwrap()
 4073                        .shutdown_language_servers_on_quit(cx)
 4074                }),
 4075                lsp_tree: LanguageServerTree::new(
 4076                    manifest_tree,
 4077                    languages.clone(),
 4078                    toolchain_store.clone(),
 4079                ),
 4080                toolchain_store,
 4081                registered_buffers: HashMap::default(),
 4082                buffers_opened_in_servers: HashMap::default(),
 4083                buffer_pull_diagnostics_result_ids: HashMap::default(),
 4084                workspace_pull_diagnostics_result_ids: HashMap::default(),
 4085                restricted_worktrees_tasks: HashMap::default(),
 4086                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 4087                    .manifest_file_names(),
 4088            }),
 4089            last_formatting_failure: None,
 4090            downstream_client: None,
 4091            buffer_store,
 4092            worktree_store,
 4093            languages: languages.clone(),
 4094            language_server_statuses: Default::default(),
 4095            nonce: StdRng::from_os_rng().random(),
 4096            diagnostic_summaries: HashMap::default(),
 4097            lsp_server_capabilities: HashMap::default(),
 4098            lsp_data: HashMap::default(),
 4099            next_hint_id: Arc::default(),
 4100            active_entry: None,
 4101            _maintain_workspace_config,
 4102            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 4103        }
 4104    }
 4105
 4106    fn send_lsp_proto_request<R: LspCommand>(
 4107        &self,
 4108        buffer: Entity<Buffer>,
 4109        client: AnyProtoClient,
 4110        upstream_project_id: u64,
 4111        request: R,
 4112        cx: &mut Context<LspStore>,
 4113    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 4114        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 4115            return Task::ready(Ok(R::Response::default()));
 4116        }
 4117        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 4118        cx.spawn(async move |this, cx| {
 4119            let response = client.request(message).await?;
 4120            let this = this.upgrade().context("project dropped")?;
 4121            request
 4122                .response_from_proto(response, this, buffer, cx.clone())
 4123                .await
 4124        })
 4125    }
 4126
 4127    pub(super) fn new_remote(
 4128        buffer_store: Entity<BufferStore>,
 4129        worktree_store: Entity<WorktreeStore>,
 4130        languages: Arc<LanguageRegistry>,
 4131        upstream_client: AnyProtoClient,
 4132        project_id: u64,
 4133        cx: &mut Context<Self>,
 4134    ) -> Self {
 4135        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 4136            .detach();
 4137        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 4138            .detach();
 4139        subscribe_to_binary_statuses(&languages, cx).detach();
 4140        let _maintain_workspace_config = {
 4141            let (sender, receiver) = watch::channel();
 4142            (Self::maintain_workspace_config(receiver, cx), sender)
 4143        };
 4144        Self {
 4145            mode: LspStoreMode::Remote(RemoteLspStore {
 4146                upstream_client: Some(upstream_client),
 4147                upstream_project_id: project_id,
 4148            }),
 4149            downstream_client: None,
 4150            last_formatting_failure: None,
 4151            buffer_store,
 4152            worktree_store,
 4153            languages: languages.clone(),
 4154            language_server_statuses: Default::default(),
 4155            nonce: StdRng::from_os_rng().random(),
 4156            diagnostic_summaries: HashMap::default(),
 4157            lsp_server_capabilities: HashMap::default(),
 4158            next_hint_id: Arc::default(),
 4159            lsp_data: HashMap::default(),
 4160            active_entry: None,
 4161
 4162            _maintain_workspace_config,
 4163            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 4164        }
 4165    }
 4166
 4167    fn on_buffer_store_event(
 4168        &mut self,
 4169        _: Entity<BufferStore>,
 4170        event: &BufferStoreEvent,
 4171        cx: &mut Context<Self>,
 4172    ) {
 4173        match event {
 4174            BufferStoreEvent::BufferAdded(buffer) => {
 4175                self.on_buffer_added(buffer, cx).log_err();
 4176            }
 4177            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 4178                let buffer_id = buffer.read(cx).remote_id();
 4179                if let Some(local) = self.as_local_mut()
 4180                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 4181                {
 4182                    local.reset_buffer(buffer, old_file, cx);
 4183
 4184                    if local.registered_buffers.contains_key(&buffer_id) {
 4185                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 4186                    }
 4187                }
 4188
 4189                self.detect_language_for_buffer(buffer, cx);
 4190                if let Some(local) = self.as_local_mut() {
 4191                    local.initialize_buffer(buffer, cx);
 4192                    if local.registered_buffers.contains_key(&buffer_id) {
 4193                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 4194                    }
 4195                }
 4196            }
 4197            _ => {}
 4198        }
 4199    }
 4200
 4201    fn on_worktree_store_event(
 4202        &mut self,
 4203        _: Entity<WorktreeStore>,
 4204        event: &WorktreeStoreEvent,
 4205        cx: &mut Context<Self>,
 4206    ) {
 4207        match event {
 4208            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4209                if !worktree.read(cx).is_local() {
 4210                    return;
 4211                }
 4212                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4213                    worktree::Event::UpdatedEntries(changes) => {
 4214                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4215                    }
 4216                    worktree::Event::UpdatedGitRepositories(_)
 4217                    | worktree::Event::DeletedEntry(_) => {}
 4218                })
 4219                .detach()
 4220            }
 4221            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4222            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4223                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4224            }
 4225            WorktreeStoreEvent::WorktreeReleased(..)
 4226            | WorktreeStoreEvent::WorktreeOrderChanged
 4227            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4228            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4229            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4230        }
 4231    }
 4232
 4233    fn on_prettier_store_event(
 4234        &mut self,
 4235        _: Entity<PrettierStore>,
 4236        event: &PrettierStoreEvent,
 4237        cx: &mut Context<Self>,
 4238    ) {
 4239        match event {
 4240            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4241                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4242            }
 4243            PrettierStoreEvent::LanguageServerAdded {
 4244                new_server_id,
 4245                name,
 4246                prettier_server,
 4247            } => {
 4248                self.register_supplementary_language_server(
 4249                    *new_server_id,
 4250                    name.clone(),
 4251                    prettier_server.clone(),
 4252                    cx,
 4253                );
 4254            }
 4255        }
 4256    }
 4257
 4258    fn on_toolchain_store_event(
 4259        &mut self,
 4260        _: Entity<LocalToolchainStore>,
 4261        event: &ToolchainStoreEvent,
 4262        _: &mut Context<Self>,
 4263    ) {
 4264        if let ToolchainStoreEvent::ToolchainActivated = event {
 4265            self.request_workspace_config_refresh()
 4266        }
 4267    }
 4268
 4269    fn request_workspace_config_refresh(&mut self) {
 4270        *self._maintain_workspace_config.1.borrow_mut() = ();
 4271    }
 4272
 4273    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4274        self.as_local().map(|local| local.prettier_store.clone())
 4275    }
 4276
 4277    fn on_buffer_event(
 4278        &mut self,
 4279        buffer: Entity<Buffer>,
 4280        event: &language::BufferEvent,
 4281        cx: &mut Context<Self>,
 4282    ) {
 4283        match event {
 4284            language::BufferEvent::Edited => {
 4285                self.on_buffer_edited(buffer, cx);
 4286            }
 4287
 4288            language::BufferEvent::Saved => {
 4289                self.on_buffer_saved(buffer, cx);
 4290            }
 4291
 4292            _ => {}
 4293        }
 4294    }
 4295
 4296    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4297        buffer
 4298            .read(cx)
 4299            .set_language_registry(self.languages.clone());
 4300
 4301        cx.subscribe(buffer, |this, buffer, event, cx| {
 4302            this.on_buffer_event(buffer, event, cx);
 4303        })
 4304        .detach();
 4305
 4306        self.detect_language_for_buffer(buffer, cx);
 4307        if let Some(local) = self.as_local_mut() {
 4308            local.initialize_buffer(buffer, cx);
 4309        }
 4310
 4311        Ok(())
 4312    }
 4313
 4314    pub fn refresh_background_diagnostics_for_buffers(
 4315        &mut self,
 4316        buffers: HashSet<BufferId>,
 4317        cx: &mut Context<Self>,
 4318    ) -> Shared<Task<()>> {
 4319        let Some(local) = self.as_local_mut() else {
 4320            return Task::ready(()).shared();
 4321        };
 4322        for buffer in buffers {
 4323            if local.buffers_to_refresh_hash_set.insert(buffer) {
 4324                local.buffers_to_refresh_queue.push_back(buffer);
 4325                if local.buffers_to_refresh_queue.len() == 1 {
 4326                    local._background_diagnostics_worker =
 4327                        Self::background_diagnostics_worker(cx).shared();
 4328                }
 4329            }
 4330        }
 4331
 4332        local._background_diagnostics_worker.clone()
 4333    }
 4334
 4335    fn refresh_next_buffer(&mut self, cx: &mut Context<Self>) -> Option<Task<Result<()>>> {
 4336        let buffer_store = self.buffer_store.clone();
 4337        let local = self.as_local_mut()?;
 4338        while let Some(buffer_id) = local.buffers_to_refresh_queue.pop_front() {
 4339            local.buffers_to_refresh_hash_set.remove(&buffer_id);
 4340            if let Some(buffer) = buffer_store.read(cx).get(buffer_id) {
 4341                return Some(self.pull_diagnostics_for_buffer(buffer, cx));
 4342            }
 4343        }
 4344        None
 4345    }
 4346
 4347    fn background_diagnostics_worker(cx: &mut Context<Self>) -> Task<()> {
 4348        cx.spawn(async move |this, cx| {
 4349            while let Ok(Some(task)) = this.update(cx, |this, cx| this.refresh_next_buffer(cx)) {
 4350                task.await.log_err();
 4351            }
 4352        })
 4353    }
 4354
 4355    pub(crate) fn register_buffer_with_language_servers(
 4356        &mut self,
 4357        buffer: &Entity<Buffer>,
 4358        only_register_servers: HashSet<LanguageServerSelector>,
 4359        ignore_refcounts: bool,
 4360        cx: &mut Context<Self>,
 4361    ) -> OpenLspBufferHandle {
 4362        let buffer_id = buffer.read(cx).remote_id();
 4363        let handle = OpenLspBufferHandle(cx.new(|_| OpenLspBuffer(buffer.clone())));
 4364        if let Some(local) = self.as_local_mut() {
 4365            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4366            if !ignore_refcounts {
 4367                *refcount += 1;
 4368            }
 4369
 4370            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4371            // 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
 4372            // 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
 4373            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4374            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4375                return handle;
 4376            };
 4377            if !file.is_local() {
 4378                return handle;
 4379            }
 4380
 4381            if ignore_refcounts || *refcount == 1 {
 4382                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4383            }
 4384            if !ignore_refcounts {
 4385                cx.observe_release(&handle.0, move |lsp_store, buffer, cx| {
 4386                    let refcount = {
 4387                        let local = lsp_store.as_local_mut().unwrap();
 4388                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4389                            debug_panic!("bad refcounting");
 4390                            return;
 4391                        };
 4392
 4393                        *refcount -= 1;
 4394                        *refcount
 4395                    };
 4396                    if refcount == 0 {
 4397                        lsp_store.lsp_data.remove(&buffer_id);
 4398                        let local = lsp_store.as_local_mut().unwrap();
 4399                        local.registered_buffers.remove(&buffer_id);
 4400
 4401                        local.buffers_opened_in_servers.remove(&buffer_id);
 4402                        if let Some(file) = File::from_dyn(buffer.0.read(cx).file()).cloned() {
 4403                            local.unregister_old_buffer_from_language_servers(&buffer.0, &file, cx);
 4404
 4405                            let buffer_abs_path = file.abs_path(cx);
 4406                            for (_, buffer_pull_diagnostics_result_ids) in
 4407                                &mut local.buffer_pull_diagnostics_result_ids
 4408                            {
 4409                                buffer_pull_diagnostics_result_ids.retain(
 4410                                    |_, buffer_result_ids| {
 4411                                        buffer_result_ids.remove(&buffer_abs_path);
 4412                                        !buffer_result_ids.is_empty()
 4413                                    },
 4414                                );
 4415                            }
 4416
 4417                            let diagnostic_updates = local
 4418                                .language_servers
 4419                                .keys()
 4420                                .cloned()
 4421                                .map(|server_id| DocumentDiagnosticsUpdate {
 4422                                    diagnostics: DocumentDiagnostics {
 4423                                        document_abs_path: buffer_abs_path.clone(),
 4424                                        version: None,
 4425                                        diagnostics: Vec::new(),
 4426                                    },
 4427                                    result_id: None,
 4428                                    registration_id: None,
 4429                                    server_id: server_id,
 4430                                    disk_based_sources: Cow::Borrowed(&[]),
 4431                                })
 4432                                .collect::<Vec<_>>();
 4433
 4434                            lsp_store
 4435                                .merge_diagnostic_entries(
 4436                                    diagnostic_updates,
 4437                                    |_, diagnostic, _| {
 4438                                        diagnostic.source_kind != DiagnosticSourceKind::Pulled
 4439                                    },
 4440                                    cx,
 4441                                )
 4442                                .context("Clearing diagnostics for the closed buffer")
 4443                                .log_err();
 4444                        }
 4445                    }
 4446                })
 4447                .detach();
 4448            }
 4449        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4450            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4451            cx.background_spawn(async move {
 4452                upstream_client
 4453                    .request(proto::RegisterBufferWithLanguageServers {
 4454                        project_id: upstream_project_id,
 4455                        buffer_id,
 4456                        only_servers: only_register_servers
 4457                            .into_iter()
 4458                            .map(|selector| {
 4459                                let selector = match selector {
 4460                                    LanguageServerSelector::Id(language_server_id) => {
 4461                                        proto::language_server_selector::Selector::ServerId(
 4462                                            language_server_id.to_proto(),
 4463                                        )
 4464                                    }
 4465                                    LanguageServerSelector::Name(language_server_name) => {
 4466                                        proto::language_server_selector::Selector::Name(
 4467                                            language_server_name.to_string(),
 4468                                        )
 4469                                    }
 4470                                };
 4471                                proto::LanguageServerSelector {
 4472                                    selector: Some(selector),
 4473                                }
 4474                            })
 4475                            .collect(),
 4476                    })
 4477                    .await
 4478            })
 4479            .detach();
 4480        } else {
 4481            // Our remote connection got closed
 4482        }
 4483        handle
 4484    }
 4485
 4486    fn maintain_buffer_languages(
 4487        languages: Arc<LanguageRegistry>,
 4488        cx: &mut Context<Self>,
 4489    ) -> Task<()> {
 4490        let mut subscription = languages.subscribe();
 4491        let mut prev_reload_count = languages.reload_count();
 4492        cx.spawn(async move |this, cx| {
 4493            while let Some(()) = subscription.next().await {
 4494                if let Some(this) = this.upgrade() {
 4495                    // If the language registry has been reloaded, then remove and
 4496                    // re-assign the languages on all open buffers.
 4497                    let reload_count = languages.reload_count();
 4498                    if reload_count > prev_reload_count {
 4499                        prev_reload_count = reload_count;
 4500                        this.update(cx, |this, cx| {
 4501                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4502                                for buffer in buffer_store.buffers() {
 4503                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4504                                    {
 4505                                        buffer.update(cx, |buffer, cx| {
 4506                                            buffer.set_language_async(None, cx)
 4507                                        });
 4508                                        if let Some(local) = this.as_local_mut() {
 4509                                            local.reset_buffer(&buffer, &f, cx);
 4510
 4511                                            if local
 4512                                                .registered_buffers
 4513                                                .contains_key(&buffer.read(cx).remote_id())
 4514                                                && let Some(file_url) =
 4515                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4516                                            {
 4517                                                local.unregister_buffer_from_language_servers(
 4518                                                    &buffer, &file_url, cx,
 4519                                                );
 4520                                            }
 4521                                        }
 4522                                    }
 4523                                }
 4524                            });
 4525                        });
 4526                    }
 4527
 4528                    this.update(cx, |this, cx| {
 4529                        let mut plain_text_buffers = Vec::new();
 4530                        let mut buffers_with_unknown_injections = Vec::new();
 4531                        for handle in this.buffer_store.read(cx).buffers() {
 4532                            let buffer = handle.read(cx);
 4533                            if buffer.language().is_none()
 4534                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4535                            {
 4536                                plain_text_buffers.push(handle);
 4537                            } else if buffer.contains_unknown_injections() {
 4538                                buffers_with_unknown_injections.push(handle);
 4539                            }
 4540                        }
 4541
 4542                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4543                        // and reused later in the invisible worktrees.
 4544                        plain_text_buffers.sort_by_key(|buffer| {
 4545                            Reverse(
 4546                                File::from_dyn(buffer.read(cx).file())
 4547                                    .map(|file| file.worktree.read(cx).is_visible()),
 4548                            )
 4549                        });
 4550
 4551                        for buffer in plain_text_buffers {
 4552                            this.detect_language_for_buffer(&buffer, cx);
 4553                            if let Some(local) = this.as_local_mut() {
 4554                                local.initialize_buffer(&buffer, cx);
 4555                                if local
 4556                                    .registered_buffers
 4557                                    .contains_key(&buffer.read(cx).remote_id())
 4558                                {
 4559                                    local.register_buffer_with_language_servers(
 4560                                        &buffer,
 4561                                        HashSet::default(),
 4562                                        cx,
 4563                                    );
 4564                                }
 4565                            }
 4566                        }
 4567
 4568                        for buffer in buffers_with_unknown_injections {
 4569                            buffer.update(cx, |buffer, cx| buffer.reparse(cx, false));
 4570                        }
 4571                    });
 4572                }
 4573            }
 4574        })
 4575    }
 4576
 4577    fn detect_language_for_buffer(
 4578        &mut self,
 4579        buffer_handle: &Entity<Buffer>,
 4580        cx: &mut Context<Self>,
 4581    ) -> Option<language::AvailableLanguage> {
 4582        // If the buffer has a language, set it and start the language server if we haven't already.
 4583        let buffer = buffer_handle.read(cx);
 4584        let file = buffer.file()?;
 4585
 4586        let content = buffer.as_rope();
 4587        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4588        if let Some(available_language) = &available_language {
 4589            if let Some(Ok(Ok(new_language))) = self
 4590                .languages
 4591                .load_language(available_language)
 4592                .now_or_never()
 4593            {
 4594                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4595            }
 4596        } else {
 4597            cx.emit(LspStoreEvent::LanguageDetected {
 4598                buffer: buffer_handle.clone(),
 4599                new_language: None,
 4600            });
 4601        }
 4602
 4603        available_language
 4604    }
 4605
 4606    pub(crate) fn set_language_for_buffer(
 4607        &mut self,
 4608        buffer_entity: &Entity<Buffer>,
 4609        new_language: Arc<Language>,
 4610        cx: &mut Context<Self>,
 4611    ) {
 4612        let buffer = buffer_entity.read(cx);
 4613        let buffer_file = buffer.file().cloned();
 4614        let buffer_id = buffer.remote_id();
 4615        if let Some(local_store) = self.as_local_mut()
 4616            && local_store.registered_buffers.contains_key(&buffer_id)
 4617            && let Some(abs_path) =
 4618                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4619            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4620        {
 4621            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4622        }
 4623        buffer_entity.update(cx, |buffer, cx| {
 4624            if buffer
 4625                .language()
 4626                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4627            {
 4628                buffer.set_language_async(Some(new_language.clone()), cx);
 4629            }
 4630        });
 4631
 4632        let settings =
 4633            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4634        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4635
 4636        let worktree_id = if let Some(file) = buffer_file {
 4637            let worktree = file.worktree.clone();
 4638
 4639            if let Some(local) = self.as_local_mut()
 4640                && local.registered_buffers.contains_key(&buffer_id)
 4641            {
 4642                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4643            }
 4644            Some(worktree.read(cx).id())
 4645        } else {
 4646            None
 4647        };
 4648
 4649        if settings.prettier.allowed
 4650            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4651        {
 4652            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4653            if let Some(prettier_store) = prettier_store {
 4654                prettier_store.update(cx, |prettier_store, cx| {
 4655                    prettier_store.install_default_prettier(
 4656                        worktree_id,
 4657                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4658                        cx,
 4659                    )
 4660                })
 4661            }
 4662        }
 4663
 4664        cx.emit(LspStoreEvent::LanguageDetected {
 4665            buffer: buffer_entity.clone(),
 4666            new_language: Some(new_language),
 4667        })
 4668    }
 4669
 4670    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4671        self.buffer_store.clone()
 4672    }
 4673
 4674    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4675        self.active_entry = active_entry;
 4676    }
 4677
 4678    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4679        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4680            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4681        {
 4682            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4683                summaries
 4684                    .iter()
 4685                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4686            });
 4687            if let Some(summary) = summaries.next() {
 4688                client
 4689                    .send(proto::UpdateDiagnosticSummary {
 4690                        project_id: downstream_project_id,
 4691                        worktree_id: worktree.id().to_proto(),
 4692                        summary: Some(summary),
 4693                        more_summaries: summaries.collect(),
 4694                    })
 4695                    .log_err();
 4696            }
 4697        }
 4698    }
 4699
 4700    fn is_capable_for_proto_request<R>(
 4701        &self,
 4702        buffer: &Entity<Buffer>,
 4703        request: &R,
 4704        cx: &App,
 4705    ) -> bool
 4706    where
 4707        R: LspCommand,
 4708    {
 4709        self.check_if_capable_for_proto_request(
 4710            buffer,
 4711            |capabilities| {
 4712                request.check_capabilities(AdapterServerCapabilities {
 4713                    server_capabilities: capabilities.clone(),
 4714                    code_action_kinds: None,
 4715                })
 4716            },
 4717            cx,
 4718        )
 4719    }
 4720
 4721    fn check_if_capable_for_proto_request<F>(
 4722        &self,
 4723        buffer: &Entity<Buffer>,
 4724        check: F,
 4725        cx: &App,
 4726    ) -> bool
 4727    where
 4728        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4729    {
 4730        let Some(language) = buffer.read(cx).language().cloned() else {
 4731            return false;
 4732        };
 4733        let registered_language_servers = self
 4734            .languages
 4735            .lsp_adapters(&language.name())
 4736            .into_iter()
 4737            .map(|lsp_adapter| lsp_adapter.name())
 4738            .collect::<HashSet<_>>();
 4739        self.language_server_statuses
 4740            .iter()
 4741            .filter_map(|(server_id, server_status)| {
 4742                // Include servers that are either registered for this language OR
 4743                // available to be loaded (for SSH remote mode where adapters like
 4744                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4745                // but only loaded on the server side)
 4746                let is_relevant = registered_language_servers.contains(&server_status.name)
 4747                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4748                is_relevant.then_some(server_id)
 4749            })
 4750            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4751            .any(check)
 4752    }
 4753
 4754    fn all_capable_for_proto_request<F>(
 4755        &self,
 4756        buffer: &Entity<Buffer>,
 4757        mut check: F,
 4758        cx: &App,
 4759    ) -> Vec<lsp::LanguageServerId>
 4760    where
 4761        F: FnMut(&lsp::LanguageServerName, &lsp::ServerCapabilities) -> bool,
 4762    {
 4763        let Some(language) = buffer.read(cx).language().cloned() else {
 4764            return Vec::default();
 4765        };
 4766        let registered_language_servers = self
 4767            .languages
 4768            .lsp_adapters(&language.name())
 4769            .into_iter()
 4770            .map(|lsp_adapter| lsp_adapter.name())
 4771            .collect::<HashSet<_>>();
 4772        self.language_server_statuses
 4773            .iter()
 4774            .filter_map(|(server_id, server_status)| {
 4775                // Include servers that are either registered for this language OR
 4776                // available to be loaded (for SSH remote mode where adapters like
 4777                // ty/pylsp/pyright are registered via register_available_lsp_adapter
 4778                // but only loaded on the server side)
 4779                let is_relevant = registered_language_servers.contains(&server_status.name)
 4780                    || self.languages.is_lsp_adapter_available(&server_status.name);
 4781                is_relevant.then_some((server_id, &server_status.name))
 4782            })
 4783            .filter_map(|(server_id, server_name)| {
 4784                self.lsp_server_capabilities
 4785                    .get(server_id)
 4786                    .map(|c| (server_id, server_name, c))
 4787            })
 4788            .filter(|(_, server_name, capabilities)| check(server_name, capabilities))
 4789            .map(|(server_id, _, _)| *server_id)
 4790            .collect()
 4791    }
 4792
 4793    pub fn request_lsp<R>(
 4794        &mut self,
 4795        buffer: Entity<Buffer>,
 4796        server: LanguageServerToQuery,
 4797        request: R,
 4798        cx: &mut Context<Self>,
 4799    ) -> Task<Result<R::Response>>
 4800    where
 4801        R: LspCommand,
 4802        <R::LspRequest as lsp::request::Request>::Result: Send,
 4803        <R::LspRequest as lsp::request::Request>::Params: Send,
 4804    {
 4805        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4806            return self.send_lsp_proto_request(
 4807                buffer,
 4808                upstream_client,
 4809                upstream_project_id,
 4810                request,
 4811                cx,
 4812            );
 4813        }
 4814
 4815        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4816            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4817                local
 4818                    .language_servers_for_buffer(buffer, cx)
 4819                    .find(|(_, server)| {
 4820                        request.check_capabilities(server.adapter_server_capabilities())
 4821                    })
 4822                    .map(|(_, server)| server.clone())
 4823            }),
 4824            LanguageServerToQuery::Other(id) => self
 4825                .language_server_for_local_buffer(buffer, id, cx)
 4826                .and_then(|(_, server)| {
 4827                    request
 4828                        .check_capabilities(server.adapter_server_capabilities())
 4829                        .then(|| Arc::clone(server))
 4830                }),
 4831        }) else {
 4832            return Task::ready(Ok(Default::default()));
 4833        };
 4834
 4835        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4836
 4837        let Some(file) = file else {
 4838            return Task::ready(Ok(Default::default()));
 4839        };
 4840
 4841        let lsp_params = match request.to_lsp_params_or_response(
 4842            &file.abs_path(cx),
 4843            buffer.read(cx),
 4844            &language_server,
 4845            cx,
 4846        ) {
 4847            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4848            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4849            Err(err) => {
 4850                let message = format!(
 4851                    "{} via {} failed: {}",
 4852                    request.display_name(),
 4853                    language_server.name(),
 4854                    err
 4855                );
 4856                // rust-analyzer likes to error with this when its still loading up
 4857                if !message.ends_with("content modified") {
 4858                    log::warn!("{message}");
 4859                }
 4860                return Task::ready(Err(anyhow!(message)));
 4861            }
 4862        };
 4863
 4864        let status = request.status();
 4865        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4866            return Task::ready(Ok(Default::default()));
 4867        }
 4868        cx.spawn(async move |this, cx| {
 4869            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4870
 4871            let id = lsp_request.id();
 4872            let _cleanup = if status.is_some() {
 4873                cx.update(|cx| {
 4874                    this.update(cx, |this, cx| {
 4875                        this.on_lsp_work_start(
 4876                            language_server.server_id(),
 4877                            ProgressToken::Number(id),
 4878                            LanguageServerProgress {
 4879                                is_disk_based_diagnostics_progress: false,
 4880                                is_cancellable: false,
 4881                                title: None,
 4882                                message: status.clone(),
 4883                                percentage: None,
 4884                                last_update_at: cx.background_executor().now(),
 4885                            },
 4886                            cx,
 4887                        );
 4888                    })
 4889                })
 4890                .log_err();
 4891
 4892                Some(defer(|| {
 4893                    cx.update(|cx| {
 4894                        this.update(cx, |this, cx| {
 4895                            this.on_lsp_work_end(
 4896                                language_server.server_id(),
 4897                                ProgressToken::Number(id),
 4898                                cx,
 4899                            );
 4900                        })
 4901                    })
 4902                    .log_err();
 4903                }))
 4904            } else {
 4905                None
 4906            };
 4907
 4908            let result = lsp_request.await.into_response();
 4909
 4910            let response = result.map_err(|err| {
 4911                let message = format!(
 4912                    "{} via {} failed: {}",
 4913                    request.display_name(),
 4914                    language_server.name(),
 4915                    err
 4916                );
 4917                // rust-analyzer likes to error with this when its still loading up
 4918                if !message.ends_with("content modified") {
 4919                    log::warn!("{message}");
 4920                }
 4921                anyhow::anyhow!(message)
 4922            })?;
 4923
 4924            request
 4925                .response_from_lsp(
 4926                    response,
 4927                    this.upgrade().context("no app context")?,
 4928                    buffer,
 4929                    language_server.server_id(),
 4930                    cx.clone(),
 4931                )
 4932                .await
 4933        })
 4934    }
 4935
 4936    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4937        let mut language_formatters_to_check = Vec::new();
 4938        for buffer in self.buffer_store.read(cx).buffers() {
 4939            let buffer = buffer.read(cx);
 4940            let buffer_file = File::from_dyn(buffer.file());
 4941            let buffer_language = buffer.language();
 4942            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4943            if buffer_language.is_some() {
 4944                language_formatters_to_check.push((
 4945                    buffer_file.map(|f| f.worktree_id(cx)),
 4946                    settings.into_owned(),
 4947                ));
 4948            }
 4949        }
 4950
 4951        self.request_workspace_config_refresh();
 4952
 4953        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4954            prettier_store.update(cx, |prettier_store, cx| {
 4955                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4956            })
 4957        }
 4958
 4959        cx.notify();
 4960    }
 4961
 4962    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4963        let buffer_store = self.buffer_store.clone();
 4964        let Some(local) = self.as_local_mut() else {
 4965            return;
 4966        };
 4967        let mut adapters = BTreeMap::default();
 4968        let get_adapter = {
 4969            let languages = local.languages.clone();
 4970            let environment = local.environment.clone();
 4971            let weak = local.weak.clone();
 4972            let worktree_store = local.worktree_store.clone();
 4973            let http_client = local.http_client.clone();
 4974            let fs = local.fs.clone();
 4975            move |worktree_id, cx: &mut App| {
 4976                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4977                Some(LocalLspAdapterDelegate::new(
 4978                    languages.clone(),
 4979                    &environment,
 4980                    weak.clone(),
 4981                    &worktree,
 4982                    http_client.clone(),
 4983                    fs.clone(),
 4984                    cx,
 4985                ))
 4986            }
 4987        };
 4988
 4989        let mut messages_to_report = Vec::new();
 4990        let (new_tree, to_stop) = {
 4991            let mut rebase = local.lsp_tree.rebase();
 4992            let buffers = buffer_store
 4993                .read(cx)
 4994                .buffers()
 4995                .filter_map(|buffer| {
 4996                    let raw_buffer = buffer.read(cx);
 4997                    if !local
 4998                        .registered_buffers
 4999                        .contains_key(&raw_buffer.remote_id())
 5000                    {
 5001                        return None;
 5002                    }
 5003                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 5004                    let language = raw_buffer.language().cloned()?;
 5005                    Some((file, language, raw_buffer.remote_id()))
 5006                })
 5007                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 5008            for (file, language, buffer_id) in buffers {
 5009                let worktree_id = file.worktree_id(cx);
 5010                let Some(worktree) = local
 5011                    .worktree_store
 5012                    .read(cx)
 5013                    .worktree_for_id(worktree_id, cx)
 5014                else {
 5015                    continue;
 5016                };
 5017
 5018                if let Some((_, apply)) = local.reuse_existing_language_server(
 5019                    rebase.server_tree(),
 5020                    &worktree,
 5021                    &language.name(),
 5022                    cx,
 5023                ) {
 5024                    (apply)(rebase.server_tree());
 5025                } else if let Some(lsp_delegate) = adapters
 5026                    .entry(worktree_id)
 5027                    .or_insert_with(|| get_adapter(worktree_id, cx))
 5028                    .clone()
 5029                {
 5030                    let delegate =
 5031                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 5032                    let path = file
 5033                        .path()
 5034                        .parent()
 5035                        .map(Arc::from)
 5036                        .unwrap_or_else(|| file.path().clone());
 5037                    let worktree_path = ProjectPath { worktree_id, path };
 5038                    let abs_path = file.abs_path(cx);
 5039                    let nodes = rebase
 5040                        .walk(
 5041                            worktree_path,
 5042                            language.name(),
 5043                            language.manifest(),
 5044                            delegate.clone(),
 5045                            cx,
 5046                        )
 5047                        .collect::<Vec<_>>();
 5048                    for node in nodes {
 5049                        let server_id = node.server_id_or_init(|disposition| {
 5050                            let path = &disposition.path;
 5051                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 5052                            let key = LanguageServerSeed {
 5053                                worktree_id,
 5054                                name: disposition.server_name.clone(),
 5055                                settings: disposition.settings.clone(),
 5056                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 5057                                    path.worktree_id,
 5058                                    &path.path,
 5059                                    language.name(),
 5060                                ),
 5061                            };
 5062                            local.language_server_ids.remove(&key);
 5063
 5064                            let server_id = local.get_or_insert_language_server(
 5065                                &worktree,
 5066                                lsp_delegate.clone(),
 5067                                disposition,
 5068                                &language.name(),
 5069                                cx,
 5070                            );
 5071                            if let Some(state) = local.language_servers.get(&server_id)
 5072                                && let Ok(uri) = uri
 5073                            {
 5074                                state.add_workspace_folder(uri);
 5075                            };
 5076                            server_id
 5077                        });
 5078
 5079                        if let Some(language_server_id) = server_id {
 5080                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 5081                                language_server_id,
 5082                                name: node.name(),
 5083                                message:
 5084                                    proto::update_language_server::Variant::RegisteredForBuffer(
 5085                                        proto::RegisteredForBuffer {
 5086                                            buffer_abs_path: abs_path
 5087                                                .to_string_lossy()
 5088                                                .into_owned(),
 5089                                            buffer_id: buffer_id.to_proto(),
 5090                                        },
 5091                                    ),
 5092                            });
 5093                        }
 5094                    }
 5095                } else {
 5096                    continue;
 5097                }
 5098            }
 5099            rebase.finish()
 5100        };
 5101        for message in messages_to_report {
 5102            cx.emit(message);
 5103        }
 5104        local.lsp_tree = new_tree;
 5105        for (id, _) in to_stop {
 5106            self.stop_local_language_server(id, cx).detach();
 5107        }
 5108    }
 5109
 5110    pub fn apply_code_action(
 5111        &self,
 5112        buffer_handle: Entity<Buffer>,
 5113        mut action: CodeAction,
 5114        push_to_history: bool,
 5115        cx: &mut Context<Self>,
 5116    ) -> Task<Result<ProjectTransaction>> {
 5117        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5118            let request = proto::ApplyCodeAction {
 5119                project_id,
 5120                buffer_id: buffer_handle.read(cx).remote_id().into(),
 5121                action: Some(Self::serialize_code_action(&action)),
 5122            };
 5123            let buffer_store = self.buffer_store();
 5124            cx.spawn(async move |_, cx| {
 5125                let response = upstream_client
 5126                    .request(request)
 5127                    .await?
 5128                    .transaction
 5129                    .context("missing transaction")?;
 5130
 5131                buffer_store
 5132                    .update(cx, |buffer_store, cx| {
 5133                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 5134                    })
 5135                    .await
 5136            })
 5137        } else if self.mode.is_local() {
 5138            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 5139                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 5140                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 5141            }) else {
 5142                return Task::ready(Ok(ProjectTransaction::default()));
 5143            };
 5144            cx.spawn(async move |this,  cx| {
 5145                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 5146                    .await
 5147                    .context("resolving a code action")?;
 5148                if let Some(edit) = action.lsp_action.edit()
 5149                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 5150                        return LocalLspStore::deserialize_workspace_edit(
 5151                            this.upgrade().context("no app present")?,
 5152                            edit.clone(),
 5153                            push_to_history,
 5154
 5155                            lang_server.clone(),
 5156                            cx,
 5157                        )
 5158                        .await;
 5159                    }
 5160
 5161                if let Some(command) = action.lsp_action.command() {
 5162                    let server_capabilities = lang_server.capabilities();
 5163                    let available_commands = server_capabilities
 5164                        .execute_command_provider
 5165                        .as_ref()
 5166                        .map(|options| options.commands.as_slice())
 5167                        .unwrap_or_default();
 5168                    if available_commands.contains(&command.command) {
 5169                        this.update(cx, |this, _| {
 5170                            this.as_local_mut()
 5171                                .unwrap()
 5172                                .last_workspace_edits_by_language_server
 5173                                .remove(&lang_server.server_id());
 5174                        })?;
 5175
 5176                        let _result = lang_server
 5177                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 5178                                command: command.command.clone(),
 5179                                arguments: command.arguments.clone().unwrap_or_default(),
 5180                                ..lsp::ExecuteCommandParams::default()
 5181                            })
 5182                            .await.into_response()
 5183                            .context("execute command")?;
 5184
 5185                        return this.update(cx, |this, _| {
 5186                            this.as_local_mut()
 5187                                .unwrap()
 5188                                .last_workspace_edits_by_language_server
 5189                                .remove(&lang_server.server_id())
 5190                                .unwrap_or_default()
 5191                        });
 5192                    } else {
 5193                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 5194                    }
 5195                }
 5196
 5197                Ok(ProjectTransaction::default())
 5198            })
 5199        } else {
 5200            Task::ready(Err(anyhow!("no upstream client and not local")))
 5201        }
 5202    }
 5203
 5204    pub fn apply_code_action_kind(
 5205        &mut self,
 5206        buffers: HashSet<Entity<Buffer>>,
 5207        kind: CodeActionKind,
 5208        push_to_history: bool,
 5209        cx: &mut Context<Self>,
 5210    ) -> Task<anyhow::Result<ProjectTransaction>> {
 5211        if self.as_local().is_some() {
 5212            cx.spawn(async move |lsp_store, cx| {
 5213                let buffers = buffers.into_iter().collect::<Vec<_>>();
 5214                let result = LocalLspStore::execute_code_action_kind_locally(
 5215                    lsp_store.clone(),
 5216                    buffers,
 5217                    kind,
 5218                    push_to_history,
 5219                    cx,
 5220                )
 5221                .await;
 5222                lsp_store.update(cx, |lsp_store, _| {
 5223                    lsp_store.update_last_formatting_failure(&result);
 5224                })?;
 5225                result
 5226            })
 5227        } else if let Some((client, project_id)) = self.upstream_client() {
 5228            let buffer_store = self.buffer_store();
 5229            cx.spawn(async move |lsp_store, cx| {
 5230                let result = client
 5231                    .request(proto::ApplyCodeActionKind {
 5232                        project_id,
 5233                        kind: kind.as_str().to_owned(),
 5234                        buffer_ids: buffers
 5235                            .iter()
 5236                            .map(|buffer| {
 5237                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 5238                            })
 5239                            .collect(),
 5240                    })
 5241                    .await
 5242                    .and_then(|result| result.transaction.context("missing transaction"));
 5243                lsp_store.update(cx, |lsp_store, _| {
 5244                    lsp_store.update_last_formatting_failure(&result);
 5245                })?;
 5246
 5247                let transaction_response = result?;
 5248                buffer_store
 5249                    .update(cx, |buffer_store, cx| {
 5250                        buffer_store.deserialize_project_transaction(
 5251                            transaction_response,
 5252                            push_to_history,
 5253                            cx,
 5254                        )
 5255                    })
 5256                    .await
 5257            })
 5258        } else {
 5259            Task::ready(Ok(ProjectTransaction::default()))
 5260        }
 5261    }
 5262
 5263    pub fn resolved_hint(
 5264        &mut self,
 5265        buffer_id: BufferId,
 5266        id: InlayId,
 5267        cx: &mut Context<Self>,
 5268    ) -> Option<ResolvedHint> {
 5269        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 5270
 5271        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 5272        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 5273        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 5274        let (server_id, resolve_data) = match &hint.resolve_state {
 5275            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 5276            ResolveState::Resolving => {
 5277                return Some(ResolvedHint::Resolving(
 5278                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 5279                ));
 5280            }
 5281            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 5282        };
 5283
 5284        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 5285        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 5286        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 5287            id,
 5288            cx.spawn(async move |lsp_store, cx| {
 5289                let resolved_hint = resolve_task.await;
 5290                lsp_store
 5291                    .update(cx, |lsp_store, _| {
 5292                        if let Some(old_inlay_hint) = lsp_store
 5293                            .lsp_data
 5294                            .get_mut(&buffer_id)
 5295                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 5296                        {
 5297                            match resolved_hint {
 5298                                Ok(resolved_hint) => {
 5299                                    *old_inlay_hint = resolved_hint;
 5300                                }
 5301                                Err(e) => {
 5302                                    old_inlay_hint.resolve_state =
 5303                                        ResolveState::CanResolve(server_id, resolve_data);
 5304                                    log::error!("Inlay hint resolve failed: {e:#}");
 5305                                }
 5306                            }
 5307                        }
 5308                    })
 5309                    .ok();
 5310            })
 5311            .shared(),
 5312        );
 5313        debug_assert!(
 5314            previous_task.is_none(),
 5315            "Did not change hint's resolve state after spawning its resolve"
 5316        );
 5317        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 5318        None
 5319    }
 5320
 5321    fn resolve_inlay_hint(
 5322        &self,
 5323        mut hint: InlayHint,
 5324        buffer: Entity<Buffer>,
 5325        server_id: LanguageServerId,
 5326        cx: &mut Context<Self>,
 5327    ) -> Task<anyhow::Result<InlayHint>> {
 5328        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5329            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 5330            {
 5331                hint.resolve_state = ResolveState::Resolved;
 5332                return Task::ready(Ok(hint));
 5333            }
 5334            let request = proto::ResolveInlayHint {
 5335                project_id,
 5336                buffer_id: buffer.read(cx).remote_id().into(),
 5337                language_server_id: server_id.0 as u64,
 5338                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 5339            };
 5340            cx.background_spawn(async move {
 5341                let response = upstream_client
 5342                    .request(request)
 5343                    .await
 5344                    .context("inlay hints proto request")?;
 5345                match response.hint {
 5346                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5347                        .context("inlay hints proto resolve response conversion"),
 5348                    None => Ok(hint),
 5349                }
 5350            })
 5351        } else {
 5352            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5353                self.language_server_for_local_buffer(buffer, server_id, cx)
 5354                    .map(|(_, server)| server.clone())
 5355            }) else {
 5356                return Task::ready(Ok(hint));
 5357            };
 5358            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5359                return Task::ready(Ok(hint));
 5360            }
 5361            let buffer_snapshot = buffer.read(cx).snapshot();
 5362            cx.spawn(async move |_, cx| {
 5363                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5364                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5365                );
 5366                let resolved_hint = resolve_task
 5367                    .await
 5368                    .into_response()
 5369                    .context("inlay hint resolve LSP request")?;
 5370                let resolved_hint = InlayHints::lsp_to_project_hint(
 5371                    resolved_hint,
 5372                    &buffer,
 5373                    server_id,
 5374                    ResolveState::Resolved,
 5375                    false,
 5376                    cx,
 5377                )
 5378                .await?;
 5379                Ok(resolved_hint)
 5380            })
 5381        }
 5382    }
 5383
 5384    pub fn resolve_color_presentation(
 5385        &mut self,
 5386        mut color: DocumentColor,
 5387        buffer: Entity<Buffer>,
 5388        server_id: LanguageServerId,
 5389        cx: &mut Context<Self>,
 5390    ) -> Task<Result<DocumentColor>> {
 5391        if color.resolved {
 5392            return Task::ready(Ok(color));
 5393        }
 5394
 5395        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5396            let start = color.lsp_range.start;
 5397            let end = color.lsp_range.end;
 5398            let request = proto::GetColorPresentation {
 5399                project_id,
 5400                server_id: server_id.to_proto(),
 5401                buffer_id: buffer.read(cx).remote_id().into(),
 5402                color: Some(proto::ColorInformation {
 5403                    red: color.color.red,
 5404                    green: color.color.green,
 5405                    blue: color.color.blue,
 5406                    alpha: color.color.alpha,
 5407                    lsp_range_start: Some(proto::PointUtf16 {
 5408                        row: start.line,
 5409                        column: start.character,
 5410                    }),
 5411                    lsp_range_end: Some(proto::PointUtf16 {
 5412                        row: end.line,
 5413                        column: end.character,
 5414                    }),
 5415                }),
 5416            };
 5417            cx.background_spawn(async move {
 5418                let response = upstream_client
 5419                    .request(request)
 5420                    .await
 5421                    .context("color presentation proto request")?;
 5422                color.resolved = true;
 5423                color.color_presentations = response
 5424                    .presentations
 5425                    .into_iter()
 5426                    .map(|presentation| ColorPresentation {
 5427                        label: SharedString::from(presentation.label),
 5428                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5429                        additional_text_edits: presentation
 5430                            .additional_text_edits
 5431                            .into_iter()
 5432                            .filter_map(deserialize_lsp_edit)
 5433                            .collect(),
 5434                    })
 5435                    .collect();
 5436                Ok(color)
 5437            })
 5438        } else {
 5439            let path = match buffer
 5440                .update(cx, |buffer, cx| {
 5441                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5442                })
 5443                .context("buffer with the missing path")
 5444            {
 5445                Ok(path) => path,
 5446                Err(e) => return Task::ready(Err(e)),
 5447            };
 5448            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5449                self.language_server_for_local_buffer(buffer, server_id, cx)
 5450                    .map(|(_, server)| server.clone())
 5451            }) else {
 5452                return Task::ready(Ok(color));
 5453            };
 5454            cx.background_spawn(async move {
 5455                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5456                    lsp::ColorPresentationParams {
 5457                        text_document: make_text_document_identifier(&path)?,
 5458                        color: color.color,
 5459                        range: color.lsp_range,
 5460                        work_done_progress_params: Default::default(),
 5461                        partial_result_params: Default::default(),
 5462                    },
 5463                );
 5464                color.color_presentations = resolve_task
 5465                    .await
 5466                    .into_response()
 5467                    .context("color presentation resolve LSP request")?
 5468                    .into_iter()
 5469                    .map(|presentation| ColorPresentation {
 5470                        label: SharedString::from(presentation.label),
 5471                        text_edit: presentation.text_edit,
 5472                        additional_text_edits: presentation
 5473                            .additional_text_edits
 5474                            .unwrap_or_default(),
 5475                    })
 5476                    .collect();
 5477                color.resolved = true;
 5478                Ok(color)
 5479            })
 5480        }
 5481    }
 5482
 5483    pub(crate) fn linked_edits(
 5484        &mut self,
 5485        buffer: &Entity<Buffer>,
 5486        position: Anchor,
 5487        cx: &mut Context<Self>,
 5488    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5489        let snapshot = buffer.read(cx).snapshot();
 5490        let scope = snapshot.language_scope_at(position);
 5491        let Some(server_id) = self
 5492            .as_local()
 5493            .and_then(|local| {
 5494                buffer.update(cx, |buffer, cx| {
 5495                    local
 5496                        .language_servers_for_buffer(buffer, cx)
 5497                        .filter(|(_, server)| {
 5498                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5499                        })
 5500                        .filter(|(adapter, _)| {
 5501                            scope
 5502                                .as_ref()
 5503                                .map(|scope| scope.language_allowed(&adapter.name))
 5504                                .unwrap_or(true)
 5505                        })
 5506                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5507                        .next()
 5508                })
 5509            })
 5510            .or_else(|| {
 5511                self.upstream_client()
 5512                    .is_some()
 5513                    .then_some(LanguageServerToQuery::FirstCapable)
 5514            })
 5515            .filter(|_| {
 5516                maybe!({
 5517                    let language = buffer.read(cx).language_at(position)?;
 5518                    Some(
 5519                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5520                            .linked_edits,
 5521                    )
 5522                }) == Some(true)
 5523            })
 5524        else {
 5525            return Task::ready(Ok(Vec::new()));
 5526        };
 5527
 5528        self.request_lsp(
 5529            buffer.clone(),
 5530            server_id,
 5531            LinkedEditingRange { position },
 5532            cx,
 5533        )
 5534    }
 5535
 5536    fn apply_on_type_formatting(
 5537        &mut self,
 5538        buffer: Entity<Buffer>,
 5539        position: Anchor,
 5540        trigger: String,
 5541        cx: &mut Context<Self>,
 5542    ) -> Task<Result<Option<Transaction>>> {
 5543        if let Some((client, project_id)) = self.upstream_client() {
 5544            if !self.check_if_capable_for_proto_request(
 5545                &buffer,
 5546                |capabilities| {
 5547                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5548                },
 5549                cx,
 5550            ) {
 5551                return Task::ready(Ok(None));
 5552            }
 5553            let request = proto::OnTypeFormatting {
 5554                project_id,
 5555                buffer_id: buffer.read(cx).remote_id().into(),
 5556                position: Some(serialize_anchor(&position)),
 5557                trigger,
 5558                version: serialize_version(&buffer.read(cx).version()),
 5559            };
 5560            cx.background_spawn(async move {
 5561                client
 5562                    .request(request)
 5563                    .await?
 5564                    .transaction
 5565                    .map(language::proto::deserialize_transaction)
 5566                    .transpose()
 5567            })
 5568        } else if let Some(local) = self.as_local_mut() {
 5569            let buffer_id = buffer.read(cx).remote_id();
 5570            local.buffers_being_formatted.insert(buffer_id);
 5571            cx.spawn(async move |this, cx| {
 5572                let _cleanup = defer({
 5573                    let this = this.clone();
 5574                    let mut cx = cx.clone();
 5575                    move || {
 5576                        this.update(&mut cx, |this, _| {
 5577                            if let Some(local) = this.as_local_mut() {
 5578                                local.buffers_being_formatted.remove(&buffer_id);
 5579                            }
 5580                        })
 5581                        .ok();
 5582                    }
 5583                });
 5584
 5585                buffer
 5586                    .update(cx, |buffer, _| {
 5587                        buffer.wait_for_edits(Some(position.timestamp))
 5588                    })
 5589                    .await?;
 5590                this.update(cx, |this, cx| {
 5591                    let position = position.to_point_utf16(buffer.read(cx));
 5592                    this.on_type_format(buffer, position, trigger, false, cx)
 5593                })?
 5594                .await
 5595            })
 5596        } else {
 5597            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5598        }
 5599    }
 5600
 5601    pub fn on_type_format<T: ToPointUtf16>(
 5602        &mut self,
 5603        buffer: Entity<Buffer>,
 5604        position: T,
 5605        trigger: String,
 5606        push_to_history: bool,
 5607        cx: &mut Context<Self>,
 5608    ) -> Task<Result<Option<Transaction>>> {
 5609        let position = position.to_point_utf16(buffer.read(cx));
 5610        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5611    }
 5612
 5613    fn on_type_format_impl(
 5614        &mut self,
 5615        buffer: Entity<Buffer>,
 5616        position: PointUtf16,
 5617        trigger: String,
 5618        push_to_history: bool,
 5619        cx: &mut Context<Self>,
 5620    ) -> Task<Result<Option<Transaction>>> {
 5621        let options = buffer.update(cx, |buffer, cx| {
 5622            lsp_command::lsp_formatting_options(
 5623                language_settings(
 5624                    buffer.language_at(position).map(|l| l.name()),
 5625                    buffer.file(),
 5626                    cx,
 5627                )
 5628                .as_ref(),
 5629            )
 5630        });
 5631
 5632        cx.spawn(async move |this, cx| {
 5633            if let Some(waiter) =
 5634                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())
 5635            {
 5636                waiter.await?;
 5637            }
 5638            cx.update(|cx| {
 5639                this.update(cx, |this, cx| {
 5640                    this.request_lsp(
 5641                        buffer.clone(),
 5642                        LanguageServerToQuery::FirstCapable,
 5643                        OnTypeFormatting {
 5644                            position,
 5645                            trigger,
 5646                            options,
 5647                            push_to_history,
 5648                        },
 5649                        cx,
 5650                    )
 5651                })
 5652            })?
 5653            .await
 5654        })
 5655    }
 5656
 5657    pub fn definitions(
 5658        &mut self,
 5659        buffer: &Entity<Buffer>,
 5660        position: PointUtf16,
 5661        cx: &mut Context<Self>,
 5662    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5663        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5664            let request = GetDefinitions { position };
 5665            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5666                return Task::ready(Ok(None));
 5667            }
 5668            let request_task = upstream_client.request_lsp(
 5669                project_id,
 5670                None,
 5671                LSP_REQUEST_TIMEOUT,
 5672                cx.background_executor().clone(),
 5673                request.to_proto(project_id, buffer.read(cx)),
 5674            );
 5675            let buffer = buffer.clone();
 5676            cx.spawn(async move |weak_lsp_store, cx| {
 5677                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5678                    return Ok(None);
 5679                };
 5680                let Some(responses) = request_task.await? else {
 5681                    return Ok(None);
 5682                };
 5683                let actions = join_all(responses.payload.into_iter().map(|response| {
 5684                    GetDefinitions { position }.response_from_proto(
 5685                        response.response,
 5686                        lsp_store.clone(),
 5687                        buffer.clone(),
 5688                        cx.clone(),
 5689                    )
 5690                }))
 5691                .await;
 5692
 5693                Ok(Some(
 5694                    actions
 5695                        .into_iter()
 5696                        .collect::<Result<Vec<Vec<_>>>>()?
 5697                        .into_iter()
 5698                        .flatten()
 5699                        .dedup()
 5700                        .collect(),
 5701                ))
 5702            })
 5703        } else {
 5704            let definitions_task = self.request_multiple_lsp_locally(
 5705                buffer,
 5706                Some(position),
 5707                GetDefinitions { position },
 5708                cx,
 5709            );
 5710            cx.background_spawn(async move {
 5711                Ok(Some(
 5712                    definitions_task
 5713                        .await
 5714                        .into_iter()
 5715                        .flat_map(|(_, definitions)| definitions)
 5716                        .dedup()
 5717                        .collect(),
 5718                ))
 5719            })
 5720        }
 5721    }
 5722
 5723    pub fn declarations(
 5724        &mut self,
 5725        buffer: &Entity<Buffer>,
 5726        position: PointUtf16,
 5727        cx: &mut Context<Self>,
 5728    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5729        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5730            let request = GetDeclarations { position };
 5731            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5732                return Task::ready(Ok(None));
 5733            }
 5734            let request_task = upstream_client.request_lsp(
 5735                project_id,
 5736                None,
 5737                LSP_REQUEST_TIMEOUT,
 5738                cx.background_executor().clone(),
 5739                request.to_proto(project_id, buffer.read(cx)),
 5740            );
 5741            let buffer = buffer.clone();
 5742            cx.spawn(async move |weak_lsp_store, cx| {
 5743                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5744                    return Ok(None);
 5745                };
 5746                let Some(responses) = request_task.await? else {
 5747                    return Ok(None);
 5748                };
 5749                let actions = join_all(responses.payload.into_iter().map(|response| {
 5750                    GetDeclarations { position }.response_from_proto(
 5751                        response.response,
 5752                        lsp_store.clone(),
 5753                        buffer.clone(),
 5754                        cx.clone(),
 5755                    )
 5756                }))
 5757                .await;
 5758
 5759                Ok(Some(
 5760                    actions
 5761                        .into_iter()
 5762                        .collect::<Result<Vec<Vec<_>>>>()?
 5763                        .into_iter()
 5764                        .flatten()
 5765                        .dedup()
 5766                        .collect(),
 5767                ))
 5768            })
 5769        } else {
 5770            let declarations_task = self.request_multiple_lsp_locally(
 5771                buffer,
 5772                Some(position),
 5773                GetDeclarations { position },
 5774                cx,
 5775            );
 5776            cx.background_spawn(async move {
 5777                Ok(Some(
 5778                    declarations_task
 5779                        .await
 5780                        .into_iter()
 5781                        .flat_map(|(_, declarations)| declarations)
 5782                        .dedup()
 5783                        .collect(),
 5784                ))
 5785            })
 5786        }
 5787    }
 5788
 5789    pub fn type_definitions(
 5790        &mut self,
 5791        buffer: &Entity<Buffer>,
 5792        position: PointUtf16,
 5793        cx: &mut Context<Self>,
 5794    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5795        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5796            let request = GetTypeDefinitions { position };
 5797            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5798                return Task::ready(Ok(None));
 5799            }
 5800            let request_task = upstream_client.request_lsp(
 5801                project_id,
 5802                None,
 5803                LSP_REQUEST_TIMEOUT,
 5804                cx.background_executor().clone(),
 5805                request.to_proto(project_id, buffer.read(cx)),
 5806            );
 5807            let buffer = buffer.clone();
 5808            cx.spawn(async move |weak_lsp_store, cx| {
 5809                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5810                    return Ok(None);
 5811                };
 5812                let Some(responses) = request_task.await? else {
 5813                    return Ok(None);
 5814                };
 5815                let actions = join_all(responses.payload.into_iter().map(|response| {
 5816                    GetTypeDefinitions { position }.response_from_proto(
 5817                        response.response,
 5818                        lsp_store.clone(),
 5819                        buffer.clone(),
 5820                        cx.clone(),
 5821                    )
 5822                }))
 5823                .await;
 5824
 5825                Ok(Some(
 5826                    actions
 5827                        .into_iter()
 5828                        .collect::<Result<Vec<Vec<_>>>>()?
 5829                        .into_iter()
 5830                        .flatten()
 5831                        .dedup()
 5832                        .collect(),
 5833                ))
 5834            })
 5835        } else {
 5836            let type_definitions_task = self.request_multiple_lsp_locally(
 5837                buffer,
 5838                Some(position),
 5839                GetTypeDefinitions { position },
 5840                cx,
 5841            );
 5842            cx.background_spawn(async move {
 5843                Ok(Some(
 5844                    type_definitions_task
 5845                        .await
 5846                        .into_iter()
 5847                        .flat_map(|(_, type_definitions)| type_definitions)
 5848                        .dedup()
 5849                        .collect(),
 5850                ))
 5851            })
 5852        }
 5853    }
 5854
 5855    pub fn implementations(
 5856        &mut self,
 5857        buffer: &Entity<Buffer>,
 5858        position: PointUtf16,
 5859        cx: &mut Context<Self>,
 5860    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5861        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5862            let request = GetImplementations { position };
 5863            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5864                return Task::ready(Ok(None));
 5865            }
 5866            let request_task = upstream_client.request_lsp(
 5867                project_id,
 5868                None,
 5869                LSP_REQUEST_TIMEOUT,
 5870                cx.background_executor().clone(),
 5871                request.to_proto(project_id, buffer.read(cx)),
 5872            );
 5873            let buffer = buffer.clone();
 5874            cx.spawn(async move |weak_lsp_store, cx| {
 5875                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5876                    return Ok(None);
 5877                };
 5878                let Some(responses) = request_task.await? else {
 5879                    return Ok(None);
 5880                };
 5881                let actions = join_all(responses.payload.into_iter().map(|response| {
 5882                    GetImplementations { position }.response_from_proto(
 5883                        response.response,
 5884                        lsp_store.clone(),
 5885                        buffer.clone(),
 5886                        cx.clone(),
 5887                    )
 5888                }))
 5889                .await;
 5890
 5891                Ok(Some(
 5892                    actions
 5893                        .into_iter()
 5894                        .collect::<Result<Vec<Vec<_>>>>()?
 5895                        .into_iter()
 5896                        .flatten()
 5897                        .dedup()
 5898                        .collect(),
 5899                ))
 5900            })
 5901        } else {
 5902            let implementations_task = self.request_multiple_lsp_locally(
 5903                buffer,
 5904                Some(position),
 5905                GetImplementations { position },
 5906                cx,
 5907            );
 5908            cx.background_spawn(async move {
 5909                Ok(Some(
 5910                    implementations_task
 5911                        .await
 5912                        .into_iter()
 5913                        .flat_map(|(_, implementations)| implementations)
 5914                        .dedup()
 5915                        .collect(),
 5916                ))
 5917            })
 5918        }
 5919    }
 5920
 5921    pub fn references(
 5922        &mut self,
 5923        buffer: &Entity<Buffer>,
 5924        position: PointUtf16,
 5925        cx: &mut Context<Self>,
 5926    ) -> Task<Result<Option<Vec<Location>>>> {
 5927        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5928            let request = GetReferences { position };
 5929            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5930                return Task::ready(Ok(None));
 5931            }
 5932
 5933            let request_task = upstream_client.request_lsp(
 5934                project_id,
 5935                None,
 5936                LSP_REQUEST_TIMEOUT,
 5937                cx.background_executor().clone(),
 5938                request.to_proto(project_id, buffer.read(cx)),
 5939            );
 5940            let buffer = buffer.clone();
 5941            cx.spawn(async move |weak_lsp_store, cx| {
 5942                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5943                    return Ok(None);
 5944                };
 5945                let Some(responses) = request_task.await? else {
 5946                    return Ok(None);
 5947                };
 5948
 5949                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5950                    GetReferences { position }.response_from_proto(
 5951                        lsp_response.response,
 5952                        lsp_store.clone(),
 5953                        buffer.clone(),
 5954                        cx.clone(),
 5955                    )
 5956                }))
 5957                .await
 5958                .into_iter()
 5959                .collect::<Result<Vec<Vec<_>>>>()?
 5960                .into_iter()
 5961                .flatten()
 5962                .dedup()
 5963                .collect();
 5964                Ok(Some(locations))
 5965            })
 5966        } else {
 5967            let references_task = self.request_multiple_lsp_locally(
 5968                buffer,
 5969                Some(position),
 5970                GetReferences { position },
 5971                cx,
 5972            );
 5973            cx.background_spawn(async move {
 5974                Ok(Some(
 5975                    references_task
 5976                        .await
 5977                        .into_iter()
 5978                        .flat_map(|(_, references)| references)
 5979                        .dedup()
 5980                        .collect(),
 5981                ))
 5982            })
 5983        }
 5984    }
 5985
 5986    pub fn code_actions(
 5987        &mut self,
 5988        buffer: &Entity<Buffer>,
 5989        range: Range<Anchor>,
 5990        kinds: Option<Vec<CodeActionKind>>,
 5991        cx: &mut Context<Self>,
 5992    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5993        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5994            let request = GetCodeActions {
 5995                range: range.clone(),
 5996                kinds: kinds.clone(),
 5997            };
 5998            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5999                return Task::ready(Ok(None));
 6000            }
 6001            let request_task = upstream_client.request_lsp(
 6002                project_id,
 6003                None,
 6004                LSP_REQUEST_TIMEOUT,
 6005                cx.background_executor().clone(),
 6006                request.to_proto(project_id, buffer.read(cx)),
 6007            );
 6008            let buffer = buffer.clone();
 6009            cx.spawn(async move |weak_lsp_store, cx| {
 6010                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6011                    return Ok(None);
 6012                };
 6013                let Some(responses) = request_task.await? else {
 6014                    return Ok(None);
 6015                };
 6016                let actions = join_all(responses.payload.into_iter().map(|response| {
 6017                    GetCodeActions {
 6018                        range: range.clone(),
 6019                        kinds: kinds.clone(),
 6020                    }
 6021                    .response_from_proto(
 6022                        response.response,
 6023                        lsp_store.clone(),
 6024                        buffer.clone(),
 6025                        cx.clone(),
 6026                    )
 6027                }))
 6028                .await;
 6029
 6030                Ok(Some(
 6031                    actions
 6032                        .into_iter()
 6033                        .collect::<Result<Vec<Vec<_>>>>()?
 6034                        .into_iter()
 6035                        .flatten()
 6036                        .collect(),
 6037                ))
 6038            })
 6039        } else {
 6040            let all_actions_task = self.request_multiple_lsp_locally(
 6041                buffer,
 6042                Some(range.start),
 6043                GetCodeActions { range, kinds },
 6044                cx,
 6045            );
 6046            cx.background_spawn(async move {
 6047                Ok(Some(
 6048                    all_actions_task
 6049                        .await
 6050                        .into_iter()
 6051                        .flat_map(|(_, actions)| actions)
 6052                        .collect(),
 6053                ))
 6054            })
 6055        }
 6056    }
 6057
 6058    pub fn code_lens_actions(
 6059        &mut self,
 6060        buffer: &Entity<Buffer>,
 6061        cx: &mut Context<Self>,
 6062    ) -> CodeLensTask {
 6063        let version_queried_for = buffer.read(cx).version();
 6064        let buffer_id = buffer.read(cx).remote_id();
 6065        let existing_servers = self.as_local().map(|local| {
 6066            local
 6067                .buffers_opened_in_servers
 6068                .get(&buffer_id)
 6069                .cloned()
 6070                .unwrap_or_default()
 6071        });
 6072
 6073        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 6074            if let Some(cached_lens) = &lsp_data.code_lens {
 6075                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 6076                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 6077                        existing_servers != cached_lens.lens.keys().copied().collect()
 6078                    });
 6079                    if !has_different_servers {
 6080                        return Task::ready(Ok(Some(
 6081                            cached_lens.lens.values().flatten().cloned().collect(),
 6082                        )))
 6083                        .shared();
 6084                    }
 6085                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 6086                    if !version_queried_for.changed_since(updating_for) {
 6087                        return running_update.clone();
 6088                    }
 6089                }
 6090            }
 6091        }
 6092
 6093        let lens_lsp_data = self
 6094            .latest_lsp_data(buffer, cx)
 6095            .code_lens
 6096            .get_or_insert_default();
 6097        let buffer = buffer.clone();
 6098        let query_version_queried_for = version_queried_for.clone();
 6099        let new_task = cx
 6100            .spawn(async move |lsp_store, cx| {
 6101                cx.background_executor()
 6102                    .timer(Duration::from_millis(30))
 6103                    .await;
 6104                let fetched_lens = lsp_store
 6105                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 6106                    .map_err(Arc::new)?
 6107                    .await
 6108                    .context("fetching code lens")
 6109                    .map_err(Arc::new);
 6110                let fetched_lens = match fetched_lens {
 6111                    Ok(fetched_lens) => fetched_lens,
 6112                    Err(e) => {
 6113                        lsp_store
 6114                            .update(cx, |lsp_store, _| {
 6115                                if let Some(lens_lsp_data) = lsp_store
 6116                                    .lsp_data
 6117                                    .get_mut(&buffer_id)
 6118                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 6119                                {
 6120                                    lens_lsp_data.update = None;
 6121                                }
 6122                            })
 6123                            .ok();
 6124                        return Err(e);
 6125                    }
 6126                };
 6127
 6128                lsp_store
 6129                    .update(cx, |lsp_store, _| {
 6130                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 6131                        let code_lens = lsp_data.code_lens.as_mut()?;
 6132                        if let Some(fetched_lens) = fetched_lens {
 6133                            if lsp_data.buffer_version == query_version_queried_for {
 6134                                code_lens.lens.extend(fetched_lens);
 6135                            } else if !lsp_data
 6136                                .buffer_version
 6137                                .changed_since(&query_version_queried_for)
 6138                            {
 6139                                lsp_data.buffer_version = query_version_queried_for;
 6140                                code_lens.lens = fetched_lens;
 6141                            }
 6142                        }
 6143                        code_lens.update = None;
 6144                        Some(code_lens.lens.values().flatten().cloned().collect())
 6145                    })
 6146                    .map_err(Arc::new)
 6147            })
 6148            .shared();
 6149        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 6150        new_task
 6151    }
 6152
 6153    fn fetch_code_lens(
 6154        &mut self,
 6155        buffer: &Entity<Buffer>,
 6156        cx: &mut Context<Self>,
 6157    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 6158        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6159            let request = GetCodeLens;
 6160            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6161                return Task::ready(Ok(None));
 6162            }
 6163            let request_task = upstream_client.request_lsp(
 6164                project_id,
 6165                None,
 6166                LSP_REQUEST_TIMEOUT,
 6167                cx.background_executor().clone(),
 6168                request.to_proto(project_id, buffer.read(cx)),
 6169            );
 6170            let buffer = buffer.clone();
 6171            cx.spawn(async move |weak_lsp_store, cx| {
 6172                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6173                    return Ok(None);
 6174                };
 6175                let Some(responses) = request_task.await? else {
 6176                    return Ok(None);
 6177                };
 6178
 6179                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 6180                    let lsp_store = lsp_store.clone();
 6181                    let buffer = buffer.clone();
 6182                    let cx = cx.clone();
 6183                    async move {
 6184                        (
 6185                            LanguageServerId::from_proto(response.server_id),
 6186                            GetCodeLens
 6187                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6188                                .await,
 6189                        )
 6190                    }
 6191                }))
 6192                .await;
 6193
 6194                let mut has_errors = false;
 6195                let code_lens_actions = code_lens_actions
 6196                    .into_iter()
 6197                    .filter_map(|(server_id, code_lens)| match code_lens {
 6198                        Ok(code_lens) => Some((server_id, code_lens)),
 6199                        Err(e) => {
 6200                            has_errors = true;
 6201                            log::error!("{e:#}");
 6202                            None
 6203                        }
 6204                    })
 6205                    .collect::<HashMap<_, _>>();
 6206                anyhow::ensure!(
 6207                    !has_errors || !code_lens_actions.is_empty(),
 6208                    "Failed to fetch code lens"
 6209                );
 6210                Ok(Some(code_lens_actions))
 6211            })
 6212        } else {
 6213            let code_lens_actions_task =
 6214                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 6215            cx.background_spawn(async move {
 6216                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 6217            })
 6218        }
 6219    }
 6220
 6221    #[inline(never)]
 6222    pub fn completions(
 6223        &self,
 6224        buffer: &Entity<Buffer>,
 6225        position: PointUtf16,
 6226        context: CompletionContext,
 6227        cx: &mut Context<Self>,
 6228    ) -> Task<Result<Vec<CompletionResponse>>> {
 6229        let language_registry = self.languages.clone();
 6230
 6231        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6232            let snapshot = buffer.read(cx).snapshot();
 6233            let offset = position.to_offset(&snapshot);
 6234            let scope = snapshot.language_scope_at(offset);
 6235            let capable_lsps = self.all_capable_for_proto_request(
 6236                buffer,
 6237                |server_name, capabilities| {
 6238                    capabilities.completion_provider.is_some()
 6239                        && scope
 6240                            .as_ref()
 6241                            .map(|scope| scope.language_allowed(server_name))
 6242                            .unwrap_or(true)
 6243                },
 6244                cx,
 6245            );
 6246            if capable_lsps.is_empty() {
 6247                return Task::ready(Ok(Vec::new()));
 6248            }
 6249
 6250            let language = buffer.read(cx).language().cloned();
 6251
 6252            // In the future, we should provide project guests with the names of LSP adapters,
 6253            // so that they can use the correct LSP adapter when computing labels. For now,
 6254            // guests just use the first LSP adapter associated with the buffer's language.
 6255            let lsp_adapter = language.as_ref().and_then(|language| {
 6256                language_registry
 6257                    .lsp_adapters(&language.name())
 6258                    .first()
 6259                    .cloned()
 6260            });
 6261
 6262            let buffer = buffer.clone();
 6263
 6264            cx.spawn(async move |this, cx| {
 6265                let requests = join_all(
 6266                    capable_lsps
 6267                        .into_iter()
 6268                        .map(|id| {
 6269                            let request = GetCompletions {
 6270                                position,
 6271                                context: context.clone(),
 6272                                server_id: Some(id),
 6273                            };
 6274                            let buffer = buffer.clone();
 6275                            let language = language.clone();
 6276                            let lsp_adapter = lsp_adapter.clone();
 6277                            let upstream_client = upstream_client.clone();
 6278                            let response = this
 6279                                .update(cx, |this, cx| {
 6280                                    this.send_lsp_proto_request(
 6281                                        buffer,
 6282                                        upstream_client,
 6283                                        project_id,
 6284                                        request,
 6285                                        cx,
 6286                                    )
 6287                                })
 6288                                .log_err();
 6289                            async move {
 6290                                let response = response?.await.log_err()?;
 6291
 6292                                let completions = populate_labels_for_completions(
 6293                                    response.completions,
 6294                                    language,
 6295                                    lsp_adapter,
 6296                                )
 6297                                .await;
 6298
 6299                                Some(CompletionResponse {
 6300                                    completions,
 6301                                    display_options: CompletionDisplayOptions::default(),
 6302                                    is_incomplete: response.is_incomplete,
 6303                                })
 6304                            }
 6305                        })
 6306                        .collect::<Vec<_>>(),
 6307                );
 6308                Ok(requests.await.into_iter().flatten().collect::<Vec<_>>())
 6309            })
 6310        } else if let Some(local) = self.as_local() {
 6311            let snapshot = buffer.read(cx).snapshot();
 6312            let offset = position.to_offset(&snapshot);
 6313            let scope = snapshot.language_scope_at(offset);
 6314            let language = snapshot.language().cloned();
 6315            let completion_settings = language_settings(
 6316                language.as_ref().map(|language| language.name()),
 6317                buffer.read(cx).file(),
 6318                cx,
 6319            )
 6320            .completions
 6321            .clone();
 6322            if !completion_settings.lsp {
 6323                return Task::ready(Ok(Vec::new()));
 6324            }
 6325
 6326            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 6327                local
 6328                    .language_servers_for_buffer(buffer, cx)
 6329                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 6330                    .filter(|(adapter, _)| {
 6331                        scope
 6332                            .as_ref()
 6333                            .map(|scope| scope.language_allowed(&adapter.name))
 6334                            .unwrap_or(true)
 6335                    })
 6336                    .map(|(_, server)| server.server_id())
 6337                    .collect()
 6338            });
 6339
 6340            let buffer = buffer.clone();
 6341            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 6342            let lsp_timeout = if lsp_timeout > 0 {
 6343                Some(Duration::from_millis(lsp_timeout))
 6344            } else {
 6345                None
 6346            };
 6347            cx.spawn(async move |this,  cx| {
 6348                let mut tasks = Vec::with_capacity(server_ids.len());
 6349                this.update(cx, |lsp_store, cx| {
 6350                    for server_id in server_ids {
 6351                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 6352                        let lsp_timeout = lsp_timeout
 6353                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 6354                        let mut timeout = cx.background_spawn(async move {
 6355                            match lsp_timeout {
 6356                                Some(lsp_timeout) => {
 6357                                    lsp_timeout.await;
 6358                                    true
 6359                                },
 6360                                None => false,
 6361                            }
 6362                        }).fuse();
 6363                        let mut lsp_request = lsp_store.request_lsp(
 6364                            buffer.clone(),
 6365                            LanguageServerToQuery::Other(server_id),
 6366                            GetCompletions {
 6367                                position,
 6368                                context: context.clone(),
 6369                                server_id: Some(server_id),
 6370                            },
 6371                            cx,
 6372                        ).fuse();
 6373                        let new_task = cx.background_spawn(async move {
 6374                            select_biased! {
 6375                                response = lsp_request => anyhow::Ok(Some(response?)),
 6376                                timeout_happened = timeout => {
 6377                                    if timeout_happened {
 6378                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6379                                        Ok(None)
 6380                                    } else {
 6381                                        let completions = lsp_request.await?;
 6382                                        Ok(Some(completions))
 6383                                    }
 6384                                },
 6385                            }
 6386                        });
 6387                        tasks.push((lsp_adapter, new_task));
 6388                    }
 6389                })?;
 6390
 6391                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6392                    let completion_response = task.await.ok()??;
 6393                    let completions = populate_labels_for_completions(
 6394                            completion_response.completions,
 6395                            language.clone(),
 6396                            lsp_adapter,
 6397                        )
 6398                        .await;
 6399                    Some(CompletionResponse {
 6400                        completions,
 6401                        display_options: CompletionDisplayOptions::default(),
 6402                        is_incomplete: completion_response.is_incomplete,
 6403                    })
 6404                });
 6405
 6406                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6407
 6408                Ok(responses.into_iter().flatten().collect())
 6409            })
 6410        } else {
 6411            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6412        }
 6413    }
 6414
 6415    pub fn resolve_completions(
 6416        &self,
 6417        buffer: Entity<Buffer>,
 6418        completion_indices: Vec<usize>,
 6419        completions: Rc<RefCell<Box<[Completion]>>>,
 6420        cx: &mut Context<Self>,
 6421    ) -> Task<Result<bool>> {
 6422        let client = self.upstream_client();
 6423        let buffer_id = buffer.read(cx).remote_id();
 6424        let buffer_snapshot = buffer.read(cx).snapshot();
 6425
 6426        if !self.check_if_capable_for_proto_request(
 6427            &buffer,
 6428            GetCompletions::can_resolve_completions,
 6429            cx,
 6430        ) {
 6431            return Task::ready(Ok(false));
 6432        }
 6433        cx.spawn(async move |lsp_store, cx| {
 6434            let mut did_resolve = false;
 6435            if let Some((client, project_id)) = client {
 6436                for completion_index in completion_indices {
 6437                    let server_id = {
 6438                        let completion = &completions.borrow()[completion_index];
 6439                        completion.source.server_id()
 6440                    };
 6441                    if let Some(server_id) = server_id {
 6442                        if Self::resolve_completion_remote(
 6443                            project_id,
 6444                            server_id,
 6445                            buffer_id,
 6446                            completions.clone(),
 6447                            completion_index,
 6448                            client.clone(),
 6449                        )
 6450                        .await
 6451                        .log_err()
 6452                        .is_some()
 6453                        {
 6454                            did_resolve = true;
 6455                        }
 6456                    } else {
 6457                        resolve_word_completion(
 6458                            &buffer_snapshot,
 6459                            &mut completions.borrow_mut()[completion_index],
 6460                        );
 6461                    }
 6462                }
 6463            } else {
 6464                for completion_index in completion_indices {
 6465                    let server_id = {
 6466                        let completion = &completions.borrow()[completion_index];
 6467                        completion.source.server_id()
 6468                    };
 6469                    if let Some(server_id) = server_id {
 6470                        let server_and_adapter = lsp_store
 6471                            .read_with(cx, |lsp_store, _| {
 6472                                let server = lsp_store.language_server_for_id(server_id)?;
 6473                                let adapter =
 6474                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6475                                Some((server, adapter))
 6476                            })
 6477                            .ok()
 6478                            .flatten();
 6479                        let Some((server, adapter)) = server_and_adapter else {
 6480                            continue;
 6481                        };
 6482
 6483                        let resolved = Self::resolve_completion_local(
 6484                            server,
 6485                            completions.clone(),
 6486                            completion_index,
 6487                        )
 6488                        .await
 6489                        .log_err()
 6490                        .is_some();
 6491                        if resolved {
 6492                            Self::regenerate_completion_labels(
 6493                                adapter,
 6494                                &buffer_snapshot,
 6495                                completions.clone(),
 6496                                completion_index,
 6497                            )
 6498                            .await
 6499                            .log_err();
 6500                            did_resolve = true;
 6501                        }
 6502                    } else {
 6503                        resolve_word_completion(
 6504                            &buffer_snapshot,
 6505                            &mut completions.borrow_mut()[completion_index],
 6506                        );
 6507                    }
 6508                }
 6509            }
 6510
 6511            Ok(did_resolve)
 6512        })
 6513    }
 6514
 6515    async fn resolve_completion_local(
 6516        server: Arc<lsp::LanguageServer>,
 6517        completions: Rc<RefCell<Box<[Completion]>>>,
 6518        completion_index: usize,
 6519    ) -> Result<()> {
 6520        let server_id = server.server_id();
 6521        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6522            return Ok(());
 6523        }
 6524
 6525        let request = {
 6526            let completion = &completions.borrow()[completion_index];
 6527            match &completion.source {
 6528                CompletionSource::Lsp {
 6529                    lsp_completion,
 6530                    resolved,
 6531                    server_id: completion_server_id,
 6532                    ..
 6533                } => {
 6534                    if *resolved {
 6535                        return Ok(());
 6536                    }
 6537                    anyhow::ensure!(
 6538                        server_id == *completion_server_id,
 6539                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6540                    );
 6541                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6542                }
 6543                CompletionSource::BufferWord { .. }
 6544                | CompletionSource::Dap { .. }
 6545                | CompletionSource::Custom => {
 6546                    return Ok(());
 6547                }
 6548            }
 6549        };
 6550        let resolved_completion = request
 6551            .await
 6552            .into_response()
 6553            .context("resolve completion")?;
 6554
 6555        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6556        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6557
 6558        let mut completions = completions.borrow_mut();
 6559        let completion = &mut completions[completion_index];
 6560        if let CompletionSource::Lsp {
 6561            lsp_completion,
 6562            resolved,
 6563            server_id: completion_server_id,
 6564            ..
 6565        } = &mut completion.source
 6566        {
 6567            if *resolved {
 6568                return Ok(());
 6569            }
 6570            anyhow::ensure!(
 6571                server_id == *completion_server_id,
 6572                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6573            );
 6574            **lsp_completion = resolved_completion;
 6575            *resolved = true;
 6576        }
 6577        Ok(())
 6578    }
 6579
 6580    async fn regenerate_completion_labels(
 6581        adapter: Arc<CachedLspAdapter>,
 6582        snapshot: &BufferSnapshot,
 6583        completions: Rc<RefCell<Box<[Completion]>>>,
 6584        completion_index: usize,
 6585    ) -> Result<()> {
 6586        let completion_item = completions.borrow()[completion_index]
 6587            .source
 6588            .lsp_completion(true)
 6589            .map(Cow::into_owned);
 6590        if let Some(lsp_documentation) = completion_item
 6591            .as_ref()
 6592            .and_then(|completion_item| completion_item.documentation.clone())
 6593        {
 6594            let mut completions = completions.borrow_mut();
 6595            let completion = &mut completions[completion_index];
 6596            completion.documentation = Some(lsp_documentation.into());
 6597        } else {
 6598            let mut completions = completions.borrow_mut();
 6599            let completion = &mut completions[completion_index];
 6600            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6601        }
 6602
 6603        let mut new_label = match completion_item {
 6604            Some(completion_item) => {
 6605                // Some language servers always return `detail` lazily via resolve, regardless of
 6606                // the resolvable properties Zed advertises. Regenerate labels here to handle this.
 6607                // See: https://github.com/yioneko/vtsls/issues/213
 6608                let language = snapshot.language();
 6609                match language {
 6610                    Some(language) => {
 6611                        adapter
 6612                            .labels_for_completions(
 6613                                std::slice::from_ref(&completion_item),
 6614                                language,
 6615                            )
 6616                            .await?
 6617                    }
 6618                    None => Vec::new(),
 6619                }
 6620                .pop()
 6621                .flatten()
 6622                .unwrap_or_else(|| {
 6623                    CodeLabel::fallback_for_completion(
 6624                        &completion_item,
 6625                        language.map(|language| language.as_ref()),
 6626                    )
 6627                })
 6628            }
 6629            None => CodeLabel::plain(
 6630                completions.borrow()[completion_index].new_text.clone(),
 6631                None,
 6632            ),
 6633        };
 6634        ensure_uniform_list_compatible_label(&mut new_label);
 6635
 6636        let mut completions = completions.borrow_mut();
 6637        let completion = &mut completions[completion_index];
 6638        if completion.label.filter_text() == new_label.filter_text() {
 6639            completion.label = new_label;
 6640        } else {
 6641            log::error!(
 6642                "Resolved completion changed display label from {} to {}. \
 6643                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6644                completion.label.text(),
 6645                new_label.text(),
 6646                completion.label.filter_text(),
 6647                new_label.filter_text()
 6648            );
 6649        }
 6650
 6651        Ok(())
 6652    }
 6653
 6654    async fn resolve_completion_remote(
 6655        project_id: u64,
 6656        server_id: LanguageServerId,
 6657        buffer_id: BufferId,
 6658        completions: Rc<RefCell<Box<[Completion]>>>,
 6659        completion_index: usize,
 6660        client: AnyProtoClient,
 6661    ) -> Result<()> {
 6662        let lsp_completion = {
 6663            let completion = &completions.borrow()[completion_index];
 6664            match &completion.source {
 6665                CompletionSource::Lsp {
 6666                    lsp_completion,
 6667                    resolved,
 6668                    server_id: completion_server_id,
 6669                    ..
 6670                } => {
 6671                    anyhow::ensure!(
 6672                        server_id == *completion_server_id,
 6673                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6674                    );
 6675                    if *resolved {
 6676                        return Ok(());
 6677                    }
 6678                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6679                }
 6680                CompletionSource::Custom
 6681                | CompletionSource::Dap { .. }
 6682                | CompletionSource::BufferWord { .. } => {
 6683                    return Ok(());
 6684                }
 6685            }
 6686        };
 6687        let request = proto::ResolveCompletionDocumentation {
 6688            project_id,
 6689            language_server_id: server_id.0 as u64,
 6690            lsp_completion,
 6691            buffer_id: buffer_id.into(),
 6692        };
 6693
 6694        let response = client
 6695            .request(request)
 6696            .await
 6697            .context("completion documentation resolve proto request")?;
 6698        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6699
 6700        let documentation = if response.documentation.is_empty() {
 6701            CompletionDocumentation::Undocumented
 6702        } else if response.documentation_is_markdown {
 6703            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6704        } else if response.documentation.lines().count() <= 1 {
 6705            CompletionDocumentation::SingleLine(response.documentation.into())
 6706        } else {
 6707            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6708        };
 6709
 6710        let mut completions = completions.borrow_mut();
 6711        let completion = &mut completions[completion_index];
 6712        completion.documentation = Some(documentation);
 6713        if let CompletionSource::Lsp {
 6714            insert_range,
 6715            lsp_completion,
 6716            resolved,
 6717            server_id: completion_server_id,
 6718            lsp_defaults: _,
 6719        } = &mut completion.source
 6720        {
 6721            let completion_insert_range = response
 6722                .old_insert_start
 6723                .and_then(deserialize_anchor)
 6724                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6725            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6726
 6727            if *resolved {
 6728                return Ok(());
 6729            }
 6730            anyhow::ensure!(
 6731                server_id == *completion_server_id,
 6732                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6733            );
 6734            **lsp_completion = resolved_lsp_completion;
 6735            *resolved = true;
 6736        }
 6737
 6738        let replace_range = response
 6739            .old_replace_start
 6740            .and_then(deserialize_anchor)
 6741            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6742        if let Some((old_replace_start, old_replace_end)) = replace_range
 6743            && !response.new_text.is_empty()
 6744        {
 6745            completion.new_text = response.new_text;
 6746            completion.replace_range = old_replace_start..old_replace_end;
 6747        }
 6748
 6749        Ok(())
 6750    }
 6751
 6752    pub fn apply_additional_edits_for_completion(
 6753        &self,
 6754        buffer_handle: Entity<Buffer>,
 6755        completions: Rc<RefCell<Box<[Completion]>>>,
 6756        completion_index: usize,
 6757        push_to_history: bool,
 6758        cx: &mut Context<Self>,
 6759    ) -> Task<Result<Option<Transaction>>> {
 6760        if let Some((client, project_id)) = self.upstream_client() {
 6761            let buffer = buffer_handle.read(cx);
 6762            let buffer_id = buffer.remote_id();
 6763            cx.spawn(async move |_, cx| {
 6764                let request = {
 6765                    let completion = completions.borrow()[completion_index].clone();
 6766                    proto::ApplyCompletionAdditionalEdits {
 6767                        project_id,
 6768                        buffer_id: buffer_id.into(),
 6769                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6770                            replace_range: completion.replace_range,
 6771                            new_text: completion.new_text,
 6772                            source: completion.source,
 6773                        })),
 6774                    }
 6775                };
 6776
 6777                if let Some(transaction) = client.request(request).await?.transaction {
 6778                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6779                    buffer_handle
 6780                        .update(cx, |buffer, _| {
 6781                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6782                        })
 6783                        .await?;
 6784                    if push_to_history {
 6785                        buffer_handle.update(cx, |buffer, _| {
 6786                            buffer.push_transaction(transaction.clone(), Instant::now());
 6787                            buffer.finalize_last_transaction();
 6788                        });
 6789                    }
 6790                    Ok(Some(transaction))
 6791                } else {
 6792                    Ok(None)
 6793                }
 6794            })
 6795        } else {
 6796            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6797                let completion = &completions.borrow()[completion_index];
 6798                let server_id = completion.source.server_id()?;
 6799                Some(
 6800                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6801                        .1
 6802                        .clone(),
 6803                )
 6804            }) else {
 6805                return Task::ready(Ok(None));
 6806            };
 6807
 6808            cx.spawn(async move |this, cx| {
 6809                Self::resolve_completion_local(
 6810                    server.clone(),
 6811                    completions.clone(),
 6812                    completion_index,
 6813                )
 6814                .await
 6815                .context("resolving completion")?;
 6816                let completion = completions.borrow()[completion_index].clone();
 6817                let additional_text_edits = completion
 6818                    .source
 6819                    .lsp_completion(true)
 6820                    .as_ref()
 6821                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6822                if let Some(edits) = additional_text_edits {
 6823                    let edits = this
 6824                        .update(cx, |this, cx| {
 6825                            this.as_local_mut().unwrap().edits_from_lsp(
 6826                                &buffer_handle,
 6827                                edits,
 6828                                server.server_id(),
 6829                                None,
 6830                                cx,
 6831                            )
 6832                        })?
 6833                        .await?;
 6834
 6835                    buffer_handle.update(cx, |buffer, cx| {
 6836                        buffer.finalize_last_transaction();
 6837                        buffer.start_transaction();
 6838
 6839                        for (range, text) in edits {
 6840                            let primary = &completion.replace_range;
 6841
 6842                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6843                            // and the primary completion is just an insertion (empty range), then this is likely
 6844                            // an auto-import scenario and should not be considered overlapping
 6845                            // https://github.com/zed-industries/zed/issues/26136
 6846                            let is_file_start_auto_import = {
 6847                                let snapshot = buffer.snapshot();
 6848                                let primary_start_point = primary.start.to_point(&snapshot);
 6849                                let range_start_point = range.start.to_point(&snapshot);
 6850
 6851                                let result = primary_start_point.row == 0
 6852                                    && primary_start_point.column == 0
 6853                                    && range_start_point.row == 0
 6854                                    && range_start_point.column == 0;
 6855
 6856                                result
 6857                            };
 6858
 6859                            let has_overlap = if is_file_start_auto_import {
 6860                                false
 6861                            } else {
 6862                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6863                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6864                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6865                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6866                                let result = start_within || end_within;
 6867                                result
 6868                            };
 6869
 6870                            //Skip additional edits which overlap with the primary completion edit
 6871                            //https://github.com/zed-industries/zed/pull/1871
 6872                            if !has_overlap {
 6873                                buffer.edit([(range, text)], None, cx);
 6874                            }
 6875                        }
 6876
 6877                        let transaction = if buffer.end_transaction(cx).is_some() {
 6878                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6879                            if !push_to_history {
 6880                                buffer.forget_transaction(transaction.id);
 6881                            }
 6882                            Some(transaction)
 6883                        } else {
 6884                            None
 6885                        };
 6886                        Ok(transaction)
 6887                    })
 6888                } else {
 6889                    Ok(None)
 6890                }
 6891            })
 6892        }
 6893    }
 6894
 6895    pub fn pull_diagnostics(
 6896        &mut self,
 6897        buffer: Entity<Buffer>,
 6898        cx: &mut Context<Self>,
 6899    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6900        let buffer_id = buffer.read(cx).remote_id();
 6901
 6902        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6903            let mut suitable_capabilities = None;
 6904            // Are we capable for proto request?
 6905            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6906                &buffer,
 6907                |capabilities| {
 6908                    if let Some(caps) = &capabilities.diagnostic_provider {
 6909                        suitable_capabilities = Some(caps.clone());
 6910                        true
 6911                    } else {
 6912                        false
 6913                    }
 6914                },
 6915                cx,
 6916            );
 6917            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6918            let Some(dynamic_caps) = suitable_capabilities else {
 6919                return Task::ready(Ok(None));
 6920            };
 6921            assert!(any_server_has_diagnostics_provider);
 6922
 6923            let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6924            let request = GetDocumentDiagnostics {
 6925                previous_result_id: None,
 6926                identifier,
 6927                registration_id: None,
 6928            };
 6929            let request_task = client.request_lsp(
 6930                upstream_project_id,
 6931                None,
 6932                LSP_REQUEST_TIMEOUT,
 6933                cx.background_executor().clone(),
 6934                request.to_proto(upstream_project_id, buffer.read(cx)),
 6935            );
 6936            cx.background_spawn(async move {
 6937                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6938                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6939                // Do not attempt to further process the dummy responses here.
 6940                let _response = request_task.await?;
 6941                Ok(None)
 6942            })
 6943        } else {
 6944            let servers = buffer.update(cx, |buffer, cx| {
 6945                self.running_language_servers_for_local_buffer(buffer, cx)
 6946                    .map(|(_, server)| server.clone())
 6947                    .collect::<Vec<_>>()
 6948            });
 6949
 6950            let pull_diagnostics = servers
 6951                .into_iter()
 6952                .flat_map(|server| {
 6953                    let result = maybe!({
 6954                        let local = self.as_local()?;
 6955                        let server_id = server.server_id();
 6956                        let providers_with_identifiers = local
 6957                            .language_server_dynamic_registrations
 6958                            .get(&server_id)
 6959                            .into_iter()
 6960                            .flat_map(|registrations| registrations.diagnostics.clone())
 6961                            .collect::<Vec<_>>();
 6962                        Some(
 6963                            providers_with_identifiers
 6964                                .into_iter()
 6965                                .map(|(registration_id, dynamic_caps)| {
 6966                                    let identifier = buffer_diagnostic_identifier(&dynamic_caps);
 6967                                    let registration_id = registration_id.map(SharedString::from);
 6968                                    let result_id = self.result_id_for_buffer_pull(
 6969                                        server_id,
 6970                                        buffer_id,
 6971                                        &registration_id,
 6972                                        cx,
 6973                                    );
 6974                                    self.request_lsp(
 6975                                        buffer.clone(),
 6976                                        LanguageServerToQuery::Other(server_id),
 6977                                        GetDocumentDiagnostics {
 6978                                            previous_result_id: result_id,
 6979                                            registration_id,
 6980                                            identifier,
 6981                                        },
 6982                                        cx,
 6983                                    )
 6984                                })
 6985                                .collect::<Vec<_>>(),
 6986                        )
 6987                    });
 6988
 6989                    result.unwrap_or_default()
 6990                })
 6991                .collect::<Vec<_>>();
 6992
 6993            cx.background_spawn(async move {
 6994                let mut responses = Vec::new();
 6995                for diagnostics in join_all(pull_diagnostics).await {
 6996                    responses.extend(diagnostics?);
 6997                }
 6998                Ok(Some(responses))
 6999            })
 7000        }
 7001    }
 7002
 7003    pub fn applicable_inlay_chunks(
 7004        &mut self,
 7005        buffer: &Entity<Buffer>,
 7006        ranges: &[Range<text::Anchor>],
 7007        cx: &mut Context<Self>,
 7008    ) -> Vec<Range<BufferRow>> {
 7009        let buffer_snapshot = buffer.read(cx).snapshot();
 7010        let ranges = ranges
 7011            .iter()
 7012            .map(|range| range.to_point(&buffer_snapshot))
 7013            .collect::<Vec<_>>();
 7014
 7015        self.latest_lsp_data(buffer, cx)
 7016            .inlay_hints
 7017            .applicable_chunks(ranges.as_slice())
 7018            .map(|chunk| chunk.row_range())
 7019            .collect()
 7020    }
 7021
 7022    pub fn invalidate_inlay_hints<'a>(
 7023        &'a mut self,
 7024        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 7025    ) {
 7026        for buffer_id in for_buffers {
 7027            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 7028                lsp_data.inlay_hints.clear();
 7029            }
 7030        }
 7031    }
 7032
 7033    pub fn inlay_hints(
 7034        &mut self,
 7035        invalidate: InvalidationStrategy,
 7036        buffer: Entity<Buffer>,
 7037        ranges: Vec<Range<text::Anchor>>,
 7038        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 7039        cx: &mut Context<Self>,
 7040    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 7041        let next_hint_id = self.next_hint_id.clone();
 7042        let lsp_data = self.latest_lsp_data(&buffer, cx);
 7043        let query_version = lsp_data.buffer_version.clone();
 7044        let mut lsp_refresh_requested = false;
 7045        let for_server = if let InvalidationStrategy::RefreshRequested {
 7046            server_id,
 7047            request_id,
 7048        } = invalidate
 7049        {
 7050            let invalidated = lsp_data
 7051                .inlay_hints
 7052                .invalidate_for_server_refresh(server_id, request_id);
 7053            lsp_refresh_requested = invalidated;
 7054            Some(server_id)
 7055        } else {
 7056            None
 7057        };
 7058        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 7059        let known_chunks = known_chunks
 7060            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 7061            .map(|(_, known_chunks)| known_chunks)
 7062            .unwrap_or_default();
 7063
 7064        let buffer_snapshot = buffer.read(cx).snapshot();
 7065        let ranges = ranges
 7066            .iter()
 7067            .map(|range| range.to_point(&buffer_snapshot))
 7068            .collect::<Vec<_>>();
 7069
 7070        let mut hint_fetch_tasks = Vec::new();
 7071        let mut cached_inlay_hints = None;
 7072        let mut ranges_to_query = None;
 7073        let applicable_chunks = existing_inlay_hints
 7074            .applicable_chunks(ranges.as_slice())
 7075            .filter(|chunk| !known_chunks.contains(&chunk.row_range()))
 7076            .collect::<Vec<_>>();
 7077        if applicable_chunks.is_empty() {
 7078            return HashMap::default();
 7079        }
 7080
 7081        for row_chunk in applicable_chunks {
 7082            match (
 7083                existing_inlay_hints
 7084                    .cached_hints(&row_chunk)
 7085                    .filter(|_| !lsp_refresh_requested)
 7086                    .cloned(),
 7087                existing_inlay_hints
 7088                    .fetched_hints(&row_chunk)
 7089                    .as_ref()
 7090                    .filter(|_| !lsp_refresh_requested)
 7091                    .cloned(),
 7092            ) {
 7093                (None, None) => {
 7094                    let chunk_range = row_chunk.anchor_range();
 7095                    ranges_to_query
 7096                        .get_or_insert_with(Vec::new)
 7097                        .push((row_chunk, chunk_range));
 7098                }
 7099                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 7100                (Some(cached_hints), None) => {
 7101                    for (server_id, cached_hints) in cached_hints {
 7102                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7103                            cached_inlay_hints
 7104                                .get_or_insert_with(HashMap::default)
 7105                                .entry(row_chunk.row_range())
 7106                                .or_insert_with(HashMap::default)
 7107                                .entry(server_id)
 7108                                .or_insert_with(Vec::new)
 7109                                .extend(cached_hints);
 7110                        }
 7111                    }
 7112                }
 7113                (Some(cached_hints), Some(fetched_hints)) => {
 7114                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 7115                    for (server_id, cached_hints) in cached_hints {
 7116                        if for_server.is_none_or(|for_server| for_server == server_id) {
 7117                            cached_inlay_hints
 7118                                .get_or_insert_with(HashMap::default)
 7119                                .entry(row_chunk.row_range())
 7120                                .or_insert_with(HashMap::default)
 7121                                .entry(server_id)
 7122                                .or_insert_with(Vec::new)
 7123                                .extend(cached_hints);
 7124                        }
 7125                    }
 7126                }
 7127            }
 7128        }
 7129
 7130        if hint_fetch_tasks.is_empty()
 7131            && ranges_to_query
 7132                .as_ref()
 7133                .is_none_or(|ranges| ranges.is_empty())
 7134            && let Some(cached_inlay_hints) = cached_inlay_hints
 7135        {
 7136            cached_inlay_hints
 7137                .into_iter()
 7138                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7139                .collect()
 7140        } else {
 7141            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 7142                let next_hint_id = next_hint_id.clone();
 7143                let buffer = buffer.clone();
 7144                let query_version = query_version.clone();
 7145                let new_inlay_hints = cx
 7146                    .spawn(async move |lsp_store, cx| {
 7147                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 7148                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 7149                        })?;
 7150                        new_fetch_task
 7151                            .await
 7152                            .and_then(|new_hints_by_server| {
 7153                                lsp_store.update(cx, |lsp_store, cx| {
 7154                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7155                                    let update_cache = lsp_data.buffer_version == query_version;
 7156                                    if new_hints_by_server.is_empty() {
 7157                                        if update_cache {
 7158                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 7159                                        }
 7160                                        HashMap::default()
 7161                                    } else {
 7162                                        new_hints_by_server
 7163                                            .into_iter()
 7164                                            .map(|(server_id, new_hints)| {
 7165                                                let new_hints = new_hints
 7166                                                    .into_iter()
 7167                                                    .map(|new_hint| {
 7168                                                        (
 7169                                                            InlayId::Hint(next_hint_id.fetch_add(
 7170                                                                1,
 7171                                                                atomic::Ordering::AcqRel,
 7172                                                            )),
 7173                                                            new_hint,
 7174                                                        )
 7175                                                    })
 7176                                                    .collect::<Vec<_>>();
 7177                                                if update_cache {
 7178                                                    lsp_data.inlay_hints.insert_new_hints(
 7179                                                        chunk,
 7180                                                        server_id,
 7181                                                        new_hints.clone(),
 7182                                                    );
 7183                                                }
 7184                                                (server_id, new_hints)
 7185                                            })
 7186                                            .collect()
 7187                                    }
 7188                                })
 7189                            })
 7190                            .map_err(Arc::new)
 7191                    })
 7192                    .shared();
 7193
 7194                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 7195                *fetch_task = Some(new_inlay_hints.clone());
 7196                hint_fetch_tasks.push((chunk, new_inlay_hints));
 7197            }
 7198
 7199            cached_inlay_hints
 7200                .unwrap_or_default()
 7201                .into_iter()
 7202                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 7203                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 7204                    (
 7205                        chunk.row_range(),
 7206                        cx.spawn(async move |_, _| {
 7207                            hints_fetch.await.map_err(|e| {
 7208                                if e.error_code() != ErrorCode::Internal {
 7209                                    anyhow!(e.error_code())
 7210                                } else {
 7211                                    anyhow!("{e:#}")
 7212                                }
 7213                            })
 7214                        }),
 7215                    )
 7216                }))
 7217                .collect()
 7218        }
 7219    }
 7220
 7221    fn fetch_inlay_hints(
 7222        &mut self,
 7223        for_server: Option<LanguageServerId>,
 7224        buffer: &Entity<Buffer>,
 7225        range: Range<Anchor>,
 7226        cx: &mut Context<Self>,
 7227    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 7228        let request = InlayHints {
 7229            range: range.clone(),
 7230        };
 7231        if let Some((upstream_client, project_id)) = self.upstream_client() {
 7232            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7233                return Task::ready(Ok(HashMap::default()));
 7234            }
 7235            let request_task = upstream_client.request_lsp(
 7236                project_id,
 7237                for_server.map(|id| id.to_proto()),
 7238                LSP_REQUEST_TIMEOUT,
 7239                cx.background_executor().clone(),
 7240                request.to_proto(project_id, buffer.read(cx)),
 7241            );
 7242            let buffer = buffer.clone();
 7243            cx.spawn(async move |weak_lsp_store, cx| {
 7244                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 7245                    return Ok(HashMap::default());
 7246                };
 7247                let Some(responses) = request_task.await? else {
 7248                    return Ok(HashMap::default());
 7249                };
 7250
 7251                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 7252                    let lsp_store = lsp_store.clone();
 7253                    let buffer = buffer.clone();
 7254                    let cx = cx.clone();
 7255                    let request = request.clone();
 7256                    async move {
 7257                        (
 7258                            LanguageServerId::from_proto(response.server_id),
 7259                            request
 7260                                .response_from_proto(response.response, lsp_store, buffer, cx)
 7261                                .await,
 7262                        )
 7263                    }
 7264                }))
 7265                .await;
 7266
 7267                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7268                let mut has_errors = false;
 7269                let inlay_hints = inlay_hints
 7270                    .into_iter()
 7271                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 7272                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 7273                        Err(e) => {
 7274                            has_errors = true;
 7275                            log::error!("{e:#}");
 7276                            None
 7277                        }
 7278                    })
 7279                    .map(|(server_id, mut new_hints)| {
 7280                        new_hints.retain(|hint| {
 7281                            hint.position.is_valid(&buffer_snapshot)
 7282                                && range.start.is_valid(&buffer_snapshot)
 7283                                && range.end.is_valid(&buffer_snapshot)
 7284                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7285                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7286                        });
 7287                        (server_id, new_hints)
 7288                    })
 7289                    .collect::<HashMap<_, _>>();
 7290                anyhow::ensure!(
 7291                    !has_errors || !inlay_hints.is_empty(),
 7292                    "Failed to fetch inlay hints"
 7293                );
 7294                Ok(inlay_hints)
 7295            })
 7296        } else {
 7297            let inlay_hints_task = match for_server {
 7298                Some(server_id) => {
 7299                    let server_task = self.request_lsp(
 7300                        buffer.clone(),
 7301                        LanguageServerToQuery::Other(server_id),
 7302                        request,
 7303                        cx,
 7304                    );
 7305                    cx.background_spawn(async move {
 7306                        let mut responses = Vec::new();
 7307                        match server_task.await {
 7308                            Ok(response) => responses.push((server_id, response)),
 7309                            // rust-analyzer likes to error with this when its still loading up
 7310                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 7311                            Err(e) => log::error!(
 7312                                "Error handling response for inlay hints request: {e:#}"
 7313                            ),
 7314                        }
 7315                        responses
 7316                    })
 7317                }
 7318                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 7319            };
 7320            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 7321            cx.background_spawn(async move {
 7322                Ok(inlay_hints_task
 7323                    .await
 7324                    .into_iter()
 7325                    .map(|(server_id, mut new_hints)| {
 7326                        new_hints.retain(|hint| {
 7327                            hint.position.is_valid(&buffer_snapshot)
 7328                                && range.start.is_valid(&buffer_snapshot)
 7329                                && range.end.is_valid(&buffer_snapshot)
 7330                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 7331                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 7332                        });
 7333                        (server_id, new_hints)
 7334                    })
 7335                    .collect())
 7336            })
 7337        }
 7338    }
 7339
 7340    fn diagnostic_registration_exists(
 7341        &self,
 7342        server_id: LanguageServerId,
 7343        registration_id: &Option<SharedString>,
 7344    ) -> bool {
 7345        let Some(local) = self.as_local() else {
 7346            return false;
 7347        };
 7348        let Some(registrations) = local.language_server_dynamic_registrations.get(&server_id)
 7349        else {
 7350            return false;
 7351        };
 7352        let registration_key = registration_id.as_ref().map(|s| s.to_string());
 7353        registrations.diagnostics.contains_key(&registration_key)
 7354    }
 7355
 7356    pub fn pull_diagnostics_for_buffer(
 7357        &mut self,
 7358        buffer: Entity<Buffer>,
 7359        cx: &mut Context<Self>,
 7360    ) -> Task<anyhow::Result<()>> {
 7361        let diagnostics = self.pull_diagnostics(buffer, cx);
 7362        cx.spawn(async move |lsp_store, cx| {
 7363            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 7364                return Ok(());
 7365            };
 7366            lsp_store.update(cx, |lsp_store, cx| {
 7367                if lsp_store.as_local().is_none() {
 7368                    return;
 7369                }
 7370
 7371                let mut unchanged_buffers = HashMap::default();
 7372                let server_diagnostics_updates = diagnostics
 7373                    .into_iter()
 7374                    .filter_map(|diagnostics_set| match diagnostics_set {
 7375                        LspPullDiagnostics::Response {
 7376                            server_id,
 7377                            uri,
 7378                            diagnostics,
 7379                            registration_id,
 7380                        } => Some((server_id, uri, diagnostics, registration_id)),
 7381                        LspPullDiagnostics::Default => None,
 7382                    })
 7383                    .filter(|(server_id, _, _, registration_id)| {
 7384                        lsp_store.diagnostic_registration_exists(*server_id, registration_id)
 7385                    })
 7386                    .fold(
 7387                        HashMap::default(),
 7388                        |mut acc, (server_id, uri, diagnostics, new_registration_id)| {
 7389                            let (result_id, diagnostics) = match diagnostics {
 7390                                PulledDiagnostics::Unchanged { result_id } => {
 7391                                    unchanged_buffers
 7392                                        .entry(new_registration_id.clone())
 7393                                        .or_insert_with(HashSet::default)
 7394                                        .insert(uri.clone());
 7395                                    (Some(result_id), Vec::new())
 7396                                }
 7397                                PulledDiagnostics::Changed {
 7398                                    result_id,
 7399                                    diagnostics,
 7400                                } => (result_id, diagnostics),
 7401                            };
 7402                            let disk_based_sources = Cow::Owned(
 7403                                lsp_store
 7404                                    .language_server_adapter_for_id(server_id)
 7405                                    .as_ref()
 7406                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 7407                                    .unwrap_or(&[])
 7408                                    .to_vec(),
 7409                            );
 7410                            acc.entry(server_id)
 7411                                .or_insert_with(HashMap::default)
 7412                                .entry(new_registration_id.clone())
 7413                                .or_insert_with(Vec::new)
 7414                                .push(DocumentDiagnosticsUpdate {
 7415                                    server_id,
 7416                                    diagnostics: lsp::PublishDiagnosticsParams {
 7417                                        uri,
 7418                                        diagnostics,
 7419                                        version: None,
 7420                                    },
 7421                                    result_id,
 7422                                    disk_based_sources,
 7423                                    registration_id: new_registration_id,
 7424                                });
 7425                            acc
 7426                        },
 7427                    );
 7428
 7429                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7430                    for (registration_id, diagnostic_updates) in diagnostic_updates {
 7431                        lsp_store
 7432                            .merge_lsp_diagnostics(
 7433                                DiagnosticSourceKind::Pulled,
 7434                                diagnostic_updates,
 7435                                |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
 7436                                    DiagnosticSourceKind::Pulled => {
 7437                                        old_diagnostic.registration_id != registration_id
 7438                                            || unchanged_buffers
 7439                                                .get(&old_diagnostic.registration_id)
 7440                                                .is_some_and(|unchanged_buffers| {
 7441                                                    unchanged_buffers.contains(&document_uri)
 7442                                                })
 7443                                    }
 7444                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
 7445                                        true
 7446                                    }
 7447                                },
 7448                                cx,
 7449                            )
 7450                            .log_err();
 7451                    }
 7452                }
 7453            })
 7454        })
 7455    }
 7456
 7457    pub fn document_colors(
 7458        &mut self,
 7459        known_cache_version: Option<usize>,
 7460        buffer: Entity<Buffer>,
 7461        cx: &mut Context<Self>,
 7462    ) -> Option<DocumentColorTask> {
 7463        let version_queried_for = buffer.read(cx).version();
 7464        let buffer_id = buffer.read(cx).remote_id();
 7465
 7466        let current_language_servers = self.as_local().map(|local| {
 7467            local
 7468                .buffers_opened_in_servers
 7469                .get(&buffer_id)
 7470                .cloned()
 7471                .unwrap_or_default()
 7472        });
 7473
 7474        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7475            if let Some(cached_colors) = &lsp_data.document_colors {
 7476                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7477                    let has_different_servers =
 7478                        current_language_servers.is_some_and(|current_language_servers| {
 7479                            current_language_servers
 7480                                != cached_colors.colors.keys().copied().collect()
 7481                        });
 7482                    if !has_different_servers {
 7483                        let cache_version = cached_colors.cache_version;
 7484                        if Some(cache_version) == known_cache_version {
 7485                            return None;
 7486                        } else {
 7487                            return Some(
 7488                                Task::ready(Ok(DocumentColors {
 7489                                    colors: cached_colors
 7490                                        .colors
 7491                                        .values()
 7492                                        .flatten()
 7493                                        .cloned()
 7494                                        .collect(),
 7495                                    cache_version: Some(cache_version),
 7496                                }))
 7497                                .shared(),
 7498                            );
 7499                        }
 7500                    }
 7501                }
 7502            }
 7503        }
 7504
 7505        let color_lsp_data = self
 7506            .latest_lsp_data(&buffer, cx)
 7507            .document_colors
 7508            .get_or_insert_default();
 7509        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7510            && !version_queried_for.changed_since(updating_for)
 7511        {
 7512            return Some(running_update.clone());
 7513        }
 7514        let buffer_version_queried_for = version_queried_for.clone();
 7515        let new_task = cx
 7516            .spawn(async move |lsp_store, cx| {
 7517                cx.background_executor()
 7518                    .timer(Duration::from_millis(30))
 7519                    .await;
 7520                let fetched_colors = lsp_store
 7521                    .update(cx, |lsp_store, cx| {
 7522                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7523                    })?
 7524                    .await
 7525                    .context("fetching document colors")
 7526                    .map_err(Arc::new);
 7527                let fetched_colors = match fetched_colors {
 7528                    Ok(fetched_colors) => {
 7529                        if buffer.update(cx, |buffer, _| {
 7530                            buffer.version() != buffer_version_queried_for
 7531                        }) {
 7532                            return Ok(DocumentColors::default());
 7533                        }
 7534                        fetched_colors
 7535                    }
 7536                    Err(e) => {
 7537                        lsp_store
 7538                            .update(cx, |lsp_store, _| {
 7539                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7540                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7541                                        document_colors.colors_update = None;
 7542                                    }
 7543                                }
 7544                            })
 7545                            .ok();
 7546                        return Err(e);
 7547                    }
 7548                };
 7549
 7550                lsp_store
 7551                    .update(cx, |lsp_store, cx| {
 7552                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7553                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7554
 7555                        if let Some(fetched_colors) = fetched_colors {
 7556                            if lsp_data.buffer_version == buffer_version_queried_for {
 7557                                lsp_colors.colors.extend(fetched_colors);
 7558                                lsp_colors.cache_version += 1;
 7559                            } else if !lsp_data
 7560                                .buffer_version
 7561                                .changed_since(&buffer_version_queried_for)
 7562                            {
 7563                                lsp_data.buffer_version = buffer_version_queried_for;
 7564                                lsp_colors.colors = fetched_colors;
 7565                                lsp_colors.cache_version += 1;
 7566                            }
 7567                        }
 7568                        lsp_colors.colors_update = None;
 7569                        let colors = lsp_colors
 7570                            .colors
 7571                            .values()
 7572                            .flatten()
 7573                            .cloned()
 7574                            .collect::<HashSet<_>>();
 7575                        DocumentColors {
 7576                            colors,
 7577                            cache_version: Some(lsp_colors.cache_version),
 7578                        }
 7579                    })
 7580                    .map_err(Arc::new)
 7581            })
 7582            .shared();
 7583        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7584        Some(new_task)
 7585    }
 7586
 7587    fn fetch_document_colors_for_buffer(
 7588        &mut self,
 7589        buffer: &Entity<Buffer>,
 7590        cx: &mut Context<Self>,
 7591    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7592        if let Some((client, project_id)) = self.upstream_client() {
 7593            let request = GetDocumentColor {};
 7594            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7595                return Task::ready(Ok(None));
 7596            }
 7597
 7598            let request_task = client.request_lsp(
 7599                project_id,
 7600                None,
 7601                LSP_REQUEST_TIMEOUT,
 7602                cx.background_executor().clone(),
 7603                request.to_proto(project_id, buffer.read(cx)),
 7604            );
 7605            let buffer = buffer.clone();
 7606            cx.spawn(async move |lsp_store, cx| {
 7607                let Some(lsp_store) = lsp_store.upgrade() else {
 7608                    return Ok(None);
 7609                };
 7610                let colors = join_all(
 7611                    request_task
 7612                        .await
 7613                        .log_err()
 7614                        .flatten()
 7615                        .map(|response| response.payload)
 7616                        .unwrap_or_default()
 7617                        .into_iter()
 7618                        .map(|color_response| {
 7619                            let response = request.response_from_proto(
 7620                                color_response.response,
 7621                                lsp_store.clone(),
 7622                                buffer.clone(),
 7623                                cx.clone(),
 7624                            );
 7625                            async move {
 7626                                (
 7627                                    LanguageServerId::from_proto(color_response.server_id),
 7628                                    response.await.log_err().unwrap_or_default(),
 7629                                )
 7630                            }
 7631                        }),
 7632                )
 7633                .await
 7634                .into_iter()
 7635                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7636                    acc.entry(server_id)
 7637                        .or_insert_with(HashSet::default)
 7638                        .extend(colors);
 7639                    acc
 7640                });
 7641                Ok(Some(colors))
 7642            })
 7643        } else {
 7644            let document_colors_task =
 7645                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7646            cx.background_spawn(async move {
 7647                Ok(Some(
 7648                    document_colors_task
 7649                        .await
 7650                        .into_iter()
 7651                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7652                            acc.entry(server_id)
 7653                                .or_insert_with(HashSet::default)
 7654                                .extend(colors);
 7655                            acc
 7656                        })
 7657                        .into_iter()
 7658                        .collect(),
 7659                ))
 7660            })
 7661        }
 7662    }
 7663
 7664    pub fn signature_help<T: ToPointUtf16>(
 7665        &mut self,
 7666        buffer: &Entity<Buffer>,
 7667        position: T,
 7668        cx: &mut Context<Self>,
 7669    ) -> Task<Option<Vec<SignatureHelp>>> {
 7670        let position = position.to_point_utf16(buffer.read(cx));
 7671
 7672        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7673            let request = GetSignatureHelp { position };
 7674            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7675                return Task::ready(None);
 7676            }
 7677            let request_task = client.request_lsp(
 7678                upstream_project_id,
 7679                None,
 7680                LSP_REQUEST_TIMEOUT,
 7681                cx.background_executor().clone(),
 7682                request.to_proto(upstream_project_id, buffer.read(cx)),
 7683            );
 7684            let buffer = buffer.clone();
 7685            cx.spawn(async move |weak_lsp_store, cx| {
 7686                let lsp_store = weak_lsp_store.upgrade()?;
 7687                let signatures = join_all(
 7688                    request_task
 7689                        .await
 7690                        .log_err()
 7691                        .flatten()
 7692                        .map(|response| response.payload)
 7693                        .unwrap_or_default()
 7694                        .into_iter()
 7695                        .map(|response| {
 7696                            let response = GetSignatureHelp { position }.response_from_proto(
 7697                                response.response,
 7698                                lsp_store.clone(),
 7699                                buffer.clone(),
 7700                                cx.clone(),
 7701                            );
 7702                            async move { response.await.log_err().flatten() }
 7703                        }),
 7704                )
 7705                .await
 7706                .into_iter()
 7707                .flatten()
 7708                .collect();
 7709                Some(signatures)
 7710            })
 7711        } else {
 7712            let all_actions_task = self.request_multiple_lsp_locally(
 7713                buffer,
 7714                Some(position),
 7715                GetSignatureHelp { position },
 7716                cx,
 7717            );
 7718            cx.background_spawn(async move {
 7719                Some(
 7720                    all_actions_task
 7721                        .await
 7722                        .into_iter()
 7723                        .flat_map(|(_, actions)| actions)
 7724                        .collect::<Vec<_>>(),
 7725                )
 7726            })
 7727        }
 7728    }
 7729
 7730    pub fn hover(
 7731        &mut self,
 7732        buffer: &Entity<Buffer>,
 7733        position: PointUtf16,
 7734        cx: &mut Context<Self>,
 7735    ) -> Task<Option<Vec<Hover>>> {
 7736        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7737            let request = GetHover { position };
 7738            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7739                return Task::ready(None);
 7740            }
 7741            let request_task = client.request_lsp(
 7742                upstream_project_id,
 7743                None,
 7744                LSP_REQUEST_TIMEOUT,
 7745                cx.background_executor().clone(),
 7746                request.to_proto(upstream_project_id, buffer.read(cx)),
 7747            );
 7748            let buffer = buffer.clone();
 7749            cx.spawn(async move |weak_lsp_store, cx| {
 7750                let lsp_store = weak_lsp_store.upgrade()?;
 7751                let hovers = join_all(
 7752                    request_task
 7753                        .await
 7754                        .log_err()
 7755                        .flatten()
 7756                        .map(|response| response.payload)
 7757                        .unwrap_or_default()
 7758                        .into_iter()
 7759                        .map(|response| {
 7760                            let response = GetHover { position }.response_from_proto(
 7761                                response.response,
 7762                                lsp_store.clone(),
 7763                                buffer.clone(),
 7764                                cx.clone(),
 7765                            );
 7766                            async move {
 7767                                response
 7768                                    .await
 7769                                    .log_err()
 7770                                    .flatten()
 7771                                    .and_then(remove_empty_hover_blocks)
 7772                            }
 7773                        }),
 7774                )
 7775                .await
 7776                .into_iter()
 7777                .flatten()
 7778                .collect();
 7779                Some(hovers)
 7780            })
 7781        } else {
 7782            let all_actions_task = self.request_multiple_lsp_locally(
 7783                buffer,
 7784                Some(position),
 7785                GetHover { position },
 7786                cx,
 7787            );
 7788            cx.background_spawn(async move {
 7789                Some(
 7790                    all_actions_task
 7791                        .await
 7792                        .into_iter()
 7793                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7794                        .collect::<Vec<Hover>>(),
 7795                )
 7796            })
 7797        }
 7798    }
 7799
 7800    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7801        let language_registry = self.languages.clone();
 7802
 7803        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7804            let request = upstream_client.request(proto::GetProjectSymbols {
 7805                project_id: *project_id,
 7806                query: query.to_string(),
 7807            });
 7808            cx.foreground_executor().spawn(async move {
 7809                let response = request.await?;
 7810                let mut symbols = Vec::new();
 7811                let core_symbols = response
 7812                    .symbols
 7813                    .into_iter()
 7814                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7815                    .collect::<Vec<_>>();
 7816                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7817                    .await;
 7818                Ok(symbols)
 7819            })
 7820        } else if let Some(local) = self.as_local() {
 7821            struct WorkspaceSymbolsResult {
 7822                server_id: LanguageServerId,
 7823                lsp_adapter: Arc<CachedLspAdapter>,
 7824                worktree: WeakEntity<Worktree>,
 7825                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7826            }
 7827
 7828            let mut requests = Vec::new();
 7829            let mut requested_servers = BTreeSet::new();
 7830            for (seed, state) in local.language_server_ids.iter() {
 7831                let Some(worktree_handle) = self
 7832                    .worktree_store
 7833                    .read(cx)
 7834                    .worktree_for_id(seed.worktree_id, cx)
 7835                else {
 7836                    continue;
 7837                };
 7838                let worktree = worktree_handle.read(cx);
 7839                if !worktree.is_visible() {
 7840                    continue;
 7841                }
 7842
 7843                if !requested_servers.insert(state.id) {
 7844                    continue;
 7845                }
 7846
 7847                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7848                    Some(LanguageServerState::Running {
 7849                        adapter, server, ..
 7850                    }) => (adapter.clone(), server),
 7851
 7852                    _ => continue,
 7853                };
 7854                let supports_workspace_symbol_request =
 7855                    match server.capabilities().workspace_symbol_provider {
 7856                        Some(OneOf::Left(supported)) => supported,
 7857                        Some(OneOf::Right(_)) => true,
 7858                        None => false,
 7859                    };
 7860                if !supports_workspace_symbol_request {
 7861                    continue;
 7862                }
 7863                let worktree_handle = worktree_handle.clone();
 7864                let server_id = server.server_id();
 7865                requests.push(
 7866                    server
 7867                        .request::<lsp::request::WorkspaceSymbolRequest>(
 7868                            lsp::WorkspaceSymbolParams {
 7869                                query: query.to_string(),
 7870                                ..Default::default()
 7871                            },
 7872                        )
 7873                        .map(move |response| {
 7874                            let lsp_symbols = response
 7875                                .into_response()
 7876                                .context("workspace symbols request")
 7877                                .log_err()
 7878                                .flatten()
 7879                                .map(|symbol_response| match symbol_response {
 7880                                    lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7881                                        flat_responses
 7882                                            .into_iter()
 7883                                            .map(|lsp_symbol| {
 7884                                                (
 7885                                                    lsp_symbol.name,
 7886                                                    lsp_symbol.kind,
 7887                                                    lsp_symbol.location,
 7888                                                )
 7889                                            })
 7890                                            .collect::<Vec<_>>()
 7891                                    }
 7892                                    lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7893                                        nested_responses
 7894                                            .into_iter()
 7895                                            .filter_map(|lsp_symbol| {
 7896                                                let location = match lsp_symbol.location {
 7897                                                    OneOf::Left(location) => location,
 7898                                                    OneOf::Right(_) => {
 7899                                                        log::error!(
 7900                                                            "Unexpected: client capabilities \
 7901                                                            forbid symbol resolutions in \
 7902                                                            workspace.symbol.resolveSupport"
 7903                                                        );
 7904                                                        return None;
 7905                                                    }
 7906                                                };
 7907                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7908                                            })
 7909                                            .collect::<Vec<_>>()
 7910                                    }
 7911                                })
 7912                                .unwrap_or_default();
 7913
 7914                            WorkspaceSymbolsResult {
 7915                                server_id,
 7916                                lsp_adapter,
 7917                                worktree: worktree_handle.downgrade(),
 7918                                lsp_symbols,
 7919                            }
 7920                        }),
 7921                );
 7922            }
 7923
 7924            cx.spawn(async move |this, cx| {
 7925                let responses = futures::future::join_all(requests).await;
 7926                let this = match this.upgrade() {
 7927                    Some(this) => this,
 7928                    None => return Ok(Vec::new()),
 7929                };
 7930
 7931                let mut symbols = Vec::new();
 7932                for result in responses {
 7933                    let core_symbols = this.update(cx, |this, cx| {
 7934                        result
 7935                            .lsp_symbols
 7936                            .into_iter()
 7937                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7938                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7939                                let source_worktree = result.worktree.upgrade()?;
 7940                                let source_worktree_id = source_worktree.read(cx).id();
 7941
 7942                                let path = if let Some((tree, rel_path)) =
 7943                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7944                                {
 7945                                    let worktree_id = tree.read(cx).id();
 7946                                    SymbolLocation::InProject(ProjectPath {
 7947                                        worktree_id,
 7948                                        path: rel_path,
 7949                                    })
 7950                                } else {
 7951                                    SymbolLocation::OutsideProject {
 7952                                        signature: this.symbol_signature(&abs_path),
 7953                                        abs_path: abs_path.into(),
 7954                                    }
 7955                                };
 7956
 7957                                Some(CoreSymbol {
 7958                                    source_language_server_id: result.server_id,
 7959                                    language_server_name: result.lsp_adapter.name.clone(),
 7960                                    source_worktree_id,
 7961                                    path,
 7962                                    kind: symbol_kind,
 7963                                    name: symbol_name,
 7964                                    range: range_from_lsp(symbol_location.range),
 7965                                })
 7966                            })
 7967                            .collect::<Vec<_>>()
 7968                    });
 7969
 7970                    populate_labels_for_symbols(
 7971                        core_symbols,
 7972                        &language_registry,
 7973                        Some(result.lsp_adapter),
 7974                        &mut symbols,
 7975                    )
 7976                    .await;
 7977                }
 7978
 7979                Ok(symbols)
 7980            })
 7981        } else {
 7982            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7983        }
 7984    }
 7985
 7986    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7987        let mut summary = DiagnosticSummary::default();
 7988        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7989            summary.error_count += path_summary.error_count;
 7990            summary.warning_count += path_summary.warning_count;
 7991        }
 7992        summary
 7993    }
 7994
 7995    /// Returns the diagnostic summary for a specific project path.
 7996    pub fn diagnostic_summary_for_path(
 7997        &self,
 7998        project_path: &ProjectPath,
 7999        _: &App,
 8000    ) -> DiagnosticSummary {
 8001        if let Some(summaries) = self
 8002            .diagnostic_summaries
 8003            .get(&project_path.worktree_id)
 8004            .and_then(|map| map.get(&project_path.path))
 8005        {
 8006            let (error_count, warning_count) = summaries.iter().fold(
 8007                (0, 0),
 8008                |(error_count, warning_count), (_language_server_id, summary)| {
 8009                    (
 8010                        error_count + summary.error_count,
 8011                        warning_count + summary.warning_count,
 8012                    )
 8013                },
 8014            );
 8015
 8016            DiagnosticSummary {
 8017                error_count,
 8018                warning_count,
 8019            }
 8020        } else {
 8021            DiagnosticSummary::default()
 8022        }
 8023    }
 8024
 8025    pub fn diagnostic_summaries<'a>(
 8026        &'a self,
 8027        include_ignored: bool,
 8028        cx: &'a App,
 8029    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 8030        self.worktree_store
 8031            .read(cx)
 8032            .visible_worktrees(cx)
 8033            .filter_map(|worktree| {
 8034                let worktree = worktree.read(cx);
 8035                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 8036            })
 8037            .flat_map(move |(worktree, summaries)| {
 8038                let worktree_id = worktree.id();
 8039                summaries
 8040                    .iter()
 8041                    .filter(move |(path, _)| {
 8042                        include_ignored
 8043                            || worktree
 8044                                .entry_for_path(path.as_ref())
 8045                                .is_some_and(|entry| !entry.is_ignored)
 8046                    })
 8047                    .flat_map(move |(path, summaries)| {
 8048                        summaries.iter().map(move |(server_id, summary)| {
 8049                            (
 8050                                ProjectPath {
 8051                                    worktree_id,
 8052                                    path: path.clone(),
 8053                                },
 8054                                *server_id,
 8055                                *summary,
 8056                            )
 8057                        })
 8058                    })
 8059            })
 8060    }
 8061
 8062    pub fn on_buffer_edited(
 8063        &mut self,
 8064        buffer: Entity<Buffer>,
 8065        cx: &mut Context<Self>,
 8066    ) -> Option<()> {
 8067        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 8068            Some(
 8069                self.as_local()?
 8070                    .language_servers_for_buffer(buffer, cx)
 8071                    .map(|i| i.1.clone())
 8072                    .collect(),
 8073            )
 8074        })?;
 8075
 8076        let buffer = buffer.read(cx);
 8077        let file = File::from_dyn(buffer.file())?;
 8078        let abs_path = file.as_local()?.abs_path(cx);
 8079        let uri = lsp::Uri::from_file_path(&abs_path)
 8080            .ok()
 8081            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 8082            .log_err()?;
 8083        let next_snapshot = buffer.text_snapshot();
 8084        for language_server in language_servers {
 8085            let language_server = language_server.clone();
 8086
 8087            let buffer_snapshots = self
 8088                .as_local_mut()?
 8089                .buffer_snapshots
 8090                .get_mut(&buffer.remote_id())
 8091                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 8092            let previous_snapshot = buffer_snapshots.last()?;
 8093
 8094            let build_incremental_change = || {
 8095                buffer
 8096                    .edits_since::<Dimensions<PointUtf16, usize>>(
 8097                        previous_snapshot.snapshot.version(),
 8098                    )
 8099                    .map(|edit| {
 8100                        let edit_start = edit.new.start.0;
 8101                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 8102                        let new_text = next_snapshot
 8103                            .text_for_range(edit.new.start.1..edit.new.end.1)
 8104                            .collect();
 8105                        lsp::TextDocumentContentChangeEvent {
 8106                            range: Some(lsp::Range::new(
 8107                                point_to_lsp(edit_start),
 8108                                point_to_lsp(edit_end),
 8109                            )),
 8110                            range_length: None,
 8111                            text: new_text,
 8112                        }
 8113                    })
 8114                    .collect()
 8115            };
 8116
 8117            let document_sync_kind = language_server
 8118                .capabilities()
 8119                .text_document_sync
 8120                .as_ref()
 8121                .and_then(|sync| match sync {
 8122                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 8123                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 8124                });
 8125
 8126            let content_changes: Vec<_> = match document_sync_kind {
 8127                Some(lsp::TextDocumentSyncKind::FULL) => {
 8128                    vec![lsp::TextDocumentContentChangeEvent {
 8129                        range: None,
 8130                        range_length: None,
 8131                        text: next_snapshot.text(),
 8132                    }]
 8133                }
 8134                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 8135                _ => {
 8136                    #[cfg(any(test, feature = "test-support"))]
 8137                    {
 8138                        build_incremental_change()
 8139                    }
 8140
 8141                    #[cfg(not(any(test, feature = "test-support")))]
 8142                    {
 8143                        continue;
 8144                    }
 8145                }
 8146            };
 8147
 8148            let next_version = previous_snapshot.version + 1;
 8149            buffer_snapshots.push(LspBufferSnapshot {
 8150                version: next_version,
 8151                snapshot: next_snapshot.clone(),
 8152            });
 8153
 8154            language_server
 8155                .notify::<lsp::notification::DidChangeTextDocument>(
 8156                    lsp::DidChangeTextDocumentParams {
 8157                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 8158                            uri.clone(),
 8159                            next_version,
 8160                        ),
 8161                        content_changes,
 8162                    },
 8163                )
 8164                .ok();
 8165            self.pull_workspace_diagnostics(language_server.server_id());
 8166        }
 8167
 8168        None
 8169    }
 8170
 8171    pub fn on_buffer_saved(
 8172        &mut self,
 8173        buffer: Entity<Buffer>,
 8174        cx: &mut Context<Self>,
 8175    ) -> Option<()> {
 8176        let file = File::from_dyn(buffer.read(cx).file())?;
 8177        let worktree_id = file.worktree_id(cx);
 8178        let abs_path = file.as_local()?.abs_path(cx);
 8179        let text_document = lsp::TextDocumentIdentifier {
 8180            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 8181        };
 8182        let local = self.as_local()?;
 8183
 8184        for server in local.language_servers_for_worktree(worktree_id) {
 8185            if let Some(include_text) = include_text(server.as_ref()) {
 8186                let text = if include_text {
 8187                    Some(buffer.read(cx).text())
 8188                } else {
 8189                    None
 8190                };
 8191                server
 8192                    .notify::<lsp::notification::DidSaveTextDocument>(
 8193                        lsp::DidSaveTextDocumentParams {
 8194                            text_document: text_document.clone(),
 8195                            text,
 8196                        },
 8197                    )
 8198                    .ok();
 8199            }
 8200        }
 8201
 8202        let language_servers = buffer.update(cx, |buffer, cx| {
 8203            local.language_server_ids_for_buffer(buffer, cx)
 8204        });
 8205        for language_server_id in language_servers {
 8206            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 8207        }
 8208
 8209        None
 8210    }
 8211
 8212    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 8213        maybe!(async move {
 8214            let mut refreshed_servers = HashSet::default();
 8215            let servers = lsp_store
 8216                .update(cx, |lsp_store, cx| {
 8217                    let local = lsp_store.as_local()?;
 8218
 8219                    let servers = local
 8220                        .language_server_ids
 8221                        .iter()
 8222                        .filter_map(|(seed, state)| {
 8223                            let worktree = lsp_store
 8224                                .worktree_store
 8225                                .read(cx)
 8226                                .worktree_for_id(seed.worktree_id, cx);
 8227                            let delegate: Arc<dyn LspAdapterDelegate> =
 8228                                worktree.map(|worktree| {
 8229                                    LocalLspAdapterDelegate::new(
 8230                                        local.languages.clone(),
 8231                                        &local.environment,
 8232                                        cx.weak_entity(),
 8233                                        &worktree,
 8234                                        local.http_client.clone(),
 8235                                        local.fs.clone(),
 8236                                        cx,
 8237                                    )
 8238                                })?;
 8239                            let server_id = state.id;
 8240
 8241                            let states = local.language_servers.get(&server_id)?;
 8242
 8243                            match states {
 8244                                LanguageServerState::Starting { .. } => None,
 8245                                LanguageServerState::Running {
 8246                                    adapter, server, ..
 8247                                } => {
 8248                                    let adapter = adapter.clone();
 8249                                    let server = server.clone();
 8250                                    refreshed_servers.insert(server.name());
 8251                                    let toolchain = seed.toolchain.clone();
 8252                                    Some(cx.spawn(async move |_, cx| {
 8253                                        let settings =
 8254                                            LocalLspStore::workspace_configuration_for_adapter(
 8255                                                adapter.adapter.clone(),
 8256                                                &delegate,
 8257                                                toolchain,
 8258                                                None,
 8259                                                cx,
 8260                                            )
 8261                                            .await
 8262                                            .ok()?;
 8263                                        server
 8264                                            .notify::<lsp::notification::DidChangeConfiguration>(
 8265                                                lsp::DidChangeConfigurationParams { settings },
 8266                                            )
 8267                                            .ok()?;
 8268                                        Some(())
 8269                                    }))
 8270                                }
 8271                            }
 8272                        })
 8273                        .collect::<Vec<_>>();
 8274
 8275                    Some(servers)
 8276                })
 8277                .ok()
 8278                .flatten()?;
 8279
 8280            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 8281            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 8282            // to stop and unregister its language server wrapper.
 8283            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 8284            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 8285            let _: Vec<Option<()>> = join_all(servers).await;
 8286
 8287            Some(())
 8288        })
 8289        .await;
 8290    }
 8291
 8292    fn maintain_workspace_config(
 8293        external_refresh_requests: watch::Receiver<()>,
 8294        cx: &mut Context<Self>,
 8295    ) -> Task<Result<()>> {
 8296        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 8297        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 8298
 8299        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 8300            *settings_changed_tx.borrow_mut() = ();
 8301        });
 8302
 8303        let mut joint_future =
 8304            futures::stream::select(settings_changed_rx, external_refresh_requests);
 8305        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 8306        // - 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).
 8307        // - 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.
 8308        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 8309        // - 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,
 8310        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 8311        cx.spawn(async move |this, cx| {
 8312            while let Some(()) = joint_future.next().await {
 8313                this.update(cx, |this, cx| {
 8314                    this.refresh_server_tree(cx);
 8315                })
 8316                .ok();
 8317
 8318                Self::refresh_workspace_configurations(&this, cx).await;
 8319            }
 8320
 8321            drop(settings_observation);
 8322            anyhow::Ok(())
 8323        })
 8324    }
 8325
 8326    pub fn running_language_servers_for_local_buffer<'a>(
 8327        &'a self,
 8328        buffer: &Buffer,
 8329        cx: &mut App,
 8330    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8331        let local = self.as_local();
 8332        let language_server_ids = local
 8333            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8334            .unwrap_or_default();
 8335
 8336        language_server_ids
 8337            .into_iter()
 8338            .filter_map(
 8339                move |server_id| match local?.language_servers.get(&server_id)? {
 8340                    LanguageServerState::Running {
 8341                        adapter, server, ..
 8342                    } => Some((adapter, server)),
 8343                    _ => None,
 8344                },
 8345            )
 8346    }
 8347
 8348    pub fn language_servers_for_local_buffer(
 8349        &self,
 8350        buffer: &Buffer,
 8351        cx: &mut App,
 8352    ) -> Vec<LanguageServerId> {
 8353        let local = self.as_local();
 8354        local
 8355            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 8356            .unwrap_or_default()
 8357    }
 8358
 8359    pub fn language_server_for_local_buffer<'a>(
 8360        &'a self,
 8361        buffer: &'a Buffer,
 8362        server_id: LanguageServerId,
 8363        cx: &'a mut App,
 8364    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 8365        self.as_local()?
 8366            .language_servers_for_buffer(buffer, cx)
 8367            .find(|(_, s)| s.server_id() == server_id)
 8368    }
 8369
 8370    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 8371        self.diagnostic_summaries.remove(&id_to_remove);
 8372        if let Some(local) = self.as_local_mut() {
 8373            let to_remove = local.remove_worktree(id_to_remove, cx);
 8374            for server in to_remove {
 8375                self.language_server_statuses.remove(&server);
 8376            }
 8377        }
 8378    }
 8379
 8380    pub fn shared(
 8381        &mut self,
 8382        project_id: u64,
 8383        downstream_client: AnyProtoClient,
 8384        _: &mut Context<Self>,
 8385    ) {
 8386        self.downstream_client = Some((downstream_client.clone(), project_id));
 8387
 8388        for (server_id, status) in &self.language_server_statuses {
 8389            if let Some(server) = self.language_server_for_id(*server_id) {
 8390                downstream_client
 8391                    .send(proto::StartLanguageServer {
 8392                        project_id,
 8393                        server: Some(proto::LanguageServer {
 8394                            id: server_id.to_proto(),
 8395                            name: status.name.to_string(),
 8396                            worktree_id: status.worktree.map(|id| id.to_proto()),
 8397                        }),
 8398                        capabilities: serde_json::to_string(&server.capabilities())
 8399                            .expect("serializing server LSP capabilities"),
 8400                    })
 8401                    .log_err();
 8402            }
 8403        }
 8404    }
 8405
 8406    pub fn disconnected_from_host(&mut self) {
 8407        self.downstream_client.take();
 8408    }
 8409
 8410    pub fn disconnected_from_ssh_remote(&mut self) {
 8411        if let LspStoreMode::Remote(RemoteLspStore {
 8412            upstream_client, ..
 8413        }) = &mut self.mode
 8414        {
 8415            upstream_client.take();
 8416        }
 8417    }
 8418
 8419    pub(crate) fn set_language_server_statuses_from_proto(
 8420        &mut self,
 8421        project: WeakEntity<Project>,
 8422        language_servers: Vec<proto::LanguageServer>,
 8423        server_capabilities: Vec<String>,
 8424        cx: &mut Context<Self>,
 8425    ) {
 8426        let lsp_logs = cx
 8427            .try_global::<GlobalLogStore>()
 8428            .map(|lsp_store| lsp_store.0.clone());
 8429
 8430        self.language_server_statuses = language_servers
 8431            .into_iter()
 8432            .zip(server_capabilities)
 8433            .map(|(server, server_capabilities)| {
 8434                let server_id = LanguageServerId(server.id as usize);
 8435                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8436                    self.lsp_server_capabilities
 8437                        .insert(server_id, server_capabilities);
 8438                }
 8439
 8440                let name = LanguageServerName::from_proto(server.name);
 8441                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8442
 8443                if let Some(lsp_logs) = &lsp_logs {
 8444                    lsp_logs.update(cx, |lsp_logs, cx| {
 8445                        lsp_logs.add_language_server(
 8446                            // Only remote clients get their language servers set from proto
 8447                            LanguageServerKind::Remote {
 8448                                project: project.clone(),
 8449                            },
 8450                            server_id,
 8451                            Some(name.clone()),
 8452                            worktree,
 8453                            None,
 8454                            cx,
 8455                        );
 8456                    });
 8457                }
 8458
 8459                (
 8460                    server_id,
 8461                    LanguageServerStatus {
 8462                        name,
 8463                        server_version: None,
 8464                        pending_work: Default::default(),
 8465                        has_pending_diagnostic_updates: false,
 8466                        progress_tokens: Default::default(),
 8467                        worktree,
 8468                        binary: None,
 8469                        configuration: None,
 8470                        workspace_folders: BTreeSet::new(),
 8471                    },
 8472                )
 8473            })
 8474            .collect();
 8475    }
 8476
 8477    #[cfg(feature = "test-support")]
 8478    pub fn update_diagnostic_entries(
 8479        &mut self,
 8480        server_id: LanguageServerId,
 8481        abs_path: PathBuf,
 8482        result_id: Option<SharedString>,
 8483        version: Option<i32>,
 8484        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8485        cx: &mut Context<Self>,
 8486    ) -> anyhow::Result<()> {
 8487        self.merge_diagnostic_entries(
 8488            vec![DocumentDiagnosticsUpdate {
 8489                diagnostics: DocumentDiagnostics {
 8490                    diagnostics,
 8491                    document_abs_path: abs_path,
 8492                    version,
 8493                },
 8494                result_id,
 8495                server_id,
 8496                disk_based_sources: Cow::Borrowed(&[]),
 8497                registration_id: None,
 8498            }],
 8499            |_, _, _| false,
 8500            cx,
 8501        )?;
 8502        Ok(())
 8503    }
 8504
 8505    pub fn merge_diagnostic_entries<'a>(
 8506        &mut self,
 8507        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8508        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
 8509        cx: &mut Context<Self>,
 8510    ) -> anyhow::Result<()> {
 8511        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8512        let mut updated_diagnostics_paths = HashMap::default();
 8513        for mut update in diagnostic_updates {
 8514            let abs_path = &update.diagnostics.document_abs_path;
 8515            let server_id = update.server_id;
 8516            let Some((worktree, relative_path)) =
 8517                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8518            else {
 8519                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8520                return Ok(());
 8521            };
 8522
 8523            let worktree_id = worktree.read(cx).id();
 8524            let project_path = ProjectPath {
 8525                worktree_id,
 8526                path: relative_path,
 8527            };
 8528
 8529            let document_uri = lsp::Uri::from_file_path(abs_path)
 8530                .map_err(|()| anyhow!("Failed to convert buffer path {abs_path:?} to lsp Uri"))?;
 8531            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8532                let snapshot = buffer_handle.read(cx).snapshot();
 8533                let buffer = buffer_handle.read(cx);
 8534                let reused_diagnostics = buffer
 8535                    .buffer_diagnostics(Some(server_id))
 8536                    .iter()
 8537                    .filter(|v| merge(&document_uri, &v.diagnostic, cx))
 8538                    .map(|v| {
 8539                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8540                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8541                        DiagnosticEntry {
 8542                            range: start..end,
 8543                            diagnostic: v.diagnostic.clone(),
 8544                        }
 8545                    })
 8546                    .collect::<Vec<_>>();
 8547
 8548                self.as_local_mut()
 8549                    .context("cannot merge diagnostics on a remote LspStore")?
 8550                    .update_buffer_diagnostics(
 8551                        &buffer_handle,
 8552                        server_id,
 8553                        Some(update.registration_id),
 8554                        update.result_id,
 8555                        update.diagnostics.version,
 8556                        update.diagnostics.diagnostics.clone(),
 8557                        reused_diagnostics.clone(),
 8558                        cx,
 8559                    )?;
 8560
 8561                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8562            } else if let Some(local) = self.as_local() {
 8563                let reused_diagnostics = local
 8564                    .diagnostics
 8565                    .get(&worktree_id)
 8566                    .and_then(|diagnostics_for_tree| diagnostics_for_tree.get(&project_path.path))
 8567                    .and_then(|diagnostics_by_server_id| {
 8568                        diagnostics_by_server_id
 8569                            .binary_search_by_key(&server_id, |e| e.0)
 8570                            .ok()
 8571                            .map(|ix| &diagnostics_by_server_id[ix].1)
 8572                    })
 8573                    .into_iter()
 8574                    .flatten()
 8575                    .filter(|v| merge(&document_uri, &v.diagnostic, cx));
 8576
 8577                update
 8578                    .diagnostics
 8579                    .diagnostics
 8580                    .extend(reused_diagnostics.cloned());
 8581            }
 8582
 8583            let updated = worktree.update(cx, |worktree, cx| {
 8584                self.update_worktree_diagnostics(
 8585                    worktree.id(),
 8586                    server_id,
 8587                    project_path.path.clone(),
 8588                    update.diagnostics.diagnostics,
 8589                    cx,
 8590                )
 8591            })?;
 8592            match updated {
 8593                ControlFlow::Continue(new_summary) => {
 8594                    if let Some((project_id, new_summary)) = new_summary {
 8595                        match &mut diagnostics_summary {
 8596                            Some(diagnostics_summary) => {
 8597                                diagnostics_summary
 8598                                    .more_summaries
 8599                                    .push(proto::DiagnosticSummary {
 8600                                        path: project_path.path.as_ref().to_proto(),
 8601                                        language_server_id: server_id.0 as u64,
 8602                                        error_count: new_summary.error_count,
 8603                                        warning_count: new_summary.warning_count,
 8604                                    })
 8605                            }
 8606                            None => {
 8607                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8608                                    project_id,
 8609                                    worktree_id: worktree_id.to_proto(),
 8610                                    summary: Some(proto::DiagnosticSummary {
 8611                                        path: project_path.path.as_ref().to_proto(),
 8612                                        language_server_id: server_id.0 as u64,
 8613                                        error_count: new_summary.error_count,
 8614                                        warning_count: new_summary.warning_count,
 8615                                    }),
 8616                                    more_summaries: Vec::new(),
 8617                                })
 8618                            }
 8619                        }
 8620                    }
 8621                    updated_diagnostics_paths
 8622                        .entry(server_id)
 8623                        .or_insert_with(Vec::new)
 8624                        .push(project_path);
 8625                }
 8626                ControlFlow::Break(()) => {}
 8627            }
 8628        }
 8629
 8630        if let Some((diagnostics_summary, (downstream_client, _))) =
 8631            diagnostics_summary.zip(self.downstream_client.as_ref())
 8632        {
 8633            downstream_client.send(diagnostics_summary).log_err();
 8634        }
 8635        for (server_id, paths) in updated_diagnostics_paths {
 8636            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8637        }
 8638        Ok(())
 8639    }
 8640
 8641    fn update_worktree_diagnostics(
 8642        &mut self,
 8643        worktree_id: WorktreeId,
 8644        server_id: LanguageServerId,
 8645        path_in_worktree: Arc<RelPath>,
 8646        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8647        _: &mut Context<Worktree>,
 8648    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8649        let local = match &mut self.mode {
 8650            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8651            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8652        };
 8653
 8654        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8655        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8656        let summaries_by_server_id = summaries_for_tree
 8657            .entry(path_in_worktree.clone())
 8658            .or_default();
 8659
 8660        let old_summary = summaries_by_server_id
 8661            .remove(&server_id)
 8662            .unwrap_or_default();
 8663
 8664        let new_summary = DiagnosticSummary::new(&diagnostics);
 8665        if diagnostics.is_empty() {
 8666            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8667            {
 8668                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8669                    diagnostics_by_server_id.remove(ix);
 8670                }
 8671                if diagnostics_by_server_id.is_empty() {
 8672                    diagnostics_for_tree.remove(&path_in_worktree);
 8673                }
 8674            }
 8675        } else {
 8676            summaries_by_server_id.insert(server_id, new_summary);
 8677            let diagnostics_by_server_id = diagnostics_for_tree
 8678                .entry(path_in_worktree.clone())
 8679                .or_default();
 8680            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8681                Ok(ix) => {
 8682                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8683                }
 8684                Err(ix) => {
 8685                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8686                }
 8687            }
 8688        }
 8689
 8690        if !old_summary.is_empty() || !new_summary.is_empty() {
 8691            if let Some((_, project_id)) = &self.downstream_client {
 8692                Ok(ControlFlow::Continue(Some((
 8693                    *project_id,
 8694                    proto::DiagnosticSummary {
 8695                        path: path_in_worktree.to_proto(),
 8696                        language_server_id: server_id.0 as u64,
 8697                        error_count: new_summary.error_count as u32,
 8698                        warning_count: new_summary.warning_count as u32,
 8699                    },
 8700                ))))
 8701            } else {
 8702                Ok(ControlFlow::Continue(None))
 8703            }
 8704        } else {
 8705            Ok(ControlFlow::Break(()))
 8706        }
 8707    }
 8708
 8709    pub fn open_buffer_for_symbol(
 8710        &mut self,
 8711        symbol: &Symbol,
 8712        cx: &mut Context<Self>,
 8713    ) -> Task<Result<Entity<Buffer>>> {
 8714        if let Some((client, project_id)) = self.upstream_client() {
 8715            let request = client.request(proto::OpenBufferForSymbol {
 8716                project_id,
 8717                symbol: Some(Self::serialize_symbol(symbol)),
 8718            });
 8719            cx.spawn(async move |this, cx| {
 8720                let response = request.await?;
 8721                let buffer_id = BufferId::new(response.buffer_id)?;
 8722                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8723                    .await
 8724            })
 8725        } else if let Some(local) = self.as_local() {
 8726            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8727                seed.worktree_id == symbol.source_worktree_id
 8728                    && state.id == symbol.source_language_server_id
 8729                    && symbol.language_server_name == seed.name
 8730            });
 8731            if !is_valid {
 8732                return Task::ready(Err(anyhow!(
 8733                    "language server for worktree and language not found"
 8734                )));
 8735            };
 8736
 8737            let symbol_abs_path = match &symbol.path {
 8738                SymbolLocation::InProject(project_path) => self
 8739                    .worktree_store
 8740                    .read(cx)
 8741                    .absolutize(&project_path, cx)
 8742                    .context("no such worktree"),
 8743                SymbolLocation::OutsideProject {
 8744                    abs_path,
 8745                    signature: _,
 8746                } => Ok(abs_path.to_path_buf()),
 8747            };
 8748            let symbol_abs_path = match symbol_abs_path {
 8749                Ok(abs_path) => abs_path,
 8750                Err(err) => return Task::ready(Err(err)),
 8751            };
 8752            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8753                uri
 8754            } else {
 8755                return Task::ready(Err(anyhow!("invalid symbol path")));
 8756            };
 8757
 8758            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8759        } else {
 8760            Task::ready(Err(anyhow!("no upstream client or local store")))
 8761        }
 8762    }
 8763
 8764    pub(crate) fn open_local_buffer_via_lsp(
 8765        &mut self,
 8766        abs_path: lsp::Uri,
 8767        language_server_id: LanguageServerId,
 8768        cx: &mut Context<Self>,
 8769    ) -> Task<Result<Entity<Buffer>>> {
 8770        let path_style = self.worktree_store.read(cx).path_style();
 8771        cx.spawn(async move |lsp_store, cx| {
 8772            // Escape percent-encoded string.
 8773            let current_scheme = abs_path.scheme().to_owned();
 8774            // Uri is immutable, so we can't modify the scheme
 8775
 8776            let abs_path = abs_path
 8777                .to_file_path_ext(path_style)
 8778                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8779            let p = abs_path.clone();
 8780            let yarn_worktree = lsp_store
 8781                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8782                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8783                        cx.spawn(async move |this, cx| {
 8784                            let t = this
 8785                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8786                                .ok()?;
 8787                            t.await
 8788                        })
 8789                    }),
 8790                    None => Task::ready(None),
 8791                })?
 8792                .await;
 8793            let (worktree_root_target, known_relative_path) =
 8794                if let Some((zip_root, relative_path)) = yarn_worktree {
 8795                    (zip_root, Some(relative_path))
 8796                } else {
 8797                    (Arc::<Path>::from(abs_path.as_path()), None)
 8798                };
 8799            let worktree = lsp_store.update(cx, |lsp_store, cx| {
 8800                lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8801                    worktree_store.find_worktree(&worktree_root_target, cx)
 8802                })
 8803            })?;
 8804            let (worktree, relative_path, source_ws) = if let Some(result) = worktree {
 8805                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8806                (result.0, relative_path, None)
 8807            } else {
 8808                let worktree = lsp_store
 8809                    .update(cx, |lsp_store, cx| {
 8810                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8811                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8812                        })
 8813                    })?
 8814                    .await?;
 8815                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path());
 8816                let source_ws = if worktree.read_with(cx, |worktree, _| worktree.is_local()) {
 8817                    lsp_store
 8818                        .update(cx, |lsp_store, cx| {
 8819                            if let Some(local) = lsp_store.as_local_mut() {
 8820                                local.register_language_server_for_invisible_worktree(
 8821                                    &worktree,
 8822                                    language_server_id,
 8823                                    cx,
 8824                                )
 8825                            }
 8826                            match lsp_store.language_server_statuses.get(&language_server_id) {
 8827                                Some(status) => status.worktree,
 8828                                None => None,
 8829                            }
 8830                        })
 8831                        .ok()
 8832                        .flatten()
 8833                        .zip(Some(worktree_root.clone()))
 8834                } else {
 8835                    None
 8836                };
 8837                let relative_path = if let Some(known_path) = known_relative_path {
 8838                    known_path
 8839                } else {
 8840                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8841                        .into_arc()
 8842                };
 8843                (worktree, relative_path, source_ws)
 8844            };
 8845            let project_path = ProjectPath {
 8846                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id()),
 8847                path: relative_path,
 8848            };
 8849            let buffer = lsp_store
 8850                .update(cx, |lsp_store, cx| {
 8851                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8852                        buffer_store.open_buffer(project_path, cx)
 8853                    })
 8854                })?
 8855                .await?;
 8856            // we want to adhere to the read-only settings of the worktree we came from in case we opened an invisible one
 8857            if let Some((source_ws, worktree_root)) = source_ws {
 8858                buffer.update(cx, |buffer, cx| {
 8859                    let settings = WorktreeSettings::get(
 8860                        Some(
 8861                            (&ProjectPath {
 8862                                worktree_id: source_ws,
 8863                                path: Arc::from(RelPath::empty()),
 8864                            })
 8865                                .into(),
 8866                        ),
 8867                        cx,
 8868                    );
 8869                    let is_read_only = settings.is_std_path_read_only(&worktree_root);
 8870                    if is_read_only {
 8871                        buffer.set_capability(Capability::ReadOnly, cx);
 8872                    }
 8873                });
 8874            }
 8875            Ok(buffer)
 8876        })
 8877    }
 8878
 8879    fn request_multiple_lsp_locally<P, R>(
 8880        &mut self,
 8881        buffer: &Entity<Buffer>,
 8882        position: Option<P>,
 8883        request: R,
 8884        cx: &mut Context<Self>,
 8885    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8886    where
 8887        P: ToOffset,
 8888        R: LspCommand + Clone,
 8889        <R::LspRequest as lsp::request::Request>::Result: Send,
 8890        <R::LspRequest as lsp::request::Request>::Params: Send,
 8891    {
 8892        let Some(local) = self.as_local() else {
 8893            return Task::ready(Vec::new());
 8894        };
 8895
 8896        let snapshot = buffer.read(cx).snapshot();
 8897        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8898
 8899        let server_ids = buffer.update(cx, |buffer, cx| {
 8900            local
 8901                .language_servers_for_buffer(buffer, cx)
 8902                .filter(|(adapter, _)| {
 8903                    scope
 8904                        .as_ref()
 8905                        .map(|scope| scope.language_allowed(&adapter.name))
 8906                        .unwrap_or(true)
 8907                })
 8908                .map(|(_, server)| server.server_id())
 8909                .filter(|server_id| {
 8910                    self.as_local().is_none_or(|local| {
 8911                        local
 8912                            .buffers_opened_in_servers
 8913                            .get(&snapshot.remote_id())
 8914                            .is_some_and(|servers| servers.contains(server_id))
 8915                    })
 8916                })
 8917                .collect::<Vec<_>>()
 8918        });
 8919
 8920        let mut response_results = server_ids
 8921            .into_iter()
 8922            .map(|server_id| {
 8923                let task = self.request_lsp(
 8924                    buffer.clone(),
 8925                    LanguageServerToQuery::Other(server_id),
 8926                    request.clone(),
 8927                    cx,
 8928                );
 8929                async move { (server_id, task.await) }
 8930            })
 8931            .collect::<FuturesUnordered<_>>();
 8932
 8933        cx.background_spawn(async move {
 8934            let mut responses = Vec::with_capacity(response_results.len());
 8935            while let Some((server_id, response_result)) = response_results.next().await {
 8936                match response_result {
 8937                    Ok(response) => responses.push((server_id, response)),
 8938                    // rust-analyzer likes to error with this when its still loading up
 8939                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8940                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8941                }
 8942            }
 8943            responses
 8944        })
 8945    }
 8946
 8947    async fn handle_lsp_get_completions(
 8948        this: Entity<Self>,
 8949        envelope: TypedEnvelope<proto::GetCompletions>,
 8950        mut cx: AsyncApp,
 8951    ) -> Result<proto::GetCompletionsResponse> {
 8952        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8953
 8954        let buffer_id = GetCompletions::buffer_id_from_proto(&envelope.payload)?;
 8955        let buffer_handle = this.update(&mut cx, |this, cx| {
 8956            this.buffer_store.read(cx).get_existing(buffer_id)
 8957        })?;
 8958        let request = GetCompletions::from_proto(
 8959            envelope.payload,
 8960            this.clone(),
 8961            buffer_handle.clone(),
 8962            cx.clone(),
 8963        )
 8964        .await?;
 8965
 8966        let server_to_query = match request.server_id {
 8967            Some(server_id) => LanguageServerToQuery::Other(server_id),
 8968            None => LanguageServerToQuery::FirstCapable,
 8969        };
 8970
 8971        let response = this
 8972            .update(&mut cx, |this, cx| {
 8973                this.request_lsp(buffer_handle.clone(), server_to_query, request, cx)
 8974            })
 8975            .await?;
 8976        this.update(&mut cx, |this, cx| {
 8977            Ok(GetCompletions::response_to_proto(
 8978                response,
 8979                this,
 8980                sender_id,
 8981                &buffer_handle.read(cx).version(),
 8982                cx,
 8983            ))
 8984        })
 8985    }
 8986
 8987    async fn handle_lsp_command<T: LspCommand>(
 8988        this: Entity<Self>,
 8989        envelope: TypedEnvelope<T::ProtoRequest>,
 8990        mut cx: AsyncApp,
 8991    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8992    where
 8993        <T::LspRequest as lsp::request::Request>::Params: Send,
 8994        <T::LspRequest as lsp::request::Request>::Result: Send,
 8995    {
 8996        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8997        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8998        let buffer_handle = this.update(&mut cx, |this, cx| {
 8999            this.buffer_store.read(cx).get_existing(buffer_id)
 9000        })?;
 9001        let request = T::from_proto(
 9002            envelope.payload,
 9003            this.clone(),
 9004            buffer_handle.clone(),
 9005            cx.clone(),
 9006        )
 9007        .await?;
 9008        let response = this
 9009            .update(&mut cx, |this, cx| {
 9010                this.request_lsp(
 9011                    buffer_handle.clone(),
 9012                    LanguageServerToQuery::FirstCapable,
 9013                    request,
 9014                    cx,
 9015                )
 9016            })
 9017            .await?;
 9018        this.update(&mut cx, |this, cx| {
 9019            Ok(T::response_to_proto(
 9020                response,
 9021                this,
 9022                sender_id,
 9023                &buffer_handle.read(cx).version(),
 9024                cx,
 9025            ))
 9026        })
 9027    }
 9028
 9029    async fn handle_lsp_query(
 9030        lsp_store: Entity<Self>,
 9031        envelope: TypedEnvelope<proto::LspQuery>,
 9032        mut cx: AsyncApp,
 9033    ) -> Result<proto::Ack> {
 9034        use proto::lsp_query::Request;
 9035        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9036        let lsp_query = envelope.payload;
 9037        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 9038        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 9039        match lsp_query.request.context("invalid LSP query request")? {
 9040            Request::GetReferences(get_references) => {
 9041                let position = get_references.position.clone().and_then(deserialize_anchor);
 9042                Self::query_lsp_locally::<GetReferences>(
 9043                    lsp_store,
 9044                    server_id,
 9045                    sender_id,
 9046                    lsp_request_id,
 9047                    get_references,
 9048                    position,
 9049                    &mut cx,
 9050                )
 9051                .await?;
 9052            }
 9053            Request::GetDocumentColor(get_document_color) => {
 9054                Self::query_lsp_locally::<GetDocumentColor>(
 9055                    lsp_store,
 9056                    server_id,
 9057                    sender_id,
 9058                    lsp_request_id,
 9059                    get_document_color,
 9060                    None,
 9061                    &mut cx,
 9062                )
 9063                .await?;
 9064            }
 9065            Request::GetHover(get_hover) => {
 9066                let position = get_hover.position.clone().and_then(deserialize_anchor);
 9067                Self::query_lsp_locally::<GetHover>(
 9068                    lsp_store,
 9069                    server_id,
 9070                    sender_id,
 9071                    lsp_request_id,
 9072                    get_hover,
 9073                    position,
 9074                    &mut cx,
 9075                )
 9076                .await?;
 9077            }
 9078            Request::GetCodeActions(get_code_actions) => {
 9079                Self::query_lsp_locally::<GetCodeActions>(
 9080                    lsp_store,
 9081                    server_id,
 9082                    sender_id,
 9083                    lsp_request_id,
 9084                    get_code_actions,
 9085                    None,
 9086                    &mut cx,
 9087                )
 9088                .await?;
 9089            }
 9090            Request::GetSignatureHelp(get_signature_help) => {
 9091                let position = get_signature_help
 9092                    .position
 9093                    .clone()
 9094                    .and_then(deserialize_anchor);
 9095                Self::query_lsp_locally::<GetSignatureHelp>(
 9096                    lsp_store,
 9097                    server_id,
 9098                    sender_id,
 9099                    lsp_request_id,
 9100                    get_signature_help,
 9101                    position,
 9102                    &mut cx,
 9103                )
 9104                .await?;
 9105            }
 9106            Request::GetCodeLens(get_code_lens) => {
 9107                Self::query_lsp_locally::<GetCodeLens>(
 9108                    lsp_store,
 9109                    server_id,
 9110                    sender_id,
 9111                    lsp_request_id,
 9112                    get_code_lens,
 9113                    None,
 9114                    &mut cx,
 9115                )
 9116                .await?;
 9117            }
 9118            Request::GetDefinition(get_definition) => {
 9119                let position = get_definition.position.clone().and_then(deserialize_anchor);
 9120                Self::query_lsp_locally::<GetDefinitions>(
 9121                    lsp_store,
 9122                    server_id,
 9123                    sender_id,
 9124                    lsp_request_id,
 9125                    get_definition,
 9126                    position,
 9127                    &mut cx,
 9128                )
 9129                .await?;
 9130            }
 9131            Request::GetDeclaration(get_declaration) => {
 9132                let position = get_declaration
 9133                    .position
 9134                    .clone()
 9135                    .and_then(deserialize_anchor);
 9136                Self::query_lsp_locally::<GetDeclarations>(
 9137                    lsp_store,
 9138                    server_id,
 9139                    sender_id,
 9140                    lsp_request_id,
 9141                    get_declaration,
 9142                    position,
 9143                    &mut cx,
 9144                )
 9145                .await?;
 9146            }
 9147            Request::GetTypeDefinition(get_type_definition) => {
 9148                let position = get_type_definition
 9149                    .position
 9150                    .clone()
 9151                    .and_then(deserialize_anchor);
 9152                Self::query_lsp_locally::<GetTypeDefinitions>(
 9153                    lsp_store,
 9154                    server_id,
 9155                    sender_id,
 9156                    lsp_request_id,
 9157                    get_type_definition,
 9158                    position,
 9159                    &mut cx,
 9160                )
 9161                .await?;
 9162            }
 9163            Request::GetImplementation(get_implementation) => {
 9164                let position = get_implementation
 9165                    .position
 9166                    .clone()
 9167                    .and_then(deserialize_anchor);
 9168                Self::query_lsp_locally::<GetImplementations>(
 9169                    lsp_store,
 9170                    server_id,
 9171                    sender_id,
 9172                    lsp_request_id,
 9173                    get_implementation,
 9174                    position,
 9175                    &mut cx,
 9176                )
 9177                .await?;
 9178            }
 9179            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 9180                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 9181                let version = deserialize_version(get_document_diagnostics.buffer_version());
 9182                let buffer = lsp_store.update(&mut cx, |this, cx| {
 9183                    this.buffer_store.read(cx).get_existing(buffer_id)
 9184                })?;
 9185                buffer
 9186                    .update(&mut cx, |buffer, _| {
 9187                        buffer.wait_for_version(version.clone())
 9188                    })
 9189                    .await?;
 9190                lsp_store.update(&mut cx, |lsp_store, cx| {
 9191                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 9192                    let key = LspKey {
 9193                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 9194                        server_queried: server_id,
 9195                    };
 9196                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 9197                    ) {
 9198                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 9199                            lsp_requests.clear();
 9200                        };
 9201                    }
 9202
 9203                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 9204                    existing_queries.insert(
 9205                        lsp_request_id,
 9206                        cx.spawn(async move |lsp_store, cx| {
 9207                            let diagnostics_pull = lsp_store.update(cx, |lsp_store, cx| {
 9208                                lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 9209                            });
 9210                            if let Ok(diagnostics_pull) = diagnostics_pull {
 9211                                match diagnostics_pull.await {
 9212                                    Ok(()) => {}
 9213                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 9214                                };
 9215                            }
 9216                        }),
 9217                    );
 9218                });
 9219            }
 9220            Request::InlayHints(inlay_hints) => {
 9221                let query_start = inlay_hints
 9222                    .start
 9223                    .clone()
 9224                    .and_then(deserialize_anchor)
 9225                    .context("invalid inlay hints range start")?;
 9226                let query_end = inlay_hints
 9227                    .end
 9228                    .clone()
 9229                    .and_then(deserialize_anchor)
 9230                    .context("invalid inlay hints range end")?;
 9231                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 9232                    &lsp_store,
 9233                    server_id,
 9234                    lsp_request_id,
 9235                    &inlay_hints,
 9236                    query_start..query_end,
 9237                    &mut cx,
 9238                )
 9239                .await
 9240                .context("preparing inlay hints request")?;
 9241                Self::query_lsp_locally::<InlayHints>(
 9242                    lsp_store,
 9243                    server_id,
 9244                    sender_id,
 9245                    lsp_request_id,
 9246                    inlay_hints,
 9247                    None,
 9248                    &mut cx,
 9249                )
 9250                .await
 9251                .context("querying for inlay hints")?
 9252            }
 9253        }
 9254        Ok(proto::Ack {})
 9255    }
 9256
 9257    async fn handle_lsp_query_response(
 9258        lsp_store: Entity<Self>,
 9259        envelope: TypedEnvelope<proto::LspQueryResponse>,
 9260        cx: AsyncApp,
 9261    ) -> Result<()> {
 9262        lsp_store.read_with(&cx, |lsp_store, _| {
 9263            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 9264                upstream_client.handle_lsp_response(envelope.clone());
 9265            }
 9266        });
 9267        Ok(())
 9268    }
 9269
 9270    async fn handle_apply_code_action(
 9271        this: Entity<Self>,
 9272        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 9273        mut cx: AsyncApp,
 9274    ) -> Result<proto::ApplyCodeActionResponse> {
 9275        let sender_id = envelope.original_sender_id().unwrap_or_default();
 9276        let action =
 9277            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 9278        let apply_code_action = this.update(&mut cx, |this, cx| {
 9279            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9280            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9281            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 9282        })?;
 9283
 9284        let project_transaction = apply_code_action.await?;
 9285        let project_transaction = this.update(&mut cx, |this, cx| {
 9286            this.buffer_store.update(cx, |buffer_store, cx| {
 9287                buffer_store.serialize_project_transaction_for_peer(
 9288                    project_transaction,
 9289                    sender_id,
 9290                    cx,
 9291                )
 9292            })
 9293        });
 9294        Ok(proto::ApplyCodeActionResponse {
 9295            transaction: Some(project_transaction),
 9296        })
 9297    }
 9298
 9299    async fn handle_register_buffer_with_language_servers(
 9300        this: Entity<Self>,
 9301        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 9302        mut cx: AsyncApp,
 9303    ) -> Result<proto::Ack> {
 9304        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9305        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 9306        this.update(&mut cx, |this, cx| {
 9307            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 9308                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 9309                    project_id: upstream_project_id,
 9310                    buffer_id: buffer_id.to_proto(),
 9311                    only_servers: envelope.payload.only_servers,
 9312                });
 9313            }
 9314
 9315            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 9316                anyhow::bail!("buffer is not open");
 9317            };
 9318
 9319            let handle = this.register_buffer_with_language_servers(
 9320                &buffer,
 9321                envelope
 9322                    .payload
 9323                    .only_servers
 9324                    .into_iter()
 9325                    .filter_map(|selector| {
 9326                        Some(match selector.selector? {
 9327                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9328                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9329                            }
 9330                            proto::language_server_selector::Selector::Name(name) => {
 9331                                LanguageServerSelector::Name(LanguageServerName(
 9332                                    SharedString::from(name),
 9333                                ))
 9334                            }
 9335                        })
 9336                    })
 9337                    .collect(),
 9338                false,
 9339                cx,
 9340            );
 9341            // Pull diagnostics for the buffer even if it was already registered.
 9342            // This is needed to make test_streamed_lsp_pull_diagnostics pass,
 9343            // but it's unclear if we need it.
 9344            this.pull_diagnostics_for_buffer(buffer.clone(), cx)
 9345                .detach();
 9346            this.buffer_store().update(cx, |buffer_store, _| {
 9347                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 9348            });
 9349
 9350            Ok(())
 9351        })?;
 9352        Ok(proto::Ack {})
 9353    }
 9354
 9355    async fn handle_rename_project_entry(
 9356        this: Entity<Self>,
 9357        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 9358        mut cx: AsyncApp,
 9359    ) -> Result<proto::ProjectEntryResponse> {
 9360        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 9361        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 9362        let new_path =
 9363            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 9364
 9365        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 9366            .update(&mut cx, |this, cx| {
 9367                let (worktree, entry) = this
 9368                    .worktree_store
 9369                    .read(cx)
 9370                    .worktree_and_entry_for_id(entry_id, cx)?;
 9371                let new_worktree = this
 9372                    .worktree_store
 9373                    .read(cx)
 9374                    .worktree_for_id(new_worktree_id, cx)?;
 9375                Some((
 9376                    this.worktree_store.clone(),
 9377                    worktree,
 9378                    new_worktree,
 9379                    entry.clone(),
 9380                ))
 9381            })
 9382            .context("worktree not found")?;
 9383        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 9384            (worktree.absolutize(&old_entry.path), worktree.id())
 9385        });
 9386        let new_abs_path =
 9387            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path));
 9388
 9389        let _transaction = Self::will_rename_entry(
 9390            this.downgrade(),
 9391            old_worktree_id,
 9392            &old_abs_path,
 9393            &new_abs_path,
 9394            old_entry.is_dir(),
 9395            cx.clone(),
 9396        )
 9397        .await;
 9398        let response = WorktreeStore::handle_rename_project_entry(
 9399            worktree_store,
 9400            envelope.payload,
 9401            cx.clone(),
 9402        )
 9403        .await;
 9404        this.read_with(&cx, |this, _| {
 9405            this.did_rename_entry(
 9406                old_worktree_id,
 9407                &old_abs_path,
 9408                &new_abs_path,
 9409                old_entry.is_dir(),
 9410            );
 9411        });
 9412        response
 9413    }
 9414
 9415    async fn handle_update_diagnostic_summary(
 9416        this: Entity<Self>,
 9417        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 9418        mut cx: AsyncApp,
 9419    ) -> Result<()> {
 9420        this.update(&mut cx, |lsp_store, cx| {
 9421            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 9422            let mut updated_diagnostics_paths = HashMap::default();
 9423            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 9424            for message_summary in envelope
 9425                .payload
 9426                .summary
 9427                .into_iter()
 9428                .chain(envelope.payload.more_summaries)
 9429            {
 9430                let project_path = ProjectPath {
 9431                    worktree_id,
 9432                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 9433                };
 9434                let path = project_path.path.clone();
 9435                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 9436                let summary = DiagnosticSummary {
 9437                    error_count: message_summary.error_count as usize,
 9438                    warning_count: message_summary.warning_count as usize,
 9439                };
 9440
 9441                if summary.is_empty() {
 9442                    if let Some(worktree_summaries) =
 9443                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 9444                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 9445                    {
 9446                        summaries.remove(&server_id);
 9447                        if summaries.is_empty() {
 9448                            worktree_summaries.remove(&path);
 9449                        }
 9450                    }
 9451                } else {
 9452                    lsp_store
 9453                        .diagnostic_summaries
 9454                        .entry(worktree_id)
 9455                        .or_default()
 9456                        .entry(path)
 9457                        .or_default()
 9458                        .insert(server_id, summary);
 9459                }
 9460
 9461                if let Some((_, project_id)) = &lsp_store.downstream_client {
 9462                    match &mut diagnostics_summary {
 9463                        Some(diagnostics_summary) => {
 9464                            diagnostics_summary
 9465                                .more_summaries
 9466                                .push(proto::DiagnosticSummary {
 9467                                    path: project_path.path.as_ref().to_proto(),
 9468                                    language_server_id: server_id.0 as u64,
 9469                                    error_count: summary.error_count as u32,
 9470                                    warning_count: summary.warning_count as u32,
 9471                                })
 9472                        }
 9473                        None => {
 9474                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 9475                                project_id: *project_id,
 9476                                worktree_id: worktree_id.to_proto(),
 9477                                summary: Some(proto::DiagnosticSummary {
 9478                                    path: project_path.path.as_ref().to_proto(),
 9479                                    language_server_id: server_id.0 as u64,
 9480                                    error_count: summary.error_count as u32,
 9481                                    warning_count: summary.warning_count as u32,
 9482                                }),
 9483                                more_summaries: Vec::new(),
 9484                            })
 9485                        }
 9486                    }
 9487                }
 9488                updated_diagnostics_paths
 9489                    .entry(server_id)
 9490                    .or_insert_with(Vec::new)
 9491                    .push(project_path);
 9492            }
 9493
 9494            if let Some((diagnostics_summary, (downstream_client, _))) =
 9495                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 9496            {
 9497                downstream_client.send(diagnostics_summary).log_err();
 9498            }
 9499            for (server_id, paths) in updated_diagnostics_paths {
 9500                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 9501            }
 9502            Ok(())
 9503        })
 9504    }
 9505
 9506    async fn handle_start_language_server(
 9507        lsp_store: Entity<Self>,
 9508        envelope: TypedEnvelope<proto::StartLanguageServer>,
 9509        mut cx: AsyncApp,
 9510    ) -> Result<()> {
 9511        let server = envelope.payload.server.context("invalid server")?;
 9512        let server_capabilities =
 9513            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 9514                .with_context(|| {
 9515                    format!(
 9516                        "incorrect server capabilities {}",
 9517                        envelope.payload.capabilities
 9518                    )
 9519                })?;
 9520        lsp_store.update(&mut cx, |lsp_store, cx| {
 9521            let server_id = LanguageServerId(server.id as usize);
 9522            let server_name = LanguageServerName::from_proto(server.name.clone());
 9523            lsp_store
 9524                .lsp_server_capabilities
 9525                .insert(server_id, server_capabilities);
 9526            lsp_store.language_server_statuses.insert(
 9527                server_id,
 9528                LanguageServerStatus {
 9529                    name: server_name.clone(),
 9530                    server_version: None,
 9531                    pending_work: Default::default(),
 9532                    has_pending_diagnostic_updates: false,
 9533                    progress_tokens: Default::default(),
 9534                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9535                    binary: None,
 9536                    configuration: None,
 9537                    workspace_folders: BTreeSet::new(),
 9538                },
 9539            );
 9540            cx.emit(LspStoreEvent::LanguageServerAdded(
 9541                server_id,
 9542                server_name,
 9543                server.worktree_id.map(WorktreeId::from_proto),
 9544            ));
 9545            cx.notify();
 9546        });
 9547        Ok(())
 9548    }
 9549
 9550    async fn handle_update_language_server(
 9551        lsp_store: Entity<Self>,
 9552        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9553        mut cx: AsyncApp,
 9554    ) -> Result<()> {
 9555        lsp_store.update(&mut cx, |lsp_store, cx| {
 9556            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9557
 9558            match envelope.payload.variant.context("invalid variant")? {
 9559                proto::update_language_server::Variant::WorkStart(payload) => {
 9560                    lsp_store.on_lsp_work_start(
 9561                        language_server_id,
 9562                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9563                            .context("invalid progress token value")?,
 9564                        LanguageServerProgress {
 9565                            title: payload.title,
 9566                            is_disk_based_diagnostics_progress: false,
 9567                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9568                            message: payload.message,
 9569                            percentage: payload.percentage.map(|p| p as usize),
 9570                            last_update_at: cx.background_executor().now(),
 9571                        },
 9572                        cx,
 9573                    );
 9574                }
 9575                proto::update_language_server::Variant::WorkProgress(payload) => {
 9576                    lsp_store.on_lsp_work_progress(
 9577                        language_server_id,
 9578                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9579                            .context("invalid progress token value")?,
 9580                        LanguageServerProgress {
 9581                            title: None,
 9582                            is_disk_based_diagnostics_progress: false,
 9583                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9584                            message: payload.message,
 9585                            percentage: payload.percentage.map(|p| p as usize),
 9586                            last_update_at: cx.background_executor().now(),
 9587                        },
 9588                        cx,
 9589                    );
 9590                }
 9591
 9592                proto::update_language_server::Variant::WorkEnd(payload) => {
 9593                    lsp_store.on_lsp_work_end(
 9594                        language_server_id,
 9595                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9596                            .context("invalid progress token value")?,
 9597                        cx,
 9598                    );
 9599                }
 9600
 9601                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9602                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9603                }
 9604
 9605                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9606                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9607                }
 9608
 9609                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9610                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9611                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9612                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9613                        language_server_id,
 9614                        name: envelope
 9615                            .payload
 9616                            .server_name
 9617                            .map(SharedString::new)
 9618                            .map(LanguageServerName),
 9619                        message: non_lsp,
 9620                    });
 9621                }
 9622            }
 9623
 9624            Ok(())
 9625        })
 9626    }
 9627
 9628    async fn handle_language_server_log(
 9629        this: Entity<Self>,
 9630        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9631        mut cx: AsyncApp,
 9632    ) -> Result<()> {
 9633        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9634        let log_type = envelope
 9635            .payload
 9636            .log_type
 9637            .map(LanguageServerLogType::from_proto)
 9638            .context("invalid language server log type")?;
 9639
 9640        let message = envelope.payload.message;
 9641
 9642        this.update(&mut cx, |_, cx| {
 9643            cx.emit(LspStoreEvent::LanguageServerLog(
 9644                language_server_id,
 9645                log_type,
 9646                message,
 9647            ));
 9648        });
 9649        Ok(())
 9650    }
 9651
 9652    async fn handle_lsp_ext_cancel_flycheck(
 9653        lsp_store: Entity<Self>,
 9654        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9655        cx: AsyncApp,
 9656    ) -> Result<proto::Ack> {
 9657        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9658        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9659            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9660                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9661            } else {
 9662                None
 9663            }
 9664        });
 9665        if let Some(task) = task {
 9666            task.context("handling lsp ext cancel flycheck")?;
 9667        }
 9668
 9669        Ok(proto::Ack {})
 9670    }
 9671
 9672    async fn handle_lsp_ext_run_flycheck(
 9673        lsp_store: Entity<Self>,
 9674        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9675        mut cx: AsyncApp,
 9676    ) -> Result<proto::Ack> {
 9677        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9678        lsp_store.update(&mut cx, |lsp_store, cx| {
 9679            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9680                let text_document = if envelope.payload.current_file_only {
 9681                    let buffer_id = envelope
 9682                        .payload
 9683                        .buffer_id
 9684                        .map(|id| BufferId::new(id))
 9685                        .transpose()?;
 9686                    buffer_id
 9687                        .and_then(|buffer_id| {
 9688                            lsp_store
 9689                                .buffer_store()
 9690                                .read(cx)
 9691                                .get(buffer_id)
 9692                                .and_then(|buffer| {
 9693                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9694                                })
 9695                                .map(|path| make_text_document_identifier(&path))
 9696                        })
 9697                        .transpose()?
 9698                } else {
 9699                    None
 9700                };
 9701                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9702                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9703                )?;
 9704            }
 9705            anyhow::Ok(())
 9706        })?;
 9707
 9708        Ok(proto::Ack {})
 9709    }
 9710
 9711    async fn handle_lsp_ext_clear_flycheck(
 9712        lsp_store: Entity<Self>,
 9713        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9714        cx: AsyncApp,
 9715    ) -> Result<proto::Ack> {
 9716        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9717        lsp_store.read_with(&cx, |lsp_store, _| {
 9718            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9719                Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9720            } else {
 9721                None
 9722            }
 9723        });
 9724
 9725        Ok(proto::Ack {})
 9726    }
 9727
 9728    pub fn disk_based_diagnostics_started(
 9729        &mut self,
 9730        language_server_id: LanguageServerId,
 9731        cx: &mut Context<Self>,
 9732    ) {
 9733        if let Some(language_server_status) =
 9734            self.language_server_statuses.get_mut(&language_server_id)
 9735        {
 9736            language_server_status.has_pending_diagnostic_updates = true;
 9737        }
 9738
 9739        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9740        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9741            language_server_id,
 9742            name: self
 9743                .language_server_adapter_for_id(language_server_id)
 9744                .map(|adapter| adapter.name()),
 9745            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9746                Default::default(),
 9747            ),
 9748        })
 9749    }
 9750
 9751    pub fn disk_based_diagnostics_finished(
 9752        &mut self,
 9753        language_server_id: LanguageServerId,
 9754        cx: &mut Context<Self>,
 9755    ) {
 9756        if let Some(language_server_status) =
 9757            self.language_server_statuses.get_mut(&language_server_id)
 9758        {
 9759            language_server_status.has_pending_diagnostic_updates = false;
 9760        }
 9761
 9762        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9763        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9764            language_server_id,
 9765            name: self
 9766                .language_server_adapter_for_id(language_server_id)
 9767                .map(|adapter| adapter.name()),
 9768            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9769                Default::default(),
 9770            ),
 9771        })
 9772    }
 9773
 9774    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9775    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9776    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9777    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9778    // the language server might take some time to publish diagnostics.
 9779    fn simulate_disk_based_diagnostics_events_if_needed(
 9780        &mut self,
 9781        language_server_id: LanguageServerId,
 9782        cx: &mut Context<Self>,
 9783    ) {
 9784        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9785
 9786        let Some(LanguageServerState::Running {
 9787            simulate_disk_based_diagnostics_completion,
 9788            adapter,
 9789            ..
 9790        }) = self
 9791            .as_local_mut()
 9792            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9793        else {
 9794            return;
 9795        };
 9796
 9797        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9798            return;
 9799        }
 9800
 9801        let prev_task =
 9802            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9803                cx.background_executor()
 9804                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9805                    .await;
 9806
 9807                this.update(cx, |this, cx| {
 9808                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9809
 9810                    if let Some(LanguageServerState::Running {
 9811                        simulate_disk_based_diagnostics_completion,
 9812                        ..
 9813                    }) = this.as_local_mut().and_then(|local_store| {
 9814                        local_store.language_servers.get_mut(&language_server_id)
 9815                    }) {
 9816                        *simulate_disk_based_diagnostics_completion = None;
 9817                    }
 9818                })
 9819                .ok();
 9820            }));
 9821
 9822        if prev_task.is_none() {
 9823            self.disk_based_diagnostics_started(language_server_id, cx);
 9824        }
 9825    }
 9826
 9827    pub fn language_server_statuses(
 9828        &self,
 9829    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9830        self.language_server_statuses
 9831            .iter()
 9832            .map(|(key, value)| (*key, value))
 9833    }
 9834
 9835    pub(super) fn did_rename_entry(
 9836        &self,
 9837        worktree_id: WorktreeId,
 9838        old_path: &Path,
 9839        new_path: &Path,
 9840        is_dir: bool,
 9841    ) {
 9842        maybe!({
 9843            let local_store = self.as_local()?;
 9844
 9845            let old_uri = lsp::Uri::from_file_path(old_path)
 9846                .ok()
 9847                .map(|uri| uri.to_string())?;
 9848            let new_uri = lsp::Uri::from_file_path(new_path)
 9849                .ok()
 9850                .map(|uri| uri.to_string())?;
 9851
 9852            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9853                let Some(filter) = local_store
 9854                    .language_server_paths_watched_for_rename
 9855                    .get(&language_server.server_id())
 9856                else {
 9857                    continue;
 9858                };
 9859
 9860                if filter.should_send_did_rename(&old_uri, is_dir) {
 9861                    language_server
 9862                        .notify::<DidRenameFiles>(RenameFilesParams {
 9863                            files: vec![FileRename {
 9864                                old_uri: old_uri.clone(),
 9865                                new_uri: new_uri.clone(),
 9866                            }],
 9867                        })
 9868                        .ok();
 9869                }
 9870            }
 9871            Some(())
 9872        });
 9873    }
 9874
 9875    pub(super) fn will_rename_entry(
 9876        this: WeakEntity<Self>,
 9877        worktree_id: WorktreeId,
 9878        old_path: &Path,
 9879        new_path: &Path,
 9880        is_dir: bool,
 9881        cx: AsyncApp,
 9882    ) -> Task<ProjectTransaction> {
 9883        let old_uri = lsp::Uri::from_file_path(old_path)
 9884            .ok()
 9885            .map(|uri| uri.to_string());
 9886        let new_uri = lsp::Uri::from_file_path(new_path)
 9887            .ok()
 9888            .map(|uri| uri.to_string());
 9889        cx.spawn(async move |cx| {
 9890            let mut tasks = vec![];
 9891            this.update(cx, |this, cx| {
 9892                let local_store = this.as_local()?;
 9893                let old_uri = old_uri?;
 9894                let new_uri = new_uri?;
 9895                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9896                    let Some(filter) = local_store
 9897                        .language_server_paths_watched_for_rename
 9898                        .get(&language_server.server_id())
 9899                    else {
 9900                        continue;
 9901                    };
 9902
 9903                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9904                        let apply_edit = cx.spawn({
 9905                            let old_uri = old_uri.clone();
 9906                            let new_uri = new_uri.clone();
 9907                            let language_server = language_server.clone();
 9908                            async move |this, cx| {
 9909                                let edit = language_server
 9910                                    .request::<WillRenameFiles>(RenameFilesParams {
 9911                                        files: vec![FileRename { old_uri, new_uri }],
 9912                                    })
 9913                                    .await
 9914                                    .into_response()
 9915                                    .context("will rename files")
 9916                                    .log_err()
 9917                                    .flatten()?;
 9918
 9919                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9920                                    this.upgrade()?,
 9921                                    edit,
 9922                                    false,
 9923                                    language_server.clone(),
 9924                                    cx,
 9925                                )
 9926                                .await
 9927                                .ok()?;
 9928                                Some(transaction)
 9929                            }
 9930                        });
 9931                        tasks.push(apply_edit);
 9932                    }
 9933                }
 9934                Some(())
 9935            })
 9936            .ok()
 9937            .flatten();
 9938            let mut merged_transaction = ProjectTransaction::default();
 9939            for task in tasks {
 9940                // Await on tasks sequentially so that the order of application of edits is deterministic
 9941                // (at least with regards to the order of registration of language servers)
 9942                if let Some(transaction) = task.await {
 9943                    for (buffer, buffer_transaction) in transaction.0 {
 9944                        merged_transaction.0.insert(buffer, buffer_transaction);
 9945                    }
 9946                }
 9947            }
 9948            merged_transaction
 9949        })
 9950    }
 9951
 9952    fn lsp_notify_abs_paths_changed(
 9953        &mut self,
 9954        server_id: LanguageServerId,
 9955        changes: Vec<PathEvent>,
 9956    ) {
 9957        maybe!({
 9958            let server = self.language_server_for_id(server_id)?;
 9959            let changes = changes
 9960                .into_iter()
 9961                .filter_map(|event| {
 9962                    let typ = match event.kind? {
 9963                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9964                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9965                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9966                    };
 9967                    Some(lsp::FileEvent {
 9968                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9969                        typ,
 9970                    })
 9971                })
 9972                .collect::<Vec<_>>();
 9973            if !changes.is_empty() {
 9974                server
 9975                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9976                        lsp::DidChangeWatchedFilesParams { changes },
 9977                    )
 9978                    .ok();
 9979            }
 9980            Some(())
 9981        });
 9982    }
 9983
 9984    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9985        self.as_local()?.language_server_for_id(id)
 9986    }
 9987
 9988    fn on_lsp_progress(
 9989        &mut self,
 9990        progress_params: lsp::ProgressParams,
 9991        language_server_id: LanguageServerId,
 9992        disk_based_diagnostics_progress_token: Option<String>,
 9993        cx: &mut Context<Self>,
 9994    ) {
 9995        match progress_params.value {
 9996            lsp::ProgressParamsValue::WorkDone(progress) => {
 9997                self.handle_work_done_progress(
 9998                    progress,
 9999                    language_server_id,
10000                    disk_based_diagnostics_progress_token,
10001                    ProgressToken::from_lsp(progress_params.token),
10002                    cx,
10003                );
10004            }
10005            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
10006                let registration_id = match progress_params.token {
10007                    lsp::NumberOrString::Number(_) => None,
10008                    lsp::NumberOrString::String(token) => token
10009                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
10010                        .map(|(_, id)| id.to_owned()),
10011                };
10012                if let Some(LanguageServerState::Running {
10013                    workspace_diagnostics_refresh_tasks,
10014                    ..
10015                }) = self
10016                    .as_local_mut()
10017                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
10018                    && let Some(workspace_diagnostics) =
10019                        workspace_diagnostics_refresh_tasks.get_mut(&registration_id)
10020                {
10021                    workspace_diagnostics.progress_tx.try_send(()).ok();
10022                    self.apply_workspace_diagnostic_report(
10023                        language_server_id,
10024                        report,
10025                        registration_id.map(SharedString::from),
10026                        cx,
10027                    )
10028                }
10029            }
10030        }
10031    }
10032
10033    fn handle_work_done_progress(
10034        &mut self,
10035        progress: lsp::WorkDoneProgress,
10036        language_server_id: LanguageServerId,
10037        disk_based_diagnostics_progress_token: Option<String>,
10038        token: ProgressToken,
10039        cx: &mut Context<Self>,
10040    ) {
10041        let language_server_status =
10042            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10043                status
10044            } else {
10045                return;
10046            };
10047
10048        if !language_server_status.progress_tokens.contains(&token) {
10049            return;
10050        }
10051
10052        let is_disk_based_diagnostics_progress =
10053            if let (Some(disk_based_token), ProgressToken::String(token)) =
10054                (&disk_based_diagnostics_progress_token, &token)
10055            {
10056                token.starts_with(disk_based_token)
10057            } else {
10058                false
10059            };
10060
10061        match progress {
10062            lsp::WorkDoneProgress::Begin(report) => {
10063                if is_disk_based_diagnostics_progress {
10064                    self.disk_based_diagnostics_started(language_server_id, cx);
10065                }
10066                self.on_lsp_work_start(
10067                    language_server_id,
10068                    token.clone(),
10069                    LanguageServerProgress {
10070                        title: Some(report.title),
10071                        is_disk_based_diagnostics_progress,
10072                        is_cancellable: report.cancellable.unwrap_or(false),
10073                        message: report.message.clone(),
10074                        percentage: report.percentage.map(|p| p as usize),
10075                        last_update_at: cx.background_executor().now(),
10076                    },
10077                    cx,
10078                );
10079            }
10080            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
10081                language_server_id,
10082                token,
10083                LanguageServerProgress {
10084                    title: None,
10085                    is_disk_based_diagnostics_progress,
10086                    is_cancellable: report.cancellable.unwrap_or(false),
10087                    message: report.message,
10088                    percentage: report.percentage.map(|p| p as usize),
10089                    last_update_at: cx.background_executor().now(),
10090                },
10091                cx,
10092            ),
10093            lsp::WorkDoneProgress::End(_) => {
10094                language_server_status.progress_tokens.remove(&token);
10095                self.on_lsp_work_end(language_server_id, token.clone(), cx);
10096                if is_disk_based_diagnostics_progress {
10097                    self.disk_based_diagnostics_finished(language_server_id, cx);
10098                }
10099            }
10100        }
10101    }
10102
10103    fn on_lsp_work_start(
10104        &mut self,
10105        language_server_id: LanguageServerId,
10106        token: ProgressToken,
10107        progress: LanguageServerProgress,
10108        cx: &mut Context<Self>,
10109    ) {
10110        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10111            status.pending_work.insert(token.clone(), progress.clone());
10112            cx.notify();
10113        }
10114        cx.emit(LspStoreEvent::LanguageServerUpdate {
10115            language_server_id,
10116            name: self
10117                .language_server_adapter_for_id(language_server_id)
10118                .map(|adapter| adapter.name()),
10119            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
10120                token: Some(token.to_proto()),
10121                title: progress.title,
10122                message: progress.message,
10123                percentage: progress.percentage.map(|p| p as u32),
10124                is_cancellable: Some(progress.is_cancellable),
10125            }),
10126        })
10127    }
10128
10129    fn on_lsp_work_progress(
10130        &mut self,
10131        language_server_id: LanguageServerId,
10132        token: ProgressToken,
10133        progress: LanguageServerProgress,
10134        cx: &mut Context<Self>,
10135    ) {
10136        let mut did_update = false;
10137        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10138            match status.pending_work.entry(token.clone()) {
10139                btree_map::Entry::Vacant(entry) => {
10140                    entry.insert(progress.clone());
10141                    did_update = true;
10142                }
10143                btree_map::Entry::Occupied(mut entry) => {
10144                    let entry = entry.get_mut();
10145                    if (progress.last_update_at - entry.last_update_at)
10146                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
10147                    {
10148                        entry.last_update_at = progress.last_update_at;
10149                        if progress.message.is_some() {
10150                            entry.message = progress.message.clone();
10151                        }
10152                        if progress.percentage.is_some() {
10153                            entry.percentage = progress.percentage;
10154                        }
10155                        if progress.is_cancellable != entry.is_cancellable {
10156                            entry.is_cancellable = progress.is_cancellable;
10157                        }
10158                        did_update = true;
10159                    }
10160                }
10161            }
10162        }
10163
10164        if did_update {
10165            cx.emit(LspStoreEvent::LanguageServerUpdate {
10166                language_server_id,
10167                name: self
10168                    .language_server_adapter_for_id(language_server_id)
10169                    .map(|adapter| adapter.name()),
10170                message: proto::update_language_server::Variant::WorkProgress(
10171                    proto::LspWorkProgress {
10172                        token: Some(token.to_proto()),
10173                        message: progress.message,
10174                        percentage: progress.percentage.map(|p| p as u32),
10175                        is_cancellable: Some(progress.is_cancellable),
10176                    },
10177                ),
10178            })
10179        }
10180    }
10181
10182    fn on_lsp_work_end(
10183        &mut self,
10184        language_server_id: LanguageServerId,
10185        token: ProgressToken,
10186        cx: &mut Context<Self>,
10187    ) {
10188        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
10189            if let Some(work) = status.pending_work.remove(&token)
10190                && !work.is_disk_based_diagnostics_progress
10191            {
10192                cx.emit(LspStoreEvent::RefreshInlayHints {
10193                    server_id: language_server_id,
10194                    request_id: None,
10195                });
10196            }
10197            cx.notify();
10198        }
10199
10200        cx.emit(LspStoreEvent::LanguageServerUpdate {
10201            language_server_id,
10202            name: self
10203                .language_server_adapter_for_id(language_server_id)
10204                .map(|adapter| adapter.name()),
10205            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
10206                token: Some(token.to_proto()),
10207            }),
10208        })
10209    }
10210
10211    pub async fn handle_resolve_completion_documentation(
10212        this: Entity<Self>,
10213        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
10214        mut cx: AsyncApp,
10215    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
10216        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
10217
10218        let completion = this
10219            .read_with(&cx, |this, cx| {
10220                let id = LanguageServerId(envelope.payload.language_server_id as usize);
10221                let server = this
10222                    .language_server_for_id(id)
10223                    .with_context(|| format!("No language server {id}"))?;
10224
10225                anyhow::Ok(cx.background_spawn(async move {
10226                    let can_resolve = server
10227                        .capabilities()
10228                        .completion_provider
10229                        .as_ref()
10230                        .and_then(|options| options.resolve_provider)
10231                        .unwrap_or(false);
10232                    if can_resolve {
10233                        server
10234                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
10235                            .await
10236                            .into_response()
10237                            .context("resolve completion item")
10238                    } else {
10239                        anyhow::Ok(lsp_completion)
10240                    }
10241                }))
10242            })?
10243            .await?;
10244
10245        let mut documentation_is_markdown = false;
10246        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
10247        let documentation = match completion.documentation {
10248            Some(lsp::Documentation::String(text)) => text,
10249
10250            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
10251                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
10252                value
10253            }
10254
10255            _ => String::new(),
10256        };
10257
10258        // If we have a new buffer_id, that means we're talking to a new client
10259        // and want to check for new text_edits in the completion too.
10260        let mut old_replace_start = None;
10261        let mut old_replace_end = None;
10262        let mut old_insert_start = None;
10263        let mut old_insert_end = None;
10264        let mut new_text = String::default();
10265        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
10266            let buffer_snapshot = this.update(&mut cx, |this, cx| {
10267                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10268                anyhow::Ok(buffer.read(cx).snapshot())
10269            })?;
10270
10271            if let Some(text_edit) = completion.text_edit.as_ref() {
10272                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
10273
10274                if let Some(mut edit) = edit {
10275                    LineEnding::normalize(&mut edit.new_text);
10276
10277                    new_text = edit.new_text;
10278                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
10279                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
10280                    if let Some(insert_range) = edit.insert_range {
10281                        old_insert_start = Some(serialize_anchor(&insert_range.start));
10282                        old_insert_end = Some(serialize_anchor(&insert_range.end));
10283                    }
10284                }
10285            }
10286        }
10287
10288        Ok(proto::ResolveCompletionDocumentationResponse {
10289            documentation,
10290            documentation_is_markdown,
10291            old_replace_start,
10292            old_replace_end,
10293            new_text,
10294            lsp_completion,
10295            old_insert_start,
10296            old_insert_end,
10297        })
10298    }
10299
10300    async fn handle_on_type_formatting(
10301        this: Entity<Self>,
10302        envelope: TypedEnvelope<proto::OnTypeFormatting>,
10303        mut cx: AsyncApp,
10304    ) -> Result<proto::OnTypeFormattingResponse> {
10305        let on_type_formatting = this.update(&mut cx, |this, cx| {
10306            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10307            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10308            let position = envelope
10309                .payload
10310                .position
10311                .and_then(deserialize_anchor)
10312                .context("invalid position")?;
10313            anyhow::Ok(this.apply_on_type_formatting(
10314                buffer,
10315                position,
10316                envelope.payload.trigger.clone(),
10317                cx,
10318            ))
10319        })?;
10320
10321        let transaction = on_type_formatting
10322            .await?
10323            .as_ref()
10324            .map(language::proto::serialize_transaction);
10325        Ok(proto::OnTypeFormattingResponse { transaction })
10326    }
10327
10328    async fn handle_refresh_inlay_hints(
10329        lsp_store: Entity<Self>,
10330        envelope: TypedEnvelope<proto::RefreshInlayHints>,
10331        mut cx: AsyncApp,
10332    ) -> Result<proto::Ack> {
10333        lsp_store.update(&mut cx, |_, cx| {
10334            cx.emit(LspStoreEvent::RefreshInlayHints {
10335                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
10336                request_id: envelope.payload.request_id.map(|id| id as usize),
10337            });
10338        });
10339        Ok(proto::Ack {})
10340    }
10341
10342    async fn handle_pull_workspace_diagnostics(
10343        lsp_store: Entity<Self>,
10344        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
10345        mut cx: AsyncApp,
10346    ) -> Result<proto::Ack> {
10347        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
10348        lsp_store.update(&mut cx, |lsp_store, _| {
10349            lsp_store.pull_workspace_diagnostics(server_id);
10350        });
10351        Ok(proto::Ack {})
10352    }
10353
10354    async fn handle_get_color_presentation(
10355        lsp_store: Entity<Self>,
10356        envelope: TypedEnvelope<proto::GetColorPresentation>,
10357        mut cx: AsyncApp,
10358    ) -> Result<proto::GetColorPresentationResponse> {
10359        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10360        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10361            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10362        })?;
10363
10364        let color = envelope
10365            .payload
10366            .color
10367            .context("invalid color resolve request")?;
10368        let start = color
10369            .lsp_range_start
10370            .context("invalid color resolve request")?;
10371        let end = color
10372            .lsp_range_end
10373            .context("invalid color resolve request")?;
10374
10375        let color = DocumentColor {
10376            lsp_range: lsp::Range {
10377                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
10378                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
10379            },
10380            color: lsp::Color {
10381                red: color.red,
10382                green: color.green,
10383                blue: color.blue,
10384                alpha: color.alpha,
10385            },
10386            resolved: false,
10387            color_presentations: Vec::new(),
10388        };
10389        let resolved_color = lsp_store
10390            .update(&mut cx, |lsp_store, cx| {
10391                lsp_store.resolve_color_presentation(
10392                    color,
10393                    buffer.clone(),
10394                    LanguageServerId(envelope.payload.server_id as usize),
10395                    cx,
10396                )
10397            })
10398            .await
10399            .context("resolving color presentation")?;
10400
10401        Ok(proto::GetColorPresentationResponse {
10402            presentations: resolved_color
10403                .color_presentations
10404                .into_iter()
10405                .map(|presentation| proto::ColorPresentation {
10406                    label: presentation.label.to_string(),
10407                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
10408                    additional_text_edits: presentation
10409                        .additional_text_edits
10410                        .into_iter()
10411                        .map(serialize_lsp_edit)
10412                        .collect(),
10413                })
10414                .collect(),
10415        })
10416    }
10417
10418    async fn handle_resolve_inlay_hint(
10419        lsp_store: Entity<Self>,
10420        envelope: TypedEnvelope<proto::ResolveInlayHint>,
10421        mut cx: AsyncApp,
10422    ) -> Result<proto::ResolveInlayHintResponse> {
10423        let proto_hint = envelope
10424            .payload
10425            .hint
10426            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
10427        let hint = InlayHints::proto_to_project_hint(proto_hint)
10428            .context("resolved proto inlay hint conversion")?;
10429        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
10430            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10431            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
10432        })?;
10433        let response_hint = lsp_store
10434            .update(&mut cx, |lsp_store, cx| {
10435                lsp_store.resolve_inlay_hint(
10436                    hint,
10437                    buffer,
10438                    LanguageServerId(envelope.payload.language_server_id as usize),
10439                    cx,
10440                )
10441            })
10442            .await
10443            .context("inlay hints fetch")?;
10444        Ok(proto::ResolveInlayHintResponse {
10445            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
10446        })
10447    }
10448
10449    async fn handle_refresh_code_lens(
10450        this: Entity<Self>,
10451        _: TypedEnvelope<proto::RefreshCodeLens>,
10452        mut cx: AsyncApp,
10453    ) -> Result<proto::Ack> {
10454        this.update(&mut cx, |_, cx| {
10455            cx.emit(LspStoreEvent::RefreshCodeLens);
10456        });
10457        Ok(proto::Ack {})
10458    }
10459
10460    async fn handle_open_buffer_for_symbol(
10461        this: Entity<Self>,
10462        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
10463        mut cx: AsyncApp,
10464    ) -> Result<proto::OpenBufferForSymbolResponse> {
10465        let peer_id = envelope.original_sender_id().unwrap_or_default();
10466        let symbol = envelope.payload.symbol.context("invalid symbol")?;
10467        let symbol = Self::deserialize_symbol(symbol)?;
10468        this.read_with(&cx, |this, _| {
10469            if let SymbolLocation::OutsideProject {
10470                abs_path,
10471                signature,
10472            } = &symbol.path
10473            {
10474                let new_signature = this.symbol_signature(&abs_path);
10475                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
10476            }
10477            Ok(())
10478        })?;
10479        let buffer = this
10480            .update(&mut cx, |this, cx| {
10481                this.open_buffer_for_symbol(
10482                    &Symbol {
10483                        language_server_name: symbol.language_server_name,
10484                        source_worktree_id: symbol.source_worktree_id,
10485                        source_language_server_id: symbol.source_language_server_id,
10486                        path: symbol.path,
10487                        name: symbol.name,
10488                        kind: symbol.kind,
10489                        range: symbol.range,
10490                        label: CodeLabel::default(),
10491                    },
10492                    cx,
10493                )
10494            })
10495            .await?;
10496
10497        this.update(&mut cx, |this, cx| {
10498            let is_private = buffer
10499                .read(cx)
10500                .file()
10501                .map(|f| f.is_private())
10502                .unwrap_or_default();
10503            if is_private {
10504                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
10505            } else {
10506                this.buffer_store
10507                    .update(cx, |buffer_store, cx| {
10508                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
10509                    })
10510                    .detach_and_log_err(cx);
10511                let buffer_id = buffer.read(cx).remote_id().to_proto();
10512                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
10513            }
10514        })
10515    }
10516
10517    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
10518        let mut hasher = Sha256::new();
10519        hasher.update(abs_path.to_string_lossy().as_bytes());
10520        hasher.update(self.nonce.to_be_bytes());
10521        hasher.finalize().as_slice().try_into().unwrap()
10522    }
10523
10524    pub async fn handle_get_project_symbols(
10525        this: Entity<Self>,
10526        envelope: TypedEnvelope<proto::GetProjectSymbols>,
10527        mut cx: AsyncApp,
10528    ) -> Result<proto::GetProjectSymbolsResponse> {
10529        let symbols = this
10530            .update(&mut cx, |this, cx| {
10531                this.symbols(&envelope.payload.query, cx)
10532            })
10533            .await?;
10534
10535        Ok(proto::GetProjectSymbolsResponse {
10536            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
10537        })
10538    }
10539
10540    pub async fn handle_restart_language_servers(
10541        this: Entity<Self>,
10542        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10543        mut cx: AsyncApp,
10544    ) -> Result<proto::Ack> {
10545        this.update(&mut cx, |lsp_store, cx| {
10546            let buffers =
10547                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10548            lsp_store.restart_language_servers_for_buffers(
10549                buffers,
10550                envelope
10551                    .payload
10552                    .only_servers
10553                    .into_iter()
10554                    .filter_map(|selector| {
10555                        Some(match selector.selector? {
10556                            proto::language_server_selector::Selector::ServerId(server_id) => {
10557                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10558                            }
10559                            proto::language_server_selector::Selector::Name(name) => {
10560                                LanguageServerSelector::Name(LanguageServerName(
10561                                    SharedString::from(name),
10562                                ))
10563                            }
10564                        })
10565                    })
10566                    .collect(),
10567                cx,
10568            );
10569        });
10570
10571        Ok(proto::Ack {})
10572    }
10573
10574    pub async fn handle_stop_language_servers(
10575        lsp_store: Entity<Self>,
10576        envelope: TypedEnvelope<proto::StopLanguageServers>,
10577        mut cx: AsyncApp,
10578    ) -> Result<proto::Ack> {
10579        lsp_store.update(&mut cx, |lsp_store, cx| {
10580            if envelope.payload.all
10581                && envelope.payload.also_servers.is_empty()
10582                && envelope.payload.buffer_ids.is_empty()
10583            {
10584                lsp_store.stop_all_language_servers(cx);
10585            } else {
10586                let buffers =
10587                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10588                lsp_store
10589                    .stop_language_servers_for_buffers(
10590                        buffers,
10591                        envelope
10592                            .payload
10593                            .also_servers
10594                            .into_iter()
10595                            .filter_map(|selector| {
10596                                Some(match selector.selector? {
10597                                    proto::language_server_selector::Selector::ServerId(
10598                                        server_id,
10599                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10600                                        server_id,
10601                                    )),
10602                                    proto::language_server_selector::Selector::Name(name) => {
10603                                        LanguageServerSelector::Name(LanguageServerName(
10604                                            SharedString::from(name),
10605                                        ))
10606                                    }
10607                                })
10608                            })
10609                            .collect(),
10610                        cx,
10611                    )
10612                    .detach_and_log_err(cx);
10613            }
10614        });
10615
10616        Ok(proto::Ack {})
10617    }
10618
10619    pub async fn handle_cancel_language_server_work(
10620        lsp_store: Entity<Self>,
10621        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10622        mut cx: AsyncApp,
10623    ) -> Result<proto::Ack> {
10624        lsp_store.update(&mut cx, |lsp_store, cx| {
10625            if let Some(work) = envelope.payload.work {
10626                match work {
10627                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10628                        let buffers =
10629                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10630                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10631                    }
10632                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10633                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10634                        let token = work
10635                            .token
10636                            .map(|token| {
10637                                ProgressToken::from_proto(token)
10638                                    .context("invalid work progress token")
10639                            })
10640                            .transpose()?;
10641                        lsp_store.cancel_language_server_work(server_id, token, cx);
10642                    }
10643                }
10644            }
10645            anyhow::Ok(())
10646        })?;
10647
10648        Ok(proto::Ack {})
10649    }
10650
10651    fn buffer_ids_to_buffers(
10652        &mut self,
10653        buffer_ids: impl Iterator<Item = u64>,
10654        cx: &mut Context<Self>,
10655    ) -> Vec<Entity<Buffer>> {
10656        buffer_ids
10657            .into_iter()
10658            .flat_map(|buffer_id| {
10659                self.buffer_store
10660                    .read(cx)
10661                    .get(BufferId::new(buffer_id).log_err()?)
10662            })
10663            .collect::<Vec<_>>()
10664    }
10665
10666    async fn handle_apply_additional_edits_for_completion(
10667        this: Entity<Self>,
10668        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10669        mut cx: AsyncApp,
10670    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10671        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10672            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10673            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10674            let completion = Self::deserialize_completion(
10675                envelope.payload.completion.context("invalid completion")?,
10676            )?;
10677            anyhow::Ok((buffer, completion))
10678        })?;
10679
10680        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10681            this.apply_additional_edits_for_completion(
10682                buffer,
10683                Rc::new(RefCell::new(Box::new([Completion {
10684                    replace_range: completion.replace_range,
10685                    new_text: completion.new_text,
10686                    source: completion.source,
10687                    documentation: None,
10688                    label: CodeLabel::default(),
10689                    match_start: None,
10690                    snippet_deduplication_key: None,
10691                    insert_text_mode: None,
10692                    icon_path: None,
10693                    confirm: None,
10694                }]))),
10695                0,
10696                false,
10697                cx,
10698            )
10699        });
10700
10701        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10702            transaction: apply_additional_edits
10703                .await?
10704                .as_ref()
10705                .map(language::proto::serialize_transaction),
10706        })
10707    }
10708
10709    pub fn last_formatting_failure(&self) -> Option<&str> {
10710        self.last_formatting_failure.as_deref()
10711    }
10712
10713    pub fn reset_last_formatting_failure(&mut self) {
10714        self.last_formatting_failure = None;
10715    }
10716
10717    pub fn environment_for_buffer(
10718        &self,
10719        buffer: &Entity<Buffer>,
10720        cx: &mut Context<Self>,
10721    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10722        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10723            environment.update(cx, |env, cx| {
10724                env.buffer_environment(buffer, &self.worktree_store, cx)
10725            })
10726        } else {
10727            Task::ready(None).shared()
10728        }
10729    }
10730
10731    pub fn format(
10732        &mut self,
10733        buffers: HashSet<Entity<Buffer>>,
10734        target: LspFormatTarget,
10735        push_to_history: bool,
10736        trigger: FormatTrigger,
10737        cx: &mut Context<Self>,
10738    ) -> Task<anyhow::Result<ProjectTransaction>> {
10739        let logger = zlog::scoped!("format");
10740        if self.as_local().is_some() {
10741            zlog::trace!(logger => "Formatting locally");
10742            let logger = zlog::scoped!(logger => "local");
10743            let buffers = buffers
10744                .into_iter()
10745                .map(|buffer_handle| {
10746                    let buffer = buffer_handle.read(cx);
10747                    let buffer_abs_path = File::from_dyn(buffer.file())
10748                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10749
10750                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10751                })
10752                .collect::<Vec<_>>();
10753
10754            cx.spawn(async move |lsp_store, cx| {
10755                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10756
10757                for (handle, abs_path, id) in buffers {
10758                    let env = lsp_store
10759                        .update(cx, |lsp_store, cx| {
10760                            lsp_store.environment_for_buffer(&handle, cx)
10761                        })?
10762                        .await;
10763
10764                    let ranges = match &target {
10765                        LspFormatTarget::Buffers => None,
10766                        LspFormatTarget::Ranges(ranges) => {
10767                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10768                        }
10769                    };
10770
10771                    formattable_buffers.push(FormattableBuffer {
10772                        handle,
10773                        abs_path,
10774                        env,
10775                        ranges,
10776                    });
10777                }
10778                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10779
10780                let format_timer = zlog::time!(logger => "Formatting buffers");
10781                let result = LocalLspStore::format_locally(
10782                    lsp_store.clone(),
10783                    formattable_buffers,
10784                    push_to_history,
10785                    trigger,
10786                    logger,
10787                    cx,
10788                )
10789                .await;
10790                format_timer.end();
10791
10792                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10793
10794                lsp_store.update(cx, |lsp_store, _| {
10795                    lsp_store.update_last_formatting_failure(&result);
10796                })?;
10797
10798                result
10799            })
10800        } else if let Some((client, project_id)) = self.upstream_client() {
10801            zlog::trace!(logger => "Formatting remotely");
10802            let logger = zlog::scoped!(logger => "remote");
10803
10804            let buffer_ranges = match &target {
10805                LspFormatTarget::Buffers => Vec::new(),
10806                LspFormatTarget::Ranges(ranges) => ranges
10807                    .iter()
10808                    .map(|(buffer_id, ranges)| proto::BufferFormatRanges {
10809                        buffer_id: buffer_id.to_proto(),
10810                        ranges: ranges.iter().cloned().map(serialize_anchor_range).collect(),
10811                    })
10812                    .collect(),
10813            };
10814
10815            let buffer_store = self.buffer_store();
10816            cx.spawn(async move |lsp_store, cx| {
10817                zlog::trace!(logger => "Sending remote format request");
10818                let request_timer = zlog::time!(logger => "remote format request");
10819                let result = client
10820                    .request(proto::FormatBuffers {
10821                        project_id,
10822                        trigger: trigger as i32,
10823                        buffer_ids: buffers
10824                            .iter()
10825                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().to_proto()))
10826                            .collect(),
10827                        buffer_ranges,
10828                    })
10829                    .await
10830                    .and_then(|result| result.transaction.context("missing transaction"));
10831                request_timer.end();
10832
10833                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10834
10835                lsp_store.update(cx, |lsp_store, _| {
10836                    lsp_store.update_last_formatting_failure(&result);
10837                })?;
10838
10839                let transaction_response = result?;
10840                let _timer = zlog::time!(logger => "deserializing project transaction");
10841                buffer_store
10842                    .update(cx, |buffer_store, cx| {
10843                        buffer_store.deserialize_project_transaction(
10844                            transaction_response,
10845                            push_to_history,
10846                            cx,
10847                        )
10848                    })
10849                    .await
10850            })
10851        } else {
10852            zlog::trace!(logger => "Not formatting");
10853            Task::ready(Ok(ProjectTransaction::default()))
10854        }
10855    }
10856
10857    async fn handle_format_buffers(
10858        this: Entity<Self>,
10859        envelope: TypedEnvelope<proto::FormatBuffers>,
10860        mut cx: AsyncApp,
10861    ) -> Result<proto::FormatBuffersResponse> {
10862        let sender_id = envelope.original_sender_id().unwrap_or_default();
10863        let format = this.update(&mut cx, |this, cx| {
10864            let mut buffers = HashSet::default();
10865            for buffer_id in &envelope.payload.buffer_ids {
10866                let buffer_id = BufferId::new(*buffer_id)?;
10867                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10868            }
10869
10870            let target = if envelope.payload.buffer_ranges.is_empty() {
10871                LspFormatTarget::Buffers
10872            } else {
10873                let mut ranges_map = BTreeMap::new();
10874                for buffer_range in &envelope.payload.buffer_ranges {
10875                    let buffer_id = BufferId::new(buffer_range.buffer_id)?;
10876                    let ranges: Result<Vec<_>> = buffer_range
10877                        .ranges
10878                        .iter()
10879                        .map(|range| {
10880                            deserialize_anchor_range(range.clone()).context("invalid anchor range")
10881                        })
10882                        .collect();
10883                    ranges_map.insert(buffer_id, ranges?);
10884                }
10885                LspFormatTarget::Ranges(ranges_map)
10886            };
10887
10888            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10889            anyhow::Ok(this.format(buffers, target, false, trigger, cx))
10890        })?;
10891
10892        let project_transaction = format.await?;
10893        let project_transaction = this.update(&mut cx, |this, cx| {
10894            this.buffer_store.update(cx, |buffer_store, cx| {
10895                buffer_store.serialize_project_transaction_for_peer(
10896                    project_transaction,
10897                    sender_id,
10898                    cx,
10899                )
10900            })
10901        });
10902        Ok(proto::FormatBuffersResponse {
10903            transaction: Some(project_transaction),
10904        })
10905    }
10906
10907    async fn handle_apply_code_action_kind(
10908        this: Entity<Self>,
10909        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10910        mut cx: AsyncApp,
10911    ) -> Result<proto::ApplyCodeActionKindResponse> {
10912        let sender_id = envelope.original_sender_id().unwrap_or_default();
10913        let format = this.update(&mut cx, |this, cx| {
10914            let mut buffers = HashSet::default();
10915            for buffer_id in &envelope.payload.buffer_ids {
10916                let buffer_id = BufferId::new(*buffer_id)?;
10917                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10918            }
10919            let kind = match envelope.payload.kind.as_str() {
10920                "" => CodeActionKind::EMPTY,
10921                "quickfix" => CodeActionKind::QUICKFIX,
10922                "refactor" => CodeActionKind::REFACTOR,
10923                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10924                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10925                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10926                "source" => CodeActionKind::SOURCE,
10927                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10928                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10929                _ => anyhow::bail!(
10930                    "Invalid code action kind {}",
10931                    envelope.payload.kind.as_str()
10932                ),
10933            };
10934            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10935        })?;
10936
10937        let project_transaction = format.await?;
10938        let project_transaction = this.update(&mut cx, |this, cx| {
10939            this.buffer_store.update(cx, |buffer_store, cx| {
10940                buffer_store.serialize_project_transaction_for_peer(
10941                    project_transaction,
10942                    sender_id,
10943                    cx,
10944                )
10945            })
10946        });
10947        Ok(proto::ApplyCodeActionKindResponse {
10948            transaction: Some(project_transaction),
10949        })
10950    }
10951
10952    async fn shutdown_language_server(
10953        server_state: Option<LanguageServerState>,
10954        name: LanguageServerName,
10955        cx: &mut AsyncApp,
10956    ) {
10957        let server = match server_state {
10958            Some(LanguageServerState::Starting { startup, .. }) => {
10959                let mut timer = cx
10960                    .background_executor()
10961                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10962                    .fuse();
10963
10964                select! {
10965                    server = startup.fuse() => server,
10966                    () = timer => {
10967                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10968                        None
10969                    },
10970                }
10971            }
10972
10973            Some(LanguageServerState::Running { server, .. }) => Some(server),
10974
10975            None => None,
10976        };
10977
10978        if let Some(server) = server
10979            && let Some(shutdown) = server.shutdown()
10980        {
10981            shutdown.await;
10982        }
10983    }
10984
10985    // Returns a list of all of the worktrees which no longer have a language server and the root path
10986    // for the stopped server
10987    fn stop_local_language_server(
10988        &mut self,
10989        server_id: LanguageServerId,
10990        cx: &mut Context<Self>,
10991    ) -> Task<()> {
10992        let local = match &mut self.mode {
10993            LspStoreMode::Local(local) => local,
10994            _ => {
10995                return Task::ready(());
10996            }
10997        };
10998
10999        // Remove this server ID from all entries in the given worktree.
11000        local
11001            .language_server_ids
11002            .retain(|_, state| state.id != server_id);
11003        self.buffer_store.update(cx, |buffer_store, cx| {
11004            for buffer in buffer_store.buffers() {
11005                buffer.update(cx, |buffer, cx| {
11006                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
11007                    buffer.set_completion_triggers(server_id, Default::default(), cx);
11008                });
11009            }
11010        });
11011
11012        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
11013            summaries.retain(|path, summaries_by_server_id| {
11014                if summaries_by_server_id.remove(&server_id).is_some() {
11015                    if let Some((client, project_id)) = self.downstream_client.clone() {
11016                        client
11017                            .send(proto::UpdateDiagnosticSummary {
11018                                project_id,
11019                                worktree_id: worktree_id.to_proto(),
11020                                summary: Some(proto::DiagnosticSummary {
11021                                    path: path.as_ref().to_proto(),
11022                                    language_server_id: server_id.0 as u64,
11023                                    error_count: 0,
11024                                    warning_count: 0,
11025                                }),
11026                                more_summaries: Vec::new(),
11027                            })
11028                            .log_err();
11029                    }
11030                    !summaries_by_server_id.is_empty()
11031                } else {
11032                    true
11033                }
11034            });
11035        }
11036
11037        let local = self.as_local_mut().unwrap();
11038        for diagnostics in local.diagnostics.values_mut() {
11039            diagnostics.retain(|_, diagnostics_by_server_id| {
11040                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
11041                    diagnostics_by_server_id.remove(ix);
11042                    !diagnostics_by_server_id.is_empty()
11043                } else {
11044                    true
11045                }
11046            });
11047        }
11048        local.language_server_watched_paths.remove(&server_id);
11049
11050        let server_state = local.language_servers.remove(&server_id);
11051        self.cleanup_lsp_data(server_id);
11052        let name = self
11053            .language_server_statuses
11054            .remove(&server_id)
11055            .map(|status| status.name)
11056            .or_else(|| {
11057                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
11058                    Some(adapter.name())
11059                } else {
11060                    None
11061                }
11062            });
11063
11064        if let Some(name) = name {
11065            log::info!("stopping language server {name}");
11066            self.languages
11067                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
11068            cx.notify();
11069
11070            return cx.spawn(async move |lsp_store, cx| {
11071                Self::shutdown_language_server(server_state, name.clone(), cx).await;
11072                lsp_store
11073                    .update(cx, |lsp_store, cx| {
11074                        lsp_store
11075                            .languages
11076                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
11077                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11078                        cx.notify();
11079                    })
11080                    .ok();
11081            });
11082        }
11083
11084        if server_state.is_some() {
11085            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
11086        }
11087        Task::ready(())
11088    }
11089
11090    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
11091        self.shutdown_all_language_servers(cx).detach();
11092    }
11093
11094    pub fn shutdown_all_language_servers(&mut self, cx: &mut Context<Self>) -> Task<()> {
11095        if let Some((client, project_id)) = self.upstream_client() {
11096            let request = client.request(proto::StopLanguageServers {
11097                project_id,
11098                buffer_ids: Vec::new(),
11099                also_servers: Vec::new(),
11100                all: true,
11101            });
11102            cx.background_spawn(async move {
11103                request.await.ok();
11104            })
11105        } else {
11106            let Some(local) = self.as_local_mut() else {
11107                return Task::ready(());
11108            };
11109            let language_servers_to_stop = local
11110                .language_server_ids
11111                .values()
11112                .map(|state| state.id)
11113                .collect();
11114            local.lsp_tree.remove_nodes(&language_servers_to_stop);
11115            let tasks = language_servers_to_stop
11116                .into_iter()
11117                .map(|server| self.stop_local_language_server(server, cx))
11118                .collect::<Vec<_>>();
11119            cx.background_spawn(async move {
11120                futures::future::join_all(tasks).await;
11121            })
11122        }
11123    }
11124
11125    pub fn restart_language_servers_for_buffers(
11126        &mut self,
11127        buffers: Vec<Entity<Buffer>>,
11128        only_restart_servers: HashSet<LanguageServerSelector>,
11129        cx: &mut Context<Self>,
11130    ) {
11131        if let Some((client, project_id)) = self.upstream_client() {
11132            let request = client.request(proto::RestartLanguageServers {
11133                project_id,
11134                buffer_ids: buffers
11135                    .into_iter()
11136                    .map(|b| b.read(cx).remote_id().to_proto())
11137                    .collect(),
11138                only_servers: only_restart_servers
11139                    .into_iter()
11140                    .map(|selector| {
11141                        let selector = match selector {
11142                            LanguageServerSelector::Id(language_server_id) => {
11143                                proto::language_server_selector::Selector::ServerId(
11144                                    language_server_id.to_proto(),
11145                                )
11146                            }
11147                            LanguageServerSelector::Name(language_server_name) => {
11148                                proto::language_server_selector::Selector::Name(
11149                                    language_server_name.to_string(),
11150                                )
11151                            }
11152                        };
11153                        proto::LanguageServerSelector {
11154                            selector: Some(selector),
11155                        }
11156                    })
11157                    .collect(),
11158                all: false,
11159            });
11160            cx.background_spawn(request).detach_and_log_err(cx);
11161        } else {
11162            let stop_task = if only_restart_servers.is_empty() {
11163                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
11164            } else {
11165                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
11166            };
11167            cx.spawn(async move |lsp_store, cx| {
11168                stop_task.await;
11169                lsp_store.update(cx, |lsp_store, cx| {
11170                    for buffer in buffers {
11171                        lsp_store.register_buffer_with_language_servers(
11172                            &buffer,
11173                            only_restart_servers.clone(),
11174                            true,
11175                            cx,
11176                        );
11177                    }
11178                })
11179            })
11180            .detach();
11181        }
11182    }
11183
11184    pub fn stop_language_servers_for_buffers(
11185        &mut self,
11186        buffers: Vec<Entity<Buffer>>,
11187        also_stop_servers: HashSet<LanguageServerSelector>,
11188        cx: &mut Context<Self>,
11189    ) -> Task<Result<()>> {
11190        if let Some((client, project_id)) = self.upstream_client() {
11191            let request = client.request(proto::StopLanguageServers {
11192                project_id,
11193                buffer_ids: buffers
11194                    .into_iter()
11195                    .map(|b| b.read(cx).remote_id().to_proto())
11196                    .collect(),
11197                also_servers: also_stop_servers
11198                    .into_iter()
11199                    .map(|selector| {
11200                        let selector = match selector {
11201                            LanguageServerSelector::Id(language_server_id) => {
11202                                proto::language_server_selector::Selector::ServerId(
11203                                    language_server_id.to_proto(),
11204                                )
11205                            }
11206                            LanguageServerSelector::Name(language_server_name) => {
11207                                proto::language_server_selector::Selector::Name(
11208                                    language_server_name.to_string(),
11209                                )
11210                            }
11211                        };
11212                        proto::LanguageServerSelector {
11213                            selector: Some(selector),
11214                        }
11215                    })
11216                    .collect(),
11217                all: false,
11218            });
11219            cx.background_spawn(async move {
11220                let _ = request.await?;
11221                Ok(())
11222            })
11223        } else {
11224            let task =
11225                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
11226            cx.background_spawn(async move {
11227                task.await;
11228                Ok(())
11229            })
11230        }
11231    }
11232
11233    fn stop_local_language_servers_for_buffers(
11234        &mut self,
11235        buffers: &[Entity<Buffer>],
11236        also_stop_servers: HashSet<LanguageServerSelector>,
11237        cx: &mut Context<Self>,
11238    ) -> Task<()> {
11239        let Some(local) = self.as_local_mut() else {
11240            return Task::ready(());
11241        };
11242        let mut language_server_names_to_stop = BTreeSet::default();
11243        let mut language_servers_to_stop = also_stop_servers
11244            .into_iter()
11245            .flat_map(|selector| match selector {
11246                LanguageServerSelector::Id(id) => Some(id),
11247                LanguageServerSelector::Name(name) => {
11248                    language_server_names_to_stop.insert(name);
11249                    None
11250                }
11251            })
11252            .collect::<BTreeSet<_>>();
11253
11254        let mut covered_worktrees = HashSet::default();
11255        for buffer in buffers {
11256            buffer.update(cx, |buffer, cx| {
11257                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
11258                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
11259                    && covered_worktrees.insert(worktree_id)
11260                {
11261                    language_server_names_to_stop.retain(|name| {
11262                        let old_ids_count = language_servers_to_stop.len();
11263                        let all_language_servers_with_this_name = local
11264                            .language_server_ids
11265                            .iter()
11266                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
11267                        language_servers_to_stop.extend(all_language_servers_with_this_name);
11268                        old_ids_count == language_servers_to_stop.len()
11269                    });
11270                }
11271            });
11272        }
11273        for name in language_server_names_to_stop {
11274            language_servers_to_stop.extend(
11275                local
11276                    .language_server_ids
11277                    .iter()
11278                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
11279            );
11280        }
11281
11282        local.lsp_tree.remove_nodes(&language_servers_to_stop);
11283        let tasks = language_servers_to_stop
11284            .into_iter()
11285            .map(|server| self.stop_local_language_server(server, cx))
11286            .collect::<Vec<_>>();
11287
11288        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
11289    }
11290
11291    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
11292        let (worktree, relative_path) =
11293            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
11294
11295        let project_path = ProjectPath {
11296            worktree_id: worktree.read(cx).id(),
11297            path: relative_path,
11298        };
11299
11300        Some(
11301            self.buffer_store()
11302                .read(cx)
11303                .get_by_path(&project_path)?
11304                .read(cx),
11305        )
11306    }
11307
11308    #[cfg(any(test, feature = "test-support"))]
11309    pub fn update_diagnostics(
11310        &mut self,
11311        server_id: LanguageServerId,
11312        diagnostics: lsp::PublishDiagnosticsParams,
11313        result_id: Option<SharedString>,
11314        source_kind: DiagnosticSourceKind,
11315        disk_based_sources: &[String],
11316        cx: &mut Context<Self>,
11317    ) -> Result<()> {
11318        self.merge_lsp_diagnostics(
11319            source_kind,
11320            vec![DocumentDiagnosticsUpdate {
11321                diagnostics,
11322                result_id,
11323                server_id,
11324                disk_based_sources: Cow::Borrowed(disk_based_sources),
11325                registration_id: None,
11326            }],
11327            |_, _, _| false,
11328            cx,
11329        )
11330    }
11331
11332    pub fn merge_lsp_diagnostics(
11333        &mut self,
11334        source_kind: DiagnosticSourceKind,
11335        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
11336        merge: impl Fn(&lsp::Uri, &Diagnostic, &App) -> bool + Clone,
11337        cx: &mut Context<Self>,
11338    ) -> Result<()> {
11339        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
11340        let updates = lsp_diagnostics
11341            .into_iter()
11342            .filter_map(|update| {
11343                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
11344                Some(DocumentDiagnosticsUpdate {
11345                    diagnostics: self.lsp_to_document_diagnostics(
11346                        abs_path,
11347                        source_kind,
11348                        update.server_id,
11349                        update.diagnostics,
11350                        &update.disk_based_sources,
11351                        update.registration_id.clone(),
11352                    ),
11353                    result_id: update.result_id,
11354                    server_id: update.server_id,
11355                    disk_based_sources: update.disk_based_sources,
11356                    registration_id: update.registration_id,
11357                })
11358            })
11359            .collect();
11360        self.merge_diagnostic_entries(updates, merge, cx)?;
11361        Ok(())
11362    }
11363
11364    fn lsp_to_document_diagnostics(
11365        &mut self,
11366        document_abs_path: PathBuf,
11367        source_kind: DiagnosticSourceKind,
11368        server_id: LanguageServerId,
11369        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
11370        disk_based_sources: &[String],
11371        registration_id: Option<SharedString>,
11372    ) -> DocumentDiagnostics {
11373        let mut diagnostics = Vec::default();
11374        let mut primary_diagnostic_group_ids = HashMap::default();
11375        let mut sources_by_group_id = HashMap::default();
11376        let mut supporting_diagnostics = HashMap::default();
11377
11378        let adapter = self.language_server_adapter_for_id(server_id);
11379
11380        // Ensure that primary diagnostics are always the most severe
11381        lsp_diagnostics
11382            .diagnostics
11383            .sort_by_key(|item| item.severity);
11384
11385        for diagnostic in &lsp_diagnostics.diagnostics {
11386            let source = diagnostic.source.as_ref();
11387            let range = range_from_lsp(diagnostic.range);
11388            let is_supporting = diagnostic
11389                .related_information
11390                .as_ref()
11391                .is_some_and(|infos| {
11392                    infos.iter().any(|info| {
11393                        primary_diagnostic_group_ids.contains_key(&(
11394                            source,
11395                            diagnostic.code.clone(),
11396                            range_from_lsp(info.location.range),
11397                        ))
11398                    })
11399                });
11400
11401            let is_unnecessary = diagnostic
11402                .tags
11403                .as_ref()
11404                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
11405
11406            let underline = self
11407                .language_server_adapter_for_id(server_id)
11408                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
11409
11410            if is_supporting {
11411                supporting_diagnostics.insert(
11412                    (source, diagnostic.code.clone(), range),
11413                    (diagnostic.severity, is_unnecessary),
11414                );
11415            } else {
11416                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
11417                let is_disk_based =
11418                    source.is_some_and(|source| disk_based_sources.contains(source));
11419
11420                sources_by_group_id.insert(group_id, source);
11421                primary_diagnostic_group_ids
11422                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
11423
11424                diagnostics.push(DiagnosticEntry {
11425                    range,
11426                    diagnostic: Diagnostic {
11427                        source: diagnostic.source.clone(),
11428                        source_kind,
11429                        code: diagnostic.code.clone(),
11430                        code_description: diagnostic
11431                            .code_description
11432                            .as_ref()
11433                            .and_then(|d| d.href.clone()),
11434                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
11435                        markdown: adapter.as_ref().and_then(|adapter| {
11436                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
11437                        }),
11438                        message: diagnostic.message.trim().to_string(),
11439                        group_id,
11440                        is_primary: true,
11441                        is_disk_based,
11442                        is_unnecessary,
11443                        underline,
11444                        data: diagnostic.data.clone(),
11445                        registration_id: registration_id.clone(),
11446                    },
11447                });
11448                if let Some(infos) = &diagnostic.related_information {
11449                    for info in infos {
11450                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
11451                            let range = range_from_lsp(info.location.range);
11452                            diagnostics.push(DiagnosticEntry {
11453                                range,
11454                                diagnostic: Diagnostic {
11455                                    source: diagnostic.source.clone(),
11456                                    source_kind,
11457                                    code: diagnostic.code.clone(),
11458                                    code_description: diagnostic
11459                                        .code_description
11460                                        .as_ref()
11461                                        .and_then(|d| d.href.clone()),
11462                                    severity: DiagnosticSeverity::INFORMATION,
11463                                    markdown: adapter.as_ref().and_then(|adapter| {
11464                                        adapter.diagnostic_message_to_markdown(&info.message)
11465                                    }),
11466                                    message: info.message.trim().to_string(),
11467                                    group_id,
11468                                    is_primary: false,
11469                                    is_disk_based,
11470                                    is_unnecessary: false,
11471                                    underline,
11472                                    data: diagnostic.data.clone(),
11473                                    registration_id: registration_id.clone(),
11474                                },
11475                            });
11476                        }
11477                    }
11478                }
11479            }
11480        }
11481
11482        for entry in &mut diagnostics {
11483            let diagnostic = &mut entry.diagnostic;
11484            if !diagnostic.is_primary {
11485                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
11486                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
11487                    source,
11488                    diagnostic.code.clone(),
11489                    entry.range.clone(),
11490                )) {
11491                    if let Some(severity) = severity {
11492                        diagnostic.severity = severity;
11493                    }
11494                    diagnostic.is_unnecessary = is_unnecessary;
11495                }
11496            }
11497        }
11498
11499        DocumentDiagnostics {
11500            diagnostics,
11501            document_abs_path,
11502            version: lsp_diagnostics.version,
11503        }
11504    }
11505
11506    fn insert_newly_running_language_server(
11507        &mut self,
11508        adapter: Arc<CachedLspAdapter>,
11509        language_server: Arc<LanguageServer>,
11510        server_id: LanguageServerId,
11511        key: LanguageServerSeed,
11512        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
11513        cx: &mut Context<Self>,
11514    ) {
11515        let Some(local) = self.as_local_mut() else {
11516            return;
11517        };
11518        // If the language server for this key doesn't match the server id, don't store the
11519        // server. Which will cause it to be dropped, killing the process
11520        if local
11521            .language_server_ids
11522            .get(&key)
11523            .map(|state| state.id != server_id)
11524            .unwrap_or(false)
11525        {
11526            return;
11527        }
11528
11529        // Update language_servers collection with Running variant of LanguageServerState
11530        // indicating that the server is up and running and ready
11531        let workspace_folders = workspace_folders.lock().clone();
11532        language_server.set_workspace_folders(workspace_folders);
11533
11534        let workspace_diagnostics_refresh_tasks = language_server
11535            .capabilities()
11536            .diagnostic_provider
11537            .and_then(|provider| {
11538                local
11539                    .language_server_dynamic_registrations
11540                    .entry(server_id)
11541                    .or_default()
11542                    .diagnostics
11543                    .entry(None)
11544                    .or_insert(provider.clone());
11545                let workspace_refresher =
11546                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
11547
11548                Some((None, workspace_refresher))
11549            })
11550            .into_iter()
11551            .collect();
11552        local.language_servers.insert(
11553            server_id,
11554            LanguageServerState::Running {
11555                workspace_diagnostics_refresh_tasks,
11556                adapter: adapter.clone(),
11557                server: language_server.clone(),
11558                simulate_disk_based_diagnostics_completion: None,
11559            },
11560        );
11561        local
11562            .languages
11563            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
11564        if let Some(file_ops_caps) = language_server
11565            .capabilities()
11566            .workspace
11567            .as_ref()
11568            .and_then(|ws| ws.file_operations.as_ref())
11569        {
11570            let did_rename_caps = file_ops_caps.did_rename.as_ref();
11571            let will_rename_caps = file_ops_caps.will_rename.as_ref();
11572            if did_rename_caps.or(will_rename_caps).is_some() {
11573                let watcher = RenamePathsWatchedForServer::default()
11574                    .with_did_rename_patterns(did_rename_caps)
11575                    .with_will_rename_patterns(will_rename_caps);
11576                local
11577                    .language_server_paths_watched_for_rename
11578                    .insert(server_id, watcher);
11579            }
11580        }
11581
11582        self.language_server_statuses.insert(
11583            server_id,
11584            LanguageServerStatus {
11585                name: language_server.name(),
11586                server_version: language_server.version(),
11587                pending_work: Default::default(),
11588                has_pending_diagnostic_updates: false,
11589                progress_tokens: Default::default(),
11590                worktree: Some(key.worktree_id),
11591                binary: Some(language_server.binary().clone()),
11592                configuration: Some(language_server.configuration().clone()),
11593                workspace_folders: language_server.workspace_folders(),
11594            },
11595        );
11596
11597        cx.emit(LspStoreEvent::LanguageServerAdded(
11598            server_id,
11599            language_server.name(),
11600            Some(key.worktree_id),
11601        ));
11602
11603        let server_capabilities = language_server.capabilities();
11604        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11605            downstream_client
11606                .send(proto::StartLanguageServer {
11607                    project_id: *project_id,
11608                    server: Some(proto::LanguageServer {
11609                        id: server_id.to_proto(),
11610                        name: language_server.name().to_string(),
11611                        worktree_id: Some(key.worktree_id.to_proto()),
11612                    }),
11613                    capabilities: serde_json::to_string(&server_capabilities)
11614                        .expect("serializing server LSP capabilities"),
11615                })
11616                .log_err();
11617        }
11618        self.lsp_server_capabilities
11619            .insert(server_id, server_capabilities);
11620
11621        // Tell the language server about every open buffer in the worktree that matches the language.
11622        // Also check for buffers in worktrees that reused this server
11623        let mut worktrees_using_server = vec![key.worktree_id];
11624        if let Some(local) = self.as_local() {
11625            // Find all worktrees that have this server in their language server tree
11626            for (worktree_id, servers) in &local.lsp_tree.instances {
11627                if *worktree_id != key.worktree_id {
11628                    for server_map in servers.roots.values() {
11629                        if server_map
11630                            .values()
11631                            .any(|(node, _)| node.id() == Some(server_id))
11632                        {
11633                            worktrees_using_server.push(*worktree_id);
11634                        }
11635                    }
11636                }
11637            }
11638        }
11639
11640        let mut buffer_paths_registered = Vec::new();
11641        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11642            let mut lsp_adapters = HashMap::default();
11643            for buffer_handle in buffer_store.buffers() {
11644                let buffer = buffer_handle.read(cx);
11645                let file = match File::from_dyn(buffer.file()) {
11646                    Some(file) => file,
11647                    None => continue,
11648                };
11649                let language = match buffer.language() {
11650                    Some(language) => language,
11651                    None => continue,
11652                };
11653
11654                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11655                    || !lsp_adapters
11656                        .entry(language.name())
11657                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11658                        .iter()
11659                        .any(|a| a.name == key.name)
11660                {
11661                    continue;
11662                }
11663                // didOpen
11664                let file = match file.as_local() {
11665                    Some(file) => file,
11666                    None => continue,
11667                };
11668
11669                let local = self.as_local_mut().unwrap();
11670
11671                let buffer_id = buffer.remote_id();
11672                if local.registered_buffers.contains_key(&buffer_id) {
11673                    let versions = local
11674                        .buffer_snapshots
11675                        .entry(buffer_id)
11676                        .or_default()
11677                        .entry(server_id)
11678                        .and_modify(|_| {
11679                            assert!(
11680                            false,
11681                            "There should not be an existing snapshot for a newly inserted buffer"
11682                        )
11683                        })
11684                        .or_insert_with(|| {
11685                            vec![LspBufferSnapshot {
11686                                version: 0,
11687                                snapshot: buffer.text_snapshot(),
11688                            }]
11689                        });
11690
11691                    let snapshot = versions.last().unwrap();
11692                    let version = snapshot.version;
11693                    let initial_snapshot = &snapshot.snapshot;
11694                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11695                    language_server.register_buffer(
11696                        uri,
11697                        adapter.language_id(&language.name()),
11698                        version,
11699                        initial_snapshot.text(),
11700                    );
11701                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11702                    local
11703                        .buffers_opened_in_servers
11704                        .entry(buffer_id)
11705                        .or_default()
11706                        .insert(server_id);
11707                }
11708                buffer_handle.update(cx, |buffer, cx| {
11709                    buffer.set_completion_triggers(
11710                        server_id,
11711                        language_server
11712                            .capabilities()
11713                            .completion_provider
11714                            .as_ref()
11715                            .and_then(|provider| {
11716                                provider
11717                                    .trigger_characters
11718                                    .as_ref()
11719                                    .map(|characters| characters.iter().cloned().collect())
11720                            })
11721                            .unwrap_or_default(),
11722                        cx,
11723                    )
11724                });
11725            }
11726        });
11727
11728        for (buffer_id, abs_path) in buffer_paths_registered {
11729            cx.emit(LspStoreEvent::LanguageServerUpdate {
11730                language_server_id: server_id,
11731                name: Some(adapter.name()),
11732                message: proto::update_language_server::Variant::RegisteredForBuffer(
11733                    proto::RegisteredForBuffer {
11734                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11735                        buffer_id: buffer_id.to_proto(),
11736                    },
11737                ),
11738            });
11739        }
11740
11741        cx.notify();
11742    }
11743
11744    pub fn language_servers_running_disk_based_diagnostics(
11745        &self,
11746    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11747        self.language_server_statuses
11748            .iter()
11749            .filter_map(|(id, status)| {
11750                if status.has_pending_diagnostic_updates {
11751                    Some(*id)
11752                } else {
11753                    None
11754                }
11755            })
11756    }
11757
11758    pub(crate) fn cancel_language_server_work_for_buffers(
11759        &mut self,
11760        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11761        cx: &mut Context<Self>,
11762    ) {
11763        if let Some((client, project_id)) = self.upstream_client() {
11764            let request = client.request(proto::CancelLanguageServerWork {
11765                project_id,
11766                work: Some(proto::cancel_language_server_work::Work::Buffers(
11767                    proto::cancel_language_server_work::Buffers {
11768                        buffer_ids: buffers
11769                            .into_iter()
11770                            .map(|b| b.read(cx).remote_id().to_proto())
11771                            .collect(),
11772                    },
11773                )),
11774            });
11775            cx.background_spawn(request).detach_and_log_err(cx);
11776        } else if let Some(local) = self.as_local() {
11777            let servers = buffers
11778                .into_iter()
11779                .flat_map(|buffer| {
11780                    buffer.update(cx, |buffer, cx| {
11781                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11782                    })
11783                })
11784                .collect::<HashSet<_>>();
11785            for server_id in servers {
11786                self.cancel_language_server_work(server_id, None, cx);
11787            }
11788        }
11789    }
11790
11791    pub(crate) fn cancel_language_server_work(
11792        &mut self,
11793        server_id: LanguageServerId,
11794        token_to_cancel: Option<ProgressToken>,
11795        cx: &mut Context<Self>,
11796    ) {
11797        if let Some(local) = self.as_local() {
11798            let status = self.language_server_statuses.get(&server_id);
11799            let server = local.language_servers.get(&server_id);
11800            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11801            {
11802                for (token, progress) in &status.pending_work {
11803                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11804                        && token != token_to_cancel
11805                    {
11806                        continue;
11807                    }
11808                    if progress.is_cancellable {
11809                        server
11810                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11811                                WorkDoneProgressCancelParams {
11812                                    token: token.to_lsp(),
11813                                },
11814                            )
11815                            .ok();
11816                    }
11817                }
11818            }
11819        } else if let Some((client, project_id)) = self.upstream_client() {
11820            let request = client.request(proto::CancelLanguageServerWork {
11821                project_id,
11822                work: Some(
11823                    proto::cancel_language_server_work::Work::LanguageServerWork(
11824                        proto::cancel_language_server_work::LanguageServerWork {
11825                            language_server_id: server_id.to_proto(),
11826                            token: token_to_cancel.map(|token| token.to_proto()),
11827                        },
11828                    ),
11829                ),
11830            });
11831            cx.background_spawn(request).detach_and_log_err(cx);
11832        }
11833    }
11834
11835    fn register_supplementary_language_server(
11836        &mut self,
11837        id: LanguageServerId,
11838        name: LanguageServerName,
11839        server: Arc<LanguageServer>,
11840        cx: &mut Context<Self>,
11841    ) {
11842        if let Some(local) = self.as_local_mut() {
11843            local
11844                .supplementary_language_servers
11845                .insert(id, (name.clone(), server));
11846            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11847        }
11848    }
11849
11850    fn unregister_supplementary_language_server(
11851        &mut self,
11852        id: LanguageServerId,
11853        cx: &mut Context<Self>,
11854    ) {
11855        if let Some(local) = self.as_local_mut() {
11856            local.supplementary_language_servers.remove(&id);
11857            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11858        }
11859    }
11860
11861    pub(crate) fn supplementary_language_servers(
11862        &self,
11863    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11864        self.as_local().into_iter().flat_map(|local| {
11865            local
11866                .supplementary_language_servers
11867                .iter()
11868                .map(|(id, (name, _))| (*id, name.clone()))
11869        })
11870    }
11871
11872    pub fn language_server_adapter_for_id(
11873        &self,
11874        id: LanguageServerId,
11875    ) -> Option<Arc<CachedLspAdapter>> {
11876        self.as_local()
11877            .and_then(|local| local.language_servers.get(&id))
11878            .and_then(|language_server_state| match language_server_state {
11879                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11880                _ => None,
11881            })
11882    }
11883
11884    pub(super) fn update_local_worktree_language_servers(
11885        &mut self,
11886        worktree_handle: &Entity<Worktree>,
11887        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11888        cx: &mut Context<Self>,
11889    ) {
11890        if changes.is_empty() {
11891            return;
11892        }
11893
11894        let Some(local) = self.as_local() else { return };
11895
11896        local.prettier_store.update(cx, |prettier_store, cx| {
11897            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11898        });
11899
11900        let worktree_id = worktree_handle.read(cx).id();
11901        let mut language_server_ids = local
11902            .language_server_ids
11903            .iter()
11904            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11905            .collect::<Vec<_>>();
11906        language_server_ids.sort();
11907        language_server_ids.dedup();
11908
11909        // let abs_path = worktree_handle.read(cx).abs_path();
11910        for server_id in &language_server_ids {
11911            if let Some(LanguageServerState::Running { server, .. }) =
11912                local.language_servers.get(server_id)
11913                && let Some(watched_paths) = local
11914                    .language_server_watched_paths
11915                    .get(server_id)
11916                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11917            {
11918                let params = lsp::DidChangeWatchedFilesParams {
11919                    changes: changes
11920                        .iter()
11921                        .filter_map(|(path, _, change)| {
11922                            if !watched_paths.is_match(path.as_std_path()) {
11923                                return None;
11924                            }
11925                            let typ = match change {
11926                                PathChange::Loaded => return None,
11927                                PathChange::Added => lsp::FileChangeType::CREATED,
11928                                PathChange::Removed => lsp::FileChangeType::DELETED,
11929                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11930                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11931                            };
11932                            let uri = lsp::Uri::from_file_path(
11933                                worktree_handle.read(cx).absolutize(&path),
11934                            )
11935                            .ok()?;
11936                            Some(lsp::FileEvent { uri, typ })
11937                        })
11938                        .collect(),
11939                };
11940                if !params.changes.is_empty() {
11941                    server
11942                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11943                        .ok();
11944                }
11945            }
11946        }
11947        for (path, _, _) in changes {
11948            if let Some(file_name) = path.file_name()
11949                && local.watched_manifest_filenames.contains(file_name)
11950            {
11951                self.request_workspace_config_refresh();
11952                break;
11953            }
11954        }
11955    }
11956
11957    pub fn wait_for_remote_buffer(
11958        &mut self,
11959        id: BufferId,
11960        cx: &mut Context<Self>,
11961    ) -> Task<Result<Entity<Buffer>>> {
11962        self.buffer_store.update(cx, |buffer_store, cx| {
11963            buffer_store.wait_for_remote_buffer(id, cx)
11964        })
11965    }
11966
11967    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11968        let mut result = proto::Symbol {
11969            language_server_name: symbol.language_server_name.0.to_string(),
11970            source_worktree_id: symbol.source_worktree_id.to_proto(),
11971            language_server_id: symbol.source_language_server_id.to_proto(),
11972            name: symbol.name.clone(),
11973            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11974            start: Some(proto::PointUtf16 {
11975                row: symbol.range.start.0.row,
11976                column: symbol.range.start.0.column,
11977            }),
11978            end: Some(proto::PointUtf16 {
11979                row: symbol.range.end.0.row,
11980                column: symbol.range.end.0.column,
11981            }),
11982            worktree_id: Default::default(),
11983            path: Default::default(),
11984            signature: Default::default(),
11985        };
11986        match &symbol.path {
11987            SymbolLocation::InProject(path) => {
11988                result.worktree_id = path.worktree_id.to_proto();
11989                result.path = path.path.to_proto();
11990            }
11991            SymbolLocation::OutsideProject {
11992                abs_path,
11993                signature,
11994            } => {
11995                result.path = abs_path.to_string_lossy().into_owned();
11996                result.signature = signature.to_vec();
11997            }
11998        }
11999        result
12000    }
12001
12002    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
12003        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
12004        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
12005        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
12006
12007        let path = if serialized_symbol.signature.is_empty() {
12008            SymbolLocation::InProject(ProjectPath {
12009                worktree_id,
12010                path: RelPath::from_proto(&serialized_symbol.path)
12011                    .context("invalid symbol path")?,
12012            })
12013        } else {
12014            SymbolLocation::OutsideProject {
12015                abs_path: Path::new(&serialized_symbol.path).into(),
12016                signature: serialized_symbol
12017                    .signature
12018                    .try_into()
12019                    .map_err(|_| anyhow!("invalid signature"))?,
12020            }
12021        };
12022
12023        let start = serialized_symbol.start.context("invalid start")?;
12024        let end = serialized_symbol.end.context("invalid end")?;
12025        Ok(CoreSymbol {
12026            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
12027            source_worktree_id,
12028            source_language_server_id: LanguageServerId::from_proto(
12029                serialized_symbol.language_server_id,
12030            ),
12031            path,
12032            name: serialized_symbol.name,
12033            range: Unclipped(PointUtf16::new(start.row, start.column))
12034                ..Unclipped(PointUtf16::new(end.row, end.column)),
12035            kind,
12036        })
12037    }
12038
12039    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
12040        let mut serialized_completion = proto::Completion {
12041            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
12042            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
12043            new_text: completion.new_text.clone(),
12044            ..proto::Completion::default()
12045        };
12046        match &completion.source {
12047            CompletionSource::Lsp {
12048                insert_range,
12049                server_id,
12050                lsp_completion,
12051                lsp_defaults,
12052                resolved,
12053            } => {
12054                let (old_insert_start, old_insert_end) = insert_range
12055                    .as_ref()
12056                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
12057                    .unzip();
12058
12059                serialized_completion.old_insert_start = old_insert_start;
12060                serialized_completion.old_insert_end = old_insert_end;
12061                serialized_completion.source = proto::completion::Source::Lsp as i32;
12062                serialized_completion.server_id = server_id.0 as u64;
12063                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
12064                serialized_completion.lsp_defaults = lsp_defaults
12065                    .as_deref()
12066                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
12067                serialized_completion.resolved = *resolved;
12068            }
12069            CompletionSource::BufferWord {
12070                word_range,
12071                resolved,
12072            } => {
12073                serialized_completion.source = proto::completion::Source::BufferWord as i32;
12074                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
12075                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
12076                serialized_completion.resolved = *resolved;
12077            }
12078            CompletionSource::Custom => {
12079                serialized_completion.source = proto::completion::Source::Custom as i32;
12080                serialized_completion.resolved = true;
12081            }
12082            CompletionSource::Dap { sort_text } => {
12083                serialized_completion.source = proto::completion::Source::Dap as i32;
12084                serialized_completion.sort_text = Some(sort_text.clone());
12085            }
12086        }
12087
12088        serialized_completion
12089    }
12090
12091    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
12092        let old_replace_start = completion
12093            .old_replace_start
12094            .and_then(deserialize_anchor)
12095            .context("invalid old start")?;
12096        let old_replace_end = completion
12097            .old_replace_end
12098            .and_then(deserialize_anchor)
12099            .context("invalid old end")?;
12100        let insert_range = {
12101            match completion.old_insert_start.zip(completion.old_insert_end) {
12102                Some((start, end)) => {
12103                    let start = deserialize_anchor(start).context("invalid insert old start")?;
12104                    let end = deserialize_anchor(end).context("invalid insert old end")?;
12105                    Some(start..end)
12106                }
12107                None => None,
12108            }
12109        };
12110        Ok(CoreCompletion {
12111            replace_range: old_replace_start..old_replace_end,
12112            new_text: completion.new_text,
12113            source: match proto::completion::Source::from_i32(completion.source) {
12114                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
12115                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
12116                    insert_range,
12117                    server_id: LanguageServerId::from_proto(completion.server_id),
12118                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
12119                    lsp_defaults: completion
12120                        .lsp_defaults
12121                        .as_deref()
12122                        .map(serde_json::from_slice)
12123                        .transpose()?,
12124                    resolved: completion.resolved,
12125                },
12126                Some(proto::completion::Source::BufferWord) => {
12127                    let word_range = completion
12128                        .buffer_word_start
12129                        .and_then(deserialize_anchor)
12130                        .context("invalid buffer word start")?
12131                        ..completion
12132                            .buffer_word_end
12133                            .and_then(deserialize_anchor)
12134                            .context("invalid buffer word end")?;
12135                    CompletionSource::BufferWord {
12136                        word_range,
12137                        resolved: completion.resolved,
12138                    }
12139                }
12140                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
12141                    sort_text: completion
12142                        .sort_text
12143                        .context("expected sort text to exist")?,
12144                },
12145                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
12146            },
12147        })
12148    }
12149
12150    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
12151        let (kind, lsp_action) = match &action.lsp_action {
12152            LspAction::Action(code_action) => (
12153                proto::code_action::Kind::Action as i32,
12154                serde_json::to_vec(code_action).unwrap(),
12155            ),
12156            LspAction::Command(command) => (
12157                proto::code_action::Kind::Command as i32,
12158                serde_json::to_vec(command).unwrap(),
12159            ),
12160            LspAction::CodeLens(code_lens) => (
12161                proto::code_action::Kind::CodeLens as i32,
12162                serde_json::to_vec(code_lens).unwrap(),
12163            ),
12164        };
12165
12166        proto::CodeAction {
12167            server_id: action.server_id.0 as u64,
12168            start: Some(serialize_anchor(&action.range.start)),
12169            end: Some(serialize_anchor(&action.range.end)),
12170            lsp_action,
12171            kind,
12172            resolved: action.resolved,
12173        }
12174    }
12175
12176    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
12177        let start = action
12178            .start
12179            .and_then(deserialize_anchor)
12180            .context("invalid start")?;
12181        let end = action
12182            .end
12183            .and_then(deserialize_anchor)
12184            .context("invalid end")?;
12185        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
12186            Some(proto::code_action::Kind::Action) => {
12187                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
12188            }
12189            Some(proto::code_action::Kind::Command) => {
12190                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
12191            }
12192            Some(proto::code_action::Kind::CodeLens) => {
12193                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
12194            }
12195            None => anyhow::bail!("Unknown action kind {}", action.kind),
12196        };
12197        Ok(CodeAction {
12198            server_id: LanguageServerId(action.server_id as usize),
12199            range: start..end,
12200            resolved: action.resolved,
12201            lsp_action,
12202        })
12203    }
12204
12205    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
12206        match &formatting_result {
12207            Ok(_) => self.last_formatting_failure = None,
12208            Err(error) => {
12209                let error_string = format!("{error:#}");
12210                log::error!("Formatting failed: {error_string}");
12211                self.last_formatting_failure
12212                    .replace(error_string.lines().join(" "));
12213            }
12214        }
12215    }
12216
12217    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
12218        self.lsp_server_capabilities.remove(&for_server);
12219        for lsp_data in self.lsp_data.values_mut() {
12220            lsp_data.remove_server_data(for_server);
12221        }
12222        if let Some(local) = self.as_local_mut() {
12223            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
12224            local
12225                .workspace_pull_diagnostics_result_ids
12226                .remove(&for_server);
12227            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
12228                buffer_servers.remove(&for_server);
12229            }
12230        }
12231    }
12232
12233    pub fn result_id_for_buffer_pull(
12234        &self,
12235        server_id: LanguageServerId,
12236        buffer_id: BufferId,
12237        registration_id: &Option<SharedString>,
12238        cx: &App,
12239    ) -> Option<SharedString> {
12240        let abs_path = self
12241            .buffer_store
12242            .read(cx)
12243            .get(buffer_id)
12244            .and_then(|b| File::from_dyn(b.read(cx).file()))
12245            .map(|f| f.abs_path(cx))?;
12246        self.as_local()?
12247            .buffer_pull_diagnostics_result_ids
12248            .get(&server_id)?
12249            .get(registration_id)?
12250            .get(&abs_path)?
12251            .clone()
12252    }
12253
12254    /// Gets all result_ids for a workspace diagnostics pull request.
12255    /// First, it tries to find buffer's result_id retrieved via the diagnostics pull; if it fails, it falls back to the workspace disagnostics pull result_id.
12256    /// The latter is supposed to be of lower priority as we keep on pulling diagnostics for open buffers eagerly.
12257    pub fn result_ids_for_workspace_refresh(
12258        &self,
12259        server_id: LanguageServerId,
12260        registration_id: &Option<SharedString>,
12261    ) -> HashMap<PathBuf, SharedString> {
12262        let Some(local) = self.as_local() else {
12263            return HashMap::default();
12264        };
12265        local
12266            .workspace_pull_diagnostics_result_ids
12267            .get(&server_id)
12268            .into_iter()
12269            .filter_map(|diagnostics| diagnostics.get(registration_id))
12270            .flatten()
12271            .filter_map(|(abs_path, result_id)| {
12272                let result_id = local
12273                    .buffer_pull_diagnostics_result_ids
12274                    .get(&server_id)
12275                    .and_then(|buffer_ids_result_ids| {
12276                        buffer_ids_result_ids.get(registration_id)?.get(abs_path)
12277                    })
12278                    .cloned()
12279                    .flatten()
12280                    .or_else(|| result_id.clone())?;
12281                Some((abs_path.clone(), result_id))
12282            })
12283            .collect()
12284    }
12285
12286    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
12287        if let Some(LanguageServerState::Running {
12288            workspace_diagnostics_refresh_tasks,
12289            ..
12290        }) = self
12291            .as_local_mut()
12292            .and_then(|local| local.language_servers.get_mut(&server_id))
12293        {
12294            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
12295                diagnostics.refresh_tx.try_send(()).ok();
12296            }
12297        }
12298    }
12299
12300    /// Refreshes `textDocument/diagnostic` for all open buffers associated with the given server.
12301    /// This is called in response to `workspace/diagnostic/refresh` to comply with the LSP spec,
12302    /// which requires refreshing both workspace and document diagnostics.
12303    pub fn pull_document_diagnostics_for_server(
12304        &mut self,
12305        server_id: LanguageServerId,
12306        source_buffer_id: Option<BufferId>,
12307        cx: &mut Context<Self>,
12308    ) -> Shared<Task<()>> {
12309        let Some(local) = self.as_local_mut() else {
12310            return Task::ready(()).shared();
12311        };
12312        let mut buffers_to_refresh = HashSet::default();
12313        for (buffer_id, server_ids) in &local.buffers_opened_in_servers {
12314            if server_ids.contains(&server_id) && Some(buffer_id) != source_buffer_id.as_ref() {
12315                buffers_to_refresh.insert(*buffer_id);
12316            }
12317        }
12318
12319        self.refresh_background_diagnostics_for_buffers(buffers_to_refresh, cx)
12320    }
12321
12322    pub fn pull_document_diagnostics_for_buffer_edit(
12323        &mut self,
12324        buffer_id: BufferId,
12325        cx: &mut Context<Self>,
12326    ) {
12327        let Some(local) = self.as_local_mut() else {
12328            return;
12329        };
12330        let Some(languages_servers) = local.buffers_opened_in_servers.get(&buffer_id).cloned()
12331        else {
12332            return;
12333        };
12334        for server_id in languages_servers {
12335            let _ = self.pull_document_diagnostics_for_server(server_id, Some(buffer_id), cx);
12336        }
12337    }
12338
12339    fn apply_workspace_diagnostic_report(
12340        &mut self,
12341        server_id: LanguageServerId,
12342        report: lsp::WorkspaceDiagnosticReportResult,
12343        registration_id: Option<SharedString>,
12344        cx: &mut Context<Self>,
12345    ) {
12346        let mut workspace_diagnostics =
12347            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(
12348                report,
12349                server_id,
12350                registration_id,
12351            );
12352        workspace_diagnostics.retain(|d| match &d.diagnostics {
12353            LspPullDiagnostics::Response {
12354                server_id,
12355                registration_id,
12356                ..
12357            } => self.diagnostic_registration_exists(*server_id, registration_id),
12358            LspPullDiagnostics::Default => false,
12359        });
12360        let mut unchanged_buffers = HashMap::default();
12361        let workspace_diagnostics_updates = workspace_diagnostics
12362            .into_iter()
12363            .filter_map(
12364                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
12365                    LspPullDiagnostics::Response {
12366                        server_id,
12367                        uri,
12368                        diagnostics,
12369                        registration_id,
12370                    } => Some((
12371                        server_id,
12372                        uri,
12373                        diagnostics,
12374                        workspace_diagnostics.version,
12375                        registration_id,
12376                    )),
12377                    LspPullDiagnostics::Default => None,
12378                },
12379            )
12380            .fold(
12381                HashMap::default(),
12382                |mut acc, (server_id, uri, diagnostics, version, new_registration_id)| {
12383                    let (result_id, diagnostics) = match diagnostics {
12384                        PulledDiagnostics::Unchanged { result_id } => {
12385                            unchanged_buffers
12386                                .entry(new_registration_id.clone())
12387                                .or_insert_with(HashSet::default)
12388                                .insert(uri.clone());
12389                            (Some(result_id), Vec::new())
12390                        }
12391                        PulledDiagnostics::Changed {
12392                            result_id,
12393                            diagnostics,
12394                        } => (result_id, diagnostics),
12395                    };
12396                    let disk_based_sources = Cow::Owned(
12397                        self.language_server_adapter_for_id(server_id)
12398                            .as_ref()
12399                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
12400                            .unwrap_or(&[])
12401                            .to_vec(),
12402                    );
12403
12404                    let Some(abs_path) = uri.to_file_path().ok() else {
12405                        return acc;
12406                    };
12407                    let Some((worktree, relative_path)) =
12408                        self.worktree_store.read(cx).find_worktree(abs_path.clone(), cx)
12409                    else {
12410                        log::warn!("skipping workspace diagnostics update, no worktree found for path {abs_path:?}");
12411                        return acc;
12412                    };
12413                    let worktree_id = worktree.read(cx).id();
12414                    let project_path = ProjectPath {
12415                        worktree_id,
12416                        path: relative_path,
12417                    };
12418                    if let Some(local_lsp_store) = self.as_local_mut() {
12419                        local_lsp_store.workspace_pull_diagnostics_result_ids.entry(server_id)
12420                            .or_default().entry(new_registration_id.clone()).or_default().insert(abs_path, result_id.clone());
12421                    }
12422                    // The LSP spec recommends that "diagnostics from a document pull should win over diagnostics from a workspace pull."
12423                    // Since we actively pull diagnostics for documents with open buffers, we ignore contents of workspace pulls for these documents.
12424                    if self.buffer_store.read(cx).get_by_path(&project_path).is_none() {
12425                        acc.entry(server_id)
12426                            .or_insert_with(HashMap::default)
12427                            .entry(new_registration_id.clone())
12428                            .or_insert_with(Vec::new)
12429                            .push(DocumentDiagnosticsUpdate {
12430                                server_id,
12431                                diagnostics: lsp::PublishDiagnosticsParams {
12432                                    uri,
12433                                    diagnostics,
12434                                    version,
12435                                },
12436                                result_id,
12437                                disk_based_sources,
12438                                registration_id: new_registration_id,
12439                            });
12440                    }
12441                    acc
12442                },
12443            );
12444
12445        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
12446            for (registration_id, diagnostic_updates) in diagnostic_updates {
12447                self.merge_lsp_diagnostics(
12448                    DiagnosticSourceKind::Pulled,
12449                    diagnostic_updates,
12450                    |document_uri, old_diagnostic, _| match old_diagnostic.source_kind {
12451                        DiagnosticSourceKind::Pulled => {
12452                            old_diagnostic.registration_id != registration_id
12453                                || unchanged_buffers
12454                                    .get(&old_diagnostic.registration_id)
12455                                    .is_some_and(|unchanged_buffers| {
12456                                        unchanged_buffers.contains(&document_uri)
12457                                    })
12458                        }
12459                        DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => true,
12460                    },
12461                    cx,
12462                )
12463                .log_err();
12464            }
12465        }
12466    }
12467
12468    fn register_server_capabilities(
12469        &mut self,
12470        server_id: LanguageServerId,
12471        params: lsp::RegistrationParams,
12472        cx: &mut Context<Self>,
12473    ) -> anyhow::Result<()> {
12474        let server = self
12475            .language_server_for_id(server_id)
12476            .with_context(|| format!("no server {server_id} found"))?;
12477        for reg in params.registrations {
12478            match reg.method.as_str() {
12479                "workspace/didChangeWatchedFiles" => {
12480                    if let Some(options) = reg.register_options {
12481                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12482                            let caps = serde_json::from_value(options)?;
12483                            local_lsp_store
12484                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
12485                            true
12486                        } else {
12487                            false
12488                        };
12489                        if notify {
12490                            notify_server_capabilities_updated(&server, cx);
12491                        }
12492                    }
12493                }
12494                "workspace/didChangeConfiguration" => {
12495                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12496                }
12497                "workspace/didChangeWorkspaceFolders" => {
12498                    // In this case register options is an empty object, we can ignore it
12499                    let caps = lsp::WorkspaceFoldersServerCapabilities {
12500                        supported: Some(true),
12501                        change_notifications: Some(OneOf::Right(reg.id)),
12502                    };
12503                    server.update_capabilities(|capabilities| {
12504                        capabilities
12505                            .workspace
12506                            .get_or_insert_default()
12507                            .workspace_folders = Some(caps);
12508                    });
12509                    notify_server_capabilities_updated(&server, cx);
12510                }
12511                "workspace/symbol" => {
12512                    let options = parse_register_capabilities(reg)?;
12513                    server.update_capabilities(|capabilities| {
12514                        capabilities.workspace_symbol_provider = Some(options);
12515                    });
12516                    notify_server_capabilities_updated(&server, cx);
12517                }
12518                "workspace/fileOperations" => {
12519                    if let Some(options) = reg.register_options {
12520                        let caps = serde_json::from_value(options)?;
12521                        server.update_capabilities(|capabilities| {
12522                            capabilities
12523                                .workspace
12524                                .get_or_insert_default()
12525                                .file_operations = Some(caps);
12526                        });
12527                        notify_server_capabilities_updated(&server, cx);
12528                    }
12529                }
12530                "workspace/executeCommand" => {
12531                    if let Some(options) = reg.register_options {
12532                        let options = serde_json::from_value(options)?;
12533                        server.update_capabilities(|capabilities| {
12534                            capabilities.execute_command_provider = Some(options);
12535                        });
12536                        notify_server_capabilities_updated(&server, cx);
12537                    }
12538                }
12539                "textDocument/rangeFormatting" => {
12540                    let options = parse_register_capabilities(reg)?;
12541                    server.update_capabilities(|capabilities| {
12542                        capabilities.document_range_formatting_provider = Some(options);
12543                    });
12544                    notify_server_capabilities_updated(&server, cx);
12545                }
12546                "textDocument/onTypeFormatting" => {
12547                    if let Some(options) = reg
12548                        .register_options
12549                        .map(serde_json::from_value)
12550                        .transpose()?
12551                    {
12552                        server.update_capabilities(|capabilities| {
12553                            capabilities.document_on_type_formatting_provider = Some(options);
12554                        });
12555                        notify_server_capabilities_updated(&server, cx);
12556                    }
12557                }
12558                "textDocument/formatting" => {
12559                    let options = parse_register_capabilities(reg)?;
12560                    server.update_capabilities(|capabilities| {
12561                        capabilities.document_formatting_provider = Some(options);
12562                    });
12563                    notify_server_capabilities_updated(&server, cx);
12564                }
12565                "textDocument/rename" => {
12566                    let options = parse_register_capabilities(reg)?;
12567                    server.update_capabilities(|capabilities| {
12568                        capabilities.rename_provider = Some(options);
12569                    });
12570                    notify_server_capabilities_updated(&server, cx);
12571                }
12572                "textDocument/inlayHint" => {
12573                    let options = parse_register_capabilities(reg)?;
12574                    server.update_capabilities(|capabilities| {
12575                        capabilities.inlay_hint_provider = Some(options);
12576                    });
12577                    notify_server_capabilities_updated(&server, cx);
12578                }
12579                "textDocument/documentSymbol" => {
12580                    let options = parse_register_capabilities(reg)?;
12581                    server.update_capabilities(|capabilities| {
12582                        capabilities.document_symbol_provider = Some(options);
12583                    });
12584                    notify_server_capabilities_updated(&server, cx);
12585                }
12586                "textDocument/codeAction" => {
12587                    let options = parse_register_capabilities(reg)?;
12588                    let provider = match options {
12589                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
12590                        OneOf::Right(caps) => caps,
12591                    };
12592                    server.update_capabilities(|capabilities| {
12593                        capabilities.code_action_provider = Some(provider);
12594                    });
12595                    notify_server_capabilities_updated(&server, cx);
12596                }
12597                "textDocument/definition" => {
12598                    let options = parse_register_capabilities(reg)?;
12599                    server.update_capabilities(|capabilities| {
12600                        capabilities.definition_provider = Some(options);
12601                    });
12602                    notify_server_capabilities_updated(&server, cx);
12603                }
12604                "textDocument/completion" => {
12605                    if let Some(caps) = reg
12606                        .register_options
12607                        .map(serde_json::from_value::<CompletionOptions>)
12608                        .transpose()?
12609                    {
12610                        server.update_capabilities(|capabilities| {
12611                            capabilities.completion_provider = Some(caps.clone());
12612                        });
12613
12614                        if let Some(local) = self.as_local() {
12615                            let mut buffers_with_language_server = Vec::new();
12616                            for handle in self.buffer_store.read(cx).buffers() {
12617                                let buffer_id = handle.read(cx).remote_id();
12618                                if local
12619                                    .buffers_opened_in_servers
12620                                    .get(&buffer_id)
12621                                    .filter(|s| s.contains(&server_id))
12622                                    .is_some()
12623                                {
12624                                    buffers_with_language_server.push(handle);
12625                                }
12626                            }
12627                            let triggers = caps
12628                                .trigger_characters
12629                                .unwrap_or_default()
12630                                .into_iter()
12631                                .collect::<BTreeSet<_>>();
12632                            for handle in buffers_with_language_server {
12633                                let triggers = triggers.clone();
12634                                let _ = handle.update(cx, move |buffer, cx| {
12635                                    buffer.set_completion_triggers(server_id, triggers, cx);
12636                                });
12637                            }
12638                        }
12639                        notify_server_capabilities_updated(&server, cx);
12640                    }
12641                }
12642                "textDocument/hover" => {
12643                    let options = parse_register_capabilities(reg)?;
12644                    let provider = match options {
12645                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
12646                        OneOf::Right(caps) => caps,
12647                    };
12648                    server.update_capabilities(|capabilities| {
12649                        capabilities.hover_provider = Some(provider);
12650                    });
12651                    notify_server_capabilities_updated(&server, cx);
12652                }
12653                "textDocument/signatureHelp" => {
12654                    if let Some(caps) = reg
12655                        .register_options
12656                        .map(serde_json::from_value)
12657                        .transpose()?
12658                    {
12659                        server.update_capabilities(|capabilities| {
12660                            capabilities.signature_help_provider = Some(caps);
12661                        });
12662                        notify_server_capabilities_updated(&server, cx);
12663                    }
12664                }
12665                "textDocument/didChange" => {
12666                    if let Some(sync_kind) = reg
12667                        .register_options
12668                        .and_then(|opts| opts.get("syncKind").cloned())
12669                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12670                        .transpose()?
12671                    {
12672                        server.update_capabilities(|capabilities| {
12673                            let mut sync_options =
12674                                Self::take_text_document_sync_options(capabilities);
12675                            sync_options.change = Some(sync_kind);
12676                            capabilities.text_document_sync =
12677                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12678                        });
12679                        notify_server_capabilities_updated(&server, cx);
12680                    }
12681                }
12682                "textDocument/didSave" => {
12683                    if let Some(include_text) = reg
12684                        .register_options
12685                        .map(|opts| {
12686                            let transpose = opts
12687                                .get("includeText")
12688                                .cloned()
12689                                .map(serde_json::from_value::<Option<bool>>)
12690                                .transpose();
12691                            match transpose {
12692                                Ok(value) => Ok(value.flatten()),
12693                                Err(e) => Err(e),
12694                            }
12695                        })
12696                        .transpose()?
12697                    {
12698                        server.update_capabilities(|capabilities| {
12699                            let mut sync_options =
12700                                Self::take_text_document_sync_options(capabilities);
12701                            sync_options.save =
12702                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12703                                    include_text,
12704                                }));
12705                            capabilities.text_document_sync =
12706                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12707                        });
12708                        notify_server_capabilities_updated(&server, cx);
12709                    }
12710                }
12711                "textDocument/codeLens" => {
12712                    if let Some(caps) = reg
12713                        .register_options
12714                        .map(serde_json::from_value)
12715                        .transpose()?
12716                    {
12717                        server.update_capabilities(|capabilities| {
12718                            capabilities.code_lens_provider = Some(caps);
12719                        });
12720                        notify_server_capabilities_updated(&server, cx);
12721                    }
12722                }
12723                "textDocument/diagnostic" => {
12724                    if let Some(caps) = reg
12725                        .register_options
12726                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12727                        .transpose()?
12728                    {
12729                        let local = self
12730                            .as_local_mut()
12731                            .context("Expected LSP Store to be local")?;
12732                        let state = local
12733                            .language_servers
12734                            .get_mut(&server_id)
12735                            .context("Could not obtain Language Servers state")?;
12736                        local
12737                            .language_server_dynamic_registrations
12738                            .entry(server_id)
12739                            .or_default()
12740                            .diagnostics
12741                            .insert(Some(reg.id.clone()), caps.clone());
12742
12743                        let supports_workspace_diagnostics =
12744                            |capabilities: &DiagnosticServerCapabilities| match capabilities {
12745                                DiagnosticServerCapabilities::Options(diagnostic_options) => {
12746                                    diagnostic_options.workspace_diagnostics
12747                                }
12748                                DiagnosticServerCapabilities::RegistrationOptions(
12749                                    diagnostic_registration_options,
12750                                ) => {
12751                                    diagnostic_registration_options
12752                                        .diagnostic_options
12753                                        .workspace_diagnostics
12754                                }
12755                            };
12756
12757                        if supports_workspace_diagnostics(&caps) {
12758                            if let LanguageServerState::Running {
12759                                workspace_diagnostics_refresh_tasks,
12760                                ..
12761                            } = state
12762                                && let Some(task) = lsp_workspace_diagnostics_refresh(
12763                                    Some(reg.id.clone()),
12764                                    caps.clone(),
12765                                    server.clone(),
12766                                    cx,
12767                                )
12768                            {
12769                                workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12770                            }
12771                        }
12772
12773                        server.update_capabilities(|capabilities| {
12774                            capabilities.diagnostic_provider = Some(caps);
12775                        });
12776
12777                        notify_server_capabilities_updated(&server, cx);
12778
12779                        let _ = self.pull_document_diagnostics_for_server(server_id, None, cx);
12780                    }
12781                }
12782                "textDocument/documentColor" => {
12783                    let options = parse_register_capabilities(reg)?;
12784                    let provider = match options {
12785                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12786                        OneOf::Right(caps) => caps,
12787                    };
12788                    server.update_capabilities(|capabilities| {
12789                        capabilities.color_provider = Some(provider);
12790                    });
12791                    notify_server_capabilities_updated(&server, cx);
12792                }
12793                _ => log::warn!("unhandled capability registration: {reg:?}"),
12794            }
12795        }
12796
12797        Ok(())
12798    }
12799
12800    fn unregister_server_capabilities(
12801        &mut self,
12802        server_id: LanguageServerId,
12803        params: lsp::UnregistrationParams,
12804        cx: &mut Context<Self>,
12805    ) -> anyhow::Result<()> {
12806        let server = self
12807            .language_server_for_id(server_id)
12808            .with_context(|| format!("no server {server_id} found"))?;
12809        for unreg in params.unregisterations.iter() {
12810            match unreg.method.as_str() {
12811                "workspace/didChangeWatchedFiles" => {
12812                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12813                        local_lsp_store
12814                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12815                        true
12816                    } else {
12817                        false
12818                    };
12819                    if notify {
12820                        notify_server_capabilities_updated(&server, cx);
12821                    }
12822                }
12823                "workspace/didChangeConfiguration" => {
12824                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12825                }
12826                "workspace/didChangeWorkspaceFolders" => {
12827                    server.update_capabilities(|capabilities| {
12828                        capabilities
12829                            .workspace
12830                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12831                                workspace_folders: None,
12832                                file_operations: None,
12833                            })
12834                            .workspace_folders = None;
12835                    });
12836                    notify_server_capabilities_updated(&server, cx);
12837                }
12838                "workspace/symbol" => {
12839                    server.update_capabilities(|capabilities| {
12840                        capabilities.workspace_symbol_provider = None
12841                    });
12842                    notify_server_capabilities_updated(&server, cx);
12843                }
12844                "workspace/fileOperations" => {
12845                    server.update_capabilities(|capabilities| {
12846                        capabilities
12847                            .workspace
12848                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12849                                workspace_folders: None,
12850                                file_operations: None,
12851                            })
12852                            .file_operations = None;
12853                    });
12854                    notify_server_capabilities_updated(&server, cx);
12855                }
12856                "workspace/executeCommand" => {
12857                    server.update_capabilities(|capabilities| {
12858                        capabilities.execute_command_provider = None;
12859                    });
12860                    notify_server_capabilities_updated(&server, cx);
12861                }
12862                "textDocument/rangeFormatting" => {
12863                    server.update_capabilities(|capabilities| {
12864                        capabilities.document_range_formatting_provider = None
12865                    });
12866                    notify_server_capabilities_updated(&server, cx);
12867                }
12868                "textDocument/onTypeFormatting" => {
12869                    server.update_capabilities(|capabilities| {
12870                        capabilities.document_on_type_formatting_provider = None;
12871                    });
12872                    notify_server_capabilities_updated(&server, cx);
12873                }
12874                "textDocument/formatting" => {
12875                    server.update_capabilities(|capabilities| {
12876                        capabilities.document_formatting_provider = None;
12877                    });
12878                    notify_server_capabilities_updated(&server, cx);
12879                }
12880                "textDocument/rename" => {
12881                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12882                    notify_server_capabilities_updated(&server, cx);
12883                }
12884                "textDocument/codeAction" => {
12885                    server.update_capabilities(|capabilities| {
12886                        capabilities.code_action_provider = None;
12887                    });
12888                    notify_server_capabilities_updated(&server, cx);
12889                }
12890                "textDocument/definition" => {
12891                    server.update_capabilities(|capabilities| {
12892                        capabilities.definition_provider = None;
12893                    });
12894                    notify_server_capabilities_updated(&server, cx);
12895                }
12896                "textDocument/completion" => {
12897                    server.update_capabilities(|capabilities| {
12898                        capabilities.completion_provider = None;
12899                    });
12900                    notify_server_capabilities_updated(&server, cx);
12901                }
12902                "textDocument/hover" => {
12903                    server.update_capabilities(|capabilities| {
12904                        capabilities.hover_provider = None;
12905                    });
12906                    notify_server_capabilities_updated(&server, cx);
12907                }
12908                "textDocument/signatureHelp" => {
12909                    server.update_capabilities(|capabilities| {
12910                        capabilities.signature_help_provider = None;
12911                    });
12912                    notify_server_capabilities_updated(&server, cx);
12913                }
12914                "textDocument/didChange" => {
12915                    server.update_capabilities(|capabilities| {
12916                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12917                        sync_options.change = None;
12918                        capabilities.text_document_sync =
12919                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12920                    });
12921                    notify_server_capabilities_updated(&server, cx);
12922                }
12923                "textDocument/didSave" => {
12924                    server.update_capabilities(|capabilities| {
12925                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12926                        sync_options.save = None;
12927                        capabilities.text_document_sync =
12928                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12929                    });
12930                    notify_server_capabilities_updated(&server, cx);
12931                }
12932                "textDocument/codeLens" => {
12933                    server.update_capabilities(|capabilities| {
12934                        capabilities.code_lens_provider = None;
12935                    });
12936                    notify_server_capabilities_updated(&server, cx);
12937                }
12938                "textDocument/diagnostic" => {
12939                    let local = self
12940                        .as_local_mut()
12941                        .context("Expected LSP Store to be local")?;
12942
12943                    let state = local
12944                        .language_servers
12945                        .get_mut(&server_id)
12946                        .context("Could not obtain Language Servers state")?;
12947                    let registrations = local
12948                        .language_server_dynamic_registrations
12949                        .get_mut(&server_id)
12950                        .with_context(|| {
12951                            format!("Expected dynamic registration to exist for server {server_id}")
12952                        })?;
12953                    registrations.diagnostics
12954                        .remove(&Some(unreg.id.clone()))
12955                        .with_context(|| format!(
12956                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12957                            unreg.id)
12958                        )?;
12959                    let removed_last_diagnostic_provider = registrations.diagnostics.is_empty();
12960
12961                    if let LanguageServerState::Running {
12962                        workspace_diagnostics_refresh_tasks,
12963                        ..
12964                    } = state
12965                    {
12966                        workspace_diagnostics_refresh_tasks.remove(&Some(unreg.id.clone()));
12967                    }
12968
12969                    self.clear_unregistered_diagnostics(
12970                        server_id,
12971                        SharedString::from(unreg.id.clone()),
12972                        cx,
12973                    )?;
12974
12975                    if removed_last_diagnostic_provider {
12976                        server.update_capabilities(|capabilities| {
12977                            debug_assert!(capabilities.diagnostic_provider.is_some());
12978                            capabilities.diagnostic_provider = None;
12979                        });
12980                    }
12981
12982                    notify_server_capabilities_updated(&server, cx);
12983                }
12984                "textDocument/documentColor" => {
12985                    server.update_capabilities(|capabilities| {
12986                        capabilities.color_provider = None;
12987                    });
12988                    notify_server_capabilities_updated(&server, cx);
12989                }
12990                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12991            }
12992        }
12993
12994        Ok(())
12995    }
12996
12997    fn clear_unregistered_diagnostics(
12998        &mut self,
12999        server_id: LanguageServerId,
13000        cleared_registration_id: SharedString,
13001        cx: &mut Context<Self>,
13002    ) -> anyhow::Result<()> {
13003        let mut affected_abs_paths: HashSet<PathBuf> = HashSet::default();
13004
13005        self.buffer_store.update(cx, |buffer_store, cx| {
13006            for buffer_handle in buffer_store.buffers() {
13007                let buffer = buffer_handle.read(cx);
13008                let abs_path = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx));
13009                let Some(abs_path) = abs_path else {
13010                    continue;
13011                };
13012                affected_abs_paths.insert(abs_path);
13013            }
13014        });
13015
13016        let local = self.as_local().context("Expected LSP Store to be local")?;
13017        for (worktree_id, diagnostics_for_tree) in local.diagnostics.iter() {
13018            let Some(worktree) = self
13019                .worktree_store
13020                .read(cx)
13021                .worktree_for_id(*worktree_id, cx)
13022            else {
13023                continue;
13024            };
13025
13026            for (rel_path, diagnostics_by_server_id) in diagnostics_for_tree.iter() {
13027                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
13028                    let has_matching_registration =
13029                        diagnostics_by_server_id[ix].1.iter().any(|entry| {
13030                            entry.diagnostic.registration_id.as_ref()
13031                                == Some(&cleared_registration_id)
13032                        });
13033                    if has_matching_registration {
13034                        let abs_path = worktree.read(cx).absolutize(rel_path);
13035                        affected_abs_paths.insert(abs_path);
13036                    }
13037                }
13038            }
13039        }
13040
13041        if affected_abs_paths.is_empty() {
13042            return Ok(());
13043        }
13044
13045        // Send a fake diagnostic update which clears the state for the registration ID
13046        let clears: Vec<DocumentDiagnosticsUpdate<'static, DocumentDiagnostics>> =
13047            affected_abs_paths
13048                .into_iter()
13049                .map(|abs_path| DocumentDiagnosticsUpdate {
13050                    diagnostics: DocumentDiagnostics {
13051                        diagnostics: Vec::new(),
13052                        document_abs_path: abs_path,
13053                        version: None,
13054                    },
13055                    result_id: None,
13056                    registration_id: Some(cleared_registration_id.clone()),
13057                    server_id,
13058                    disk_based_sources: Cow::Borrowed(&[]),
13059                })
13060                .collect();
13061
13062        let merge_registration_id = cleared_registration_id.clone();
13063        self.merge_diagnostic_entries(
13064            clears,
13065            move |_, diagnostic, _| {
13066                if diagnostic.source_kind == DiagnosticSourceKind::Pulled {
13067                    diagnostic.registration_id != Some(merge_registration_id.clone())
13068                } else {
13069                    true
13070                }
13071            },
13072            cx,
13073        )?;
13074
13075        Ok(())
13076    }
13077
13078    async fn deduplicate_range_based_lsp_requests<T>(
13079        lsp_store: &Entity<Self>,
13080        server_id: Option<LanguageServerId>,
13081        lsp_request_id: LspRequestId,
13082        proto_request: &T::ProtoRequest,
13083        range: Range<Anchor>,
13084        cx: &mut AsyncApp,
13085    ) -> Result<()>
13086    where
13087        T: LspCommand,
13088        T::ProtoRequest: proto::LspRequestMessage,
13089    {
13090        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13091        let version = deserialize_version(proto_request.buffer_version());
13092        let buffer = lsp_store.update(cx, |this, cx| {
13093            this.buffer_store.read(cx).get_existing(buffer_id)
13094        })?;
13095        buffer
13096            .update(cx, |buffer, _| buffer.wait_for_version(version))
13097            .await?;
13098        lsp_store.update(cx, |lsp_store, cx| {
13099            let buffer_snapshot = buffer.read(cx).snapshot();
13100            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13101            let chunks_queried_for = lsp_data
13102                .inlay_hints
13103                .applicable_chunks(&[range.to_point(&buffer_snapshot)])
13104                .collect::<Vec<_>>();
13105            match chunks_queried_for.as_slice() {
13106                &[chunk] => {
13107                    let key = LspKey {
13108                        request_type: TypeId::of::<T>(),
13109                        server_queried: server_id,
13110                    };
13111                    let previous_request = lsp_data
13112                        .chunk_lsp_requests
13113                        .entry(key)
13114                        .or_default()
13115                        .insert(chunk, lsp_request_id);
13116                    if let Some((previous_request, running_requests)) =
13117                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
13118                    {
13119                        running_requests.remove(&previous_request);
13120                    }
13121                }
13122                _ambiguous_chunks => {
13123                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
13124                    // there, a buffer version-based check will be performed and outdated requests discarded.
13125                }
13126            }
13127            anyhow::Ok(())
13128        })?;
13129
13130        Ok(())
13131    }
13132
13133    async fn query_lsp_locally<T>(
13134        lsp_store: Entity<Self>,
13135        for_server_id: Option<LanguageServerId>,
13136        sender_id: proto::PeerId,
13137        lsp_request_id: LspRequestId,
13138        proto_request: T::ProtoRequest,
13139        position: Option<Anchor>,
13140        cx: &mut AsyncApp,
13141    ) -> Result<()>
13142    where
13143        T: LspCommand + Clone,
13144        T::ProtoRequest: proto::LspRequestMessage,
13145        <T::ProtoRequest as proto::RequestMessage>::Response:
13146            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
13147    {
13148        let buffer_id = BufferId::new(proto_request.buffer_id())?;
13149        let version = deserialize_version(proto_request.buffer_version());
13150        let buffer = lsp_store.update(cx, |this, cx| {
13151            this.buffer_store.read(cx).get_existing(buffer_id)
13152        })?;
13153        buffer
13154            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))
13155            .await?;
13156        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version());
13157        let request =
13158            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
13159        let key = LspKey {
13160            request_type: TypeId::of::<T>(),
13161            server_queried: for_server_id,
13162        };
13163        lsp_store.update(cx, |lsp_store, cx| {
13164            let request_task = match for_server_id {
13165                Some(server_id) => {
13166                    let server_task = lsp_store.request_lsp(
13167                        buffer.clone(),
13168                        LanguageServerToQuery::Other(server_id),
13169                        request.clone(),
13170                        cx,
13171                    );
13172                    cx.background_spawn(async move {
13173                        let mut responses = Vec::new();
13174                        match server_task.await {
13175                            Ok(response) => responses.push((server_id, response)),
13176                            // rust-analyzer likes to error with this when its still loading up
13177                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
13178                            Err(e) => log::error!(
13179                                "Error handling response for request {request:?}: {e:#}"
13180                            ),
13181                        }
13182                        responses
13183                    })
13184                }
13185                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
13186            };
13187            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
13188            if T::ProtoRequest::stop_previous_requests() {
13189                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
13190                    lsp_requests.clear();
13191                }
13192            }
13193            lsp_data.lsp_requests.entry(key).or_default().insert(
13194                lsp_request_id,
13195                cx.spawn(async move |lsp_store, cx| {
13196                    let response = request_task.await;
13197                    lsp_store
13198                        .update(cx, |lsp_store, cx| {
13199                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
13200                            {
13201                                let response = response
13202                                    .into_iter()
13203                                    .map(|(server_id, response)| {
13204                                        (
13205                                            server_id.to_proto(),
13206                                            T::response_to_proto(
13207                                                response,
13208                                                lsp_store,
13209                                                sender_id,
13210                                                &buffer_version,
13211                                                cx,
13212                                            )
13213                                            .into(),
13214                                        )
13215                                    })
13216                                    .collect::<HashMap<_, _>>();
13217                                match client.send_lsp_response::<T::ProtoRequest>(
13218                                    project_id,
13219                                    lsp_request_id,
13220                                    response,
13221                                ) {
13222                                    Ok(()) => {}
13223                                    Err(e) => {
13224                                        log::error!("Failed to send LSP response: {e:#}",)
13225                                    }
13226                                }
13227                            }
13228                        })
13229                        .ok();
13230                }),
13231            );
13232        });
13233        Ok(())
13234    }
13235
13236    fn take_text_document_sync_options(
13237        capabilities: &mut lsp::ServerCapabilities,
13238    ) -> lsp::TextDocumentSyncOptions {
13239        match capabilities.text_document_sync.take() {
13240            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
13241            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
13242                let mut sync_options = lsp::TextDocumentSyncOptions::default();
13243                sync_options.change = Some(sync_kind);
13244                sync_options
13245            }
13246            None => lsp::TextDocumentSyncOptions::default(),
13247        }
13248    }
13249
13250    #[cfg(any(test, feature = "test-support"))]
13251    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
13252        Some(
13253            self.lsp_data
13254                .get_mut(&buffer_id)?
13255                .code_lens
13256                .take()?
13257                .update
13258                .take()?
13259                .1,
13260        )
13261    }
13262
13263    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
13264        self.downstream_client.clone()
13265    }
13266
13267    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
13268        self.worktree_store.clone()
13269    }
13270
13271    /// Gets what's stored in the LSP data for the given buffer.
13272    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
13273        self.lsp_data.get_mut(&buffer_id)
13274    }
13275
13276    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
13277    /// new [`BufferLspData`] will be created to replace the previous state.
13278    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
13279        let (buffer_id, buffer_version) =
13280            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
13281        let lsp_data = self
13282            .lsp_data
13283            .entry(buffer_id)
13284            .or_insert_with(|| BufferLspData::new(buffer, cx));
13285        if buffer_version.changed_since(&lsp_data.buffer_version) {
13286            *lsp_data = BufferLspData::new(buffer, cx);
13287        }
13288        lsp_data
13289    }
13290}
13291
13292// Registration with registerOptions as null, should fallback to true.
13293// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
13294fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
13295    reg: lsp::Registration,
13296) -> Result<OneOf<bool, T>> {
13297    Ok(match reg.register_options {
13298        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
13299        None => OneOf::Left(true),
13300    })
13301}
13302
13303fn subscribe_to_binary_statuses(
13304    languages: &Arc<LanguageRegistry>,
13305    cx: &mut Context<'_, LspStore>,
13306) -> Task<()> {
13307    let mut server_statuses = languages.language_server_binary_statuses();
13308    cx.spawn(async move |lsp_store, cx| {
13309        while let Some((server_name, binary_status)) = server_statuses.next().await {
13310            if lsp_store
13311                .update(cx, |_, cx| {
13312                    let mut message = None;
13313                    let binary_status = match binary_status {
13314                        BinaryStatus::None => proto::ServerBinaryStatus::None,
13315                        BinaryStatus::CheckingForUpdate => {
13316                            proto::ServerBinaryStatus::CheckingForUpdate
13317                        }
13318                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
13319                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
13320                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
13321                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
13322                        BinaryStatus::Failed { error } => {
13323                            message = Some(error);
13324                            proto::ServerBinaryStatus::Failed
13325                        }
13326                    };
13327                    cx.emit(LspStoreEvent::LanguageServerUpdate {
13328                        // Binary updates are about the binary that might not have any language server id at that point.
13329                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
13330                        language_server_id: LanguageServerId(0),
13331                        name: Some(server_name),
13332                        message: proto::update_language_server::Variant::StatusUpdate(
13333                            proto::StatusUpdate {
13334                                message,
13335                                status: Some(proto::status_update::Status::Binary(
13336                                    binary_status as i32,
13337                                )),
13338                            },
13339                        ),
13340                    });
13341                })
13342                .is_err()
13343            {
13344                break;
13345            }
13346        }
13347    })
13348}
13349
13350fn lsp_workspace_diagnostics_refresh(
13351    registration_id: Option<String>,
13352    options: DiagnosticServerCapabilities,
13353    server: Arc<LanguageServer>,
13354    cx: &mut Context<'_, LspStore>,
13355) -> Option<WorkspaceRefreshTask> {
13356    let identifier = workspace_diagnostic_identifier(&options)?;
13357    let registration_id_shared = registration_id.as_ref().map(SharedString::from);
13358
13359    let (progress_tx, mut progress_rx) = mpsc::channel(1);
13360    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
13361    refresh_tx.try_send(()).ok();
13362
13363    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
13364        let mut attempts = 0;
13365        let max_attempts = 50;
13366        let mut requests = 0;
13367
13368        loop {
13369            let Some(()) = refresh_rx.recv().await else {
13370                return;
13371            };
13372
13373            'request: loop {
13374                requests += 1;
13375                if attempts > max_attempts {
13376                    log::error!(
13377                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
13378                    );
13379                    return;
13380                }
13381                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
13382                cx.background_executor()
13383                    .timer(Duration::from_millis(backoff_millis))
13384                    .await;
13385                attempts += 1;
13386
13387                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
13388                    lsp_store
13389                        .result_ids_for_workspace_refresh(server.server_id(), &registration_id_shared)
13390                        .into_iter()
13391                        .filter_map(|(abs_path, result_id)| {
13392                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
13393                            Some(lsp::PreviousResultId {
13394                                uri,
13395                                value: result_id.to_string(),
13396                            })
13397                        })
13398                        .collect()
13399                }) else {
13400                    return;
13401                };
13402
13403                let token = if let Some(registration_id) = &registration_id {
13404                    format!(
13405                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{registration_id}",
13406                        server.server_id(),
13407                    )
13408                } else {
13409                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
13410                };
13411
13412                progress_rx.try_recv().ok();
13413                let timer =
13414                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
13415                let progress = pin!(progress_rx.recv().fuse());
13416                let response_result = server
13417                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
13418                        lsp::WorkspaceDiagnosticParams {
13419                            previous_result_ids,
13420                            identifier: identifier.clone(),
13421                            work_done_progress_params: Default::default(),
13422                            partial_result_params: lsp::PartialResultParams {
13423                                partial_result_token: Some(lsp::ProgressToken::String(token)),
13424                            },
13425                        },
13426                        select(timer, progress).then(|either| match either {
13427                            Either::Left((message, ..)) => ready(message).left_future(),
13428                            Either::Right(..) => pending::<String>().right_future(),
13429                        }),
13430                    )
13431                    .await;
13432
13433                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
13434                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
13435                match response_result {
13436                    ConnectionResult::Timeout => {
13437                        log::error!("Timeout during workspace diagnostics pull");
13438                        continue 'request;
13439                    }
13440                    ConnectionResult::ConnectionReset => {
13441                        log::error!("Server closed a workspace diagnostics pull request");
13442                        continue 'request;
13443                    }
13444                    ConnectionResult::Result(Err(e)) => {
13445                        log::error!("Error during workspace diagnostics pull: {e:#}");
13446                        break 'request;
13447                    }
13448                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
13449                        attempts = 0;
13450                        if lsp_store
13451                            .update(cx, |lsp_store, cx| {
13452                                lsp_store.apply_workspace_diagnostic_report(
13453                                    server.server_id(),
13454                                    pulled_diagnostics,
13455                                    registration_id_shared.clone(),
13456                                    cx,
13457                                )
13458                            })
13459                            .is_err()
13460                        {
13461                            return;
13462                        }
13463                        break 'request;
13464                    }
13465                }
13466            }
13467        }
13468    });
13469
13470    Some(WorkspaceRefreshTask {
13471        refresh_tx,
13472        progress_tx,
13473        task: workspace_query_language_server,
13474    })
13475}
13476
13477fn buffer_diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<String> {
13478    match &options {
13479        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13480            diagnostic_options.identifier.clone()
13481        }
13482        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13483            let diagnostic_options = &registration_options.diagnostic_options;
13484            diagnostic_options.identifier.clone()
13485        }
13486    }
13487}
13488
13489fn workspace_diagnostic_identifier(
13490    options: &DiagnosticServerCapabilities,
13491) -> Option<Option<String>> {
13492    match &options {
13493        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
13494            if !diagnostic_options.workspace_diagnostics {
13495                return None;
13496            }
13497            Some(diagnostic_options.identifier.clone())
13498        }
13499        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
13500            let diagnostic_options = &registration_options.diagnostic_options;
13501            if !diagnostic_options.workspace_diagnostics {
13502                return None;
13503            }
13504            Some(diagnostic_options.identifier.clone())
13505        }
13506    }
13507}
13508
13509fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
13510    let CompletionSource::BufferWord {
13511        word_range,
13512        resolved,
13513    } = &mut completion.source
13514    else {
13515        return;
13516    };
13517    if *resolved {
13518        return;
13519    }
13520
13521    if completion.new_text
13522        != snapshot
13523            .text_for_range(word_range.clone())
13524            .collect::<String>()
13525    {
13526        return;
13527    }
13528
13529    let mut offset = 0;
13530    for chunk in snapshot.chunks(word_range.clone(), true) {
13531        let end_offset = offset + chunk.text.len();
13532        if let Some(highlight_id) = chunk.syntax_highlight_id {
13533            completion
13534                .label
13535                .runs
13536                .push((offset..end_offset, highlight_id));
13537        }
13538        offset = end_offset;
13539    }
13540    *resolved = true;
13541}
13542
13543impl EventEmitter<LspStoreEvent> for LspStore {}
13544
13545fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
13546    hover
13547        .contents
13548        .retain(|hover_block| !hover_block.text.trim().is_empty());
13549    if hover.contents.is_empty() {
13550        None
13551    } else {
13552        Some(hover)
13553    }
13554}
13555
13556async fn populate_labels_for_completions(
13557    new_completions: Vec<CoreCompletion>,
13558    language: Option<Arc<Language>>,
13559    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13560) -> Vec<Completion> {
13561    let lsp_completions = new_completions
13562        .iter()
13563        .filter_map(|new_completion| {
13564            new_completion
13565                .source
13566                .lsp_completion(true)
13567                .map(|lsp_completion| lsp_completion.into_owned())
13568        })
13569        .collect::<Vec<_>>();
13570
13571    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
13572        lsp_adapter
13573            .labels_for_completions(&lsp_completions, language)
13574            .await
13575            .log_err()
13576            .unwrap_or_default()
13577    } else {
13578        Vec::new()
13579    }
13580    .into_iter()
13581    .fuse();
13582
13583    let mut completions = Vec::new();
13584    for completion in new_completions {
13585        match completion.source.lsp_completion(true) {
13586            Some(lsp_completion) => {
13587                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
13588
13589                let mut label = labels.next().flatten().unwrap_or_else(|| {
13590                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
13591                });
13592                ensure_uniform_list_compatible_label(&mut label);
13593                completions.push(Completion {
13594                    label,
13595                    documentation,
13596                    replace_range: completion.replace_range,
13597                    new_text: completion.new_text,
13598                    insert_text_mode: lsp_completion.insert_text_mode,
13599                    source: completion.source,
13600                    icon_path: None,
13601                    confirm: None,
13602                    match_start: None,
13603                    snippet_deduplication_key: None,
13604                });
13605            }
13606            None => {
13607                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
13608                ensure_uniform_list_compatible_label(&mut label);
13609                completions.push(Completion {
13610                    label,
13611                    documentation: None,
13612                    replace_range: completion.replace_range,
13613                    new_text: completion.new_text,
13614                    source: completion.source,
13615                    insert_text_mode: None,
13616                    icon_path: None,
13617                    confirm: None,
13618                    match_start: None,
13619                    snippet_deduplication_key: None,
13620                });
13621            }
13622        }
13623    }
13624    completions
13625}
13626
13627#[derive(Debug)]
13628pub enum LanguageServerToQuery {
13629    /// Query language servers in order of users preference, up until one capable of handling the request is found.
13630    FirstCapable,
13631    /// Query a specific language server.
13632    Other(LanguageServerId),
13633}
13634
13635#[derive(Default)]
13636struct RenamePathsWatchedForServer {
13637    did_rename: Vec<RenameActionPredicate>,
13638    will_rename: Vec<RenameActionPredicate>,
13639}
13640
13641impl RenamePathsWatchedForServer {
13642    fn with_did_rename_patterns(
13643        mut self,
13644        did_rename: Option<&FileOperationRegistrationOptions>,
13645    ) -> Self {
13646        if let Some(did_rename) = did_rename {
13647            self.did_rename = did_rename
13648                .filters
13649                .iter()
13650                .filter_map(|filter| filter.try_into().log_err())
13651                .collect();
13652        }
13653        self
13654    }
13655    fn with_will_rename_patterns(
13656        mut self,
13657        will_rename: Option<&FileOperationRegistrationOptions>,
13658    ) -> Self {
13659        if let Some(will_rename) = will_rename {
13660            self.will_rename = will_rename
13661                .filters
13662                .iter()
13663                .filter_map(|filter| filter.try_into().log_err())
13664                .collect();
13665        }
13666        self
13667    }
13668
13669    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
13670        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
13671    }
13672    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
13673        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
13674    }
13675}
13676
13677impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
13678    type Error = globset::Error;
13679    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
13680        Ok(Self {
13681            kind: ops.pattern.matches.clone(),
13682            glob: GlobBuilder::new(&ops.pattern.glob)
13683                .case_insensitive(
13684                    ops.pattern
13685                        .options
13686                        .as_ref()
13687                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
13688                )
13689                .build()?
13690                .compile_matcher(),
13691        })
13692    }
13693}
13694struct RenameActionPredicate {
13695    glob: GlobMatcher,
13696    kind: Option<FileOperationPatternKind>,
13697}
13698
13699impl RenameActionPredicate {
13700    // Returns true if language server should be notified
13701    fn eval(&self, path: &str, is_dir: bool) -> bool {
13702        self.kind.as_ref().is_none_or(|kind| {
13703            let expected_kind = if is_dir {
13704                FileOperationPatternKind::Folder
13705            } else {
13706                FileOperationPatternKind::File
13707            };
13708            kind == &expected_kind
13709        }) && self.glob.is_match(path)
13710    }
13711}
13712
13713#[derive(Default)]
13714struct LanguageServerWatchedPaths {
13715    worktree_paths: HashMap<WorktreeId, GlobSet>,
13716    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
13717}
13718
13719#[derive(Default)]
13720struct LanguageServerWatchedPathsBuilder {
13721    worktree_paths: HashMap<WorktreeId, GlobSet>,
13722    abs_paths: HashMap<Arc<Path>, GlobSet>,
13723}
13724
13725impl LanguageServerWatchedPathsBuilder {
13726    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
13727        self.worktree_paths.insert(worktree_id, glob_set);
13728    }
13729    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
13730        self.abs_paths.insert(path, glob_set);
13731    }
13732    fn build(
13733        self,
13734        fs: Arc<dyn Fs>,
13735        language_server_id: LanguageServerId,
13736        cx: &mut Context<LspStore>,
13737    ) -> LanguageServerWatchedPaths {
13738        let lsp_store = cx.weak_entity();
13739
13740        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
13741        let abs_paths = self
13742            .abs_paths
13743            .into_iter()
13744            .map(|(abs_path, globset)| {
13745                let task = cx.spawn({
13746                    let abs_path = abs_path.clone();
13747                    let fs = fs.clone();
13748
13749                    let lsp_store = lsp_store.clone();
13750                    async move |_, cx| {
13751                        maybe!(async move {
13752                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
13753                            while let Some(update) = push_updates.0.next().await {
13754                                let action = lsp_store
13755                                    .update(cx, |this, _| {
13756                                        let Some(local) = this.as_local() else {
13757                                            return ControlFlow::Break(());
13758                                        };
13759                                        let Some(watcher) = local
13760                                            .language_server_watched_paths
13761                                            .get(&language_server_id)
13762                                        else {
13763                                            return ControlFlow::Break(());
13764                                        };
13765                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13766                                            "Watched abs path is not registered with a watcher",
13767                                        );
13768                                        let matching_entries = update
13769                                            .into_iter()
13770                                            .filter(|event| globs.is_match(&event.path))
13771                                            .collect::<Vec<_>>();
13772                                        this.lsp_notify_abs_paths_changed(
13773                                            language_server_id,
13774                                            matching_entries,
13775                                        );
13776                                        ControlFlow::Continue(())
13777                                    })
13778                                    .ok()?;
13779
13780                                if action.is_break() {
13781                                    break;
13782                                }
13783                            }
13784                            Some(())
13785                        })
13786                        .await;
13787                    }
13788                });
13789                (abs_path, (globset, task))
13790            })
13791            .collect();
13792        LanguageServerWatchedPaths {
13793            worktree_paths: self.worktree_paths,
13794            abs_paths,
13795        }
13796    }
13797}
13798
13799struct LspBufferSnapshot {
13800    version: i32,
13801    snapshot: TextBufferSnapshot,
13802}
13803
13804/// A prompt requested by LSP server.
13805#[derive(Clone, Debug)]
13806pub struct LanguageServerPromptRequest {
13807    pub id: usize,
13808    pub level: PromptLevel,
13809    pub message: String,
13810    pub actions: Vec<MessageActionItem>,
13811    pub lsp_name: String,
13812    pub(crate) response_channel: smol::channel::Sender<MessageActionItem>,
13813}
13814
13815impl LanguageServerPromptRequest {
13816    pub fn new(
13817        level: PromptLevel,
13818        message: String,
13819        actions: Vec<MessageActionItem>,
13820        lsp_name: String,
13821        response_channel: smol::channel::Sender<MessageActionItem>,
13822    ) -> Self {
13823        let id = NEXT_PROMPT_REQUEST_ID.fetch_add(1, atomic::Ordering::AcqRel);
13824        LanguageServerPromptRequest {
13825            id,
13826            level,
13827            message,
13828            actions,
13829            lsp_name,
13830            response_channel,
13831        }
13832    }
13833    pub async fn respond(self, index: usize) -> Option<()> {
13834        if let Some(response) = self.actions.into_iter().nth(index) {
13835            self.response_channel.send(response).await.ok()
13836        } else {
13837            None
13838        }
13839    }
13840
13841    #[cfg(any(test, feature = "test-support"))]
13842    pub fn test(
13843        level: PromptLevel,
13844        message: String,
13845        actions: Vec<MessageActionItem>,
13846        lsp_name: String,
13847    ) -> Self {
13848        let (tx, _rx) = smol::channel::unbounded();
13849        LanguageServerPromptRequest::new(level, message, actions, lsp_name, tx)
13850    }
13851}
13852impl PartialEq for LanguageServerPromptRequest {
13853    fn eq(&self, other: &Self) -> bool {
13854        self.message == other.message && self.actions == other.actions
13855    }
13856}
13857
13858#[derive(Clone, Debug, PartialEq)]
13859pub enum LanguageServerLogType {
13860    Log(MessageType),
13861    Trace { verbose_info: Option<String> },
13862    Rpc { received: bool },
13863}
13864
13865impl LanguageServerLogType {
13866    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13867        match self {
13868            Self::Log(log_type) => {
13869                use proto::log_message::LogLevel;
13870                let level = match *log_type {
13871                    MessageType::ERROR => LogLevel::Error,
13872                    MessageType::WARNING => LogLevel::Warning,
13873                    MessageType::INFO => LogLevel::Info,
13874                    MessageType::LOG => LogLevel::Log,
13875                    other => {
13876                        log::warn!("Unknown lsp log message type: {other:?}");
13877                        LogLevel::Log
13878                    }
13879                };
13880                proto::language_server_log::LogType::Log(proto::LogMessage {
13881                    level: level as i32,
13882                })
13883            }
13884            Self::Trace { verbose_info } => {
13885                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13886                    verbose_info: verbose_info.to_owned(),
13887                })
13888            }
13889            Self::Rpc { received } => {
13890                let kind = if *received {
13891                    proto::rpc_message::Kind::Received
13892                } else {
13893                    proto::rpc_message::Kind::Sent
13894                };
13895                let kind = kind as i32;
13896                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13897            }
13898        }
13899    }
13900
13901    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13902        use proto::log_message::LogLevel;
13903        use proto::rpc_message;
13904        match log_type {
13905            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13906                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13907                    LogLevel::Error => MessageType::ERROR,
13908                    LogLevel::Warning => MessageType::WARNING,
13909                    LogLevel::Info => MessageType::INFO,
13910                    LogLevel::Log => MessageType::LOG,
13911                },
13912            ),
13913            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13914                verbose_info: trace_message.verbose_info,
13915            },
13916            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13917                received: match rpc_message::Kind::from_i32(message.kind)
13918                    .unwrap_or(rpc_message::Kind::Received)
13919                {
13920                    rpc_message::Kind::Received => true,
13921                    rpc_message::Kind::Sent => false,
13922                },
13923            },
13924        }
13925    }
13926}
13927
13928pub struct WorkspaceRefreshTask {
13929    refresh_tx: mpsc::Sender<()>,
13930    progress_tx: mpsc::Sender<()>,
13931    #[allow(dead_code)]
13932    task: Task<()>,
13933}
13934
13935pub enum LanguageServerState {
13936    Starting {
13937        startup: Task<Option<Arc<LanguageServer>>>,
13938        /// List of language servers that will be added to the workspace once it's initialization completes.
13939        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13940    },
13941
13942    Running {
13943        adapter: Arc<CachedLspAdapter>,
13944        server: Arc<LanguageServer>,
13945        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13946        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13947    },
13948}
13949
13950impl LanguageServerState {
13951    fn add_workspace_folder(&self, uri: Uri) {
13952        match self {
13953            LanguageServerState::Starting {
13954                pending_workspace_folders,
13955                ..
13956            } => {
13957                pending_workspace_folders.lock().insert(uri);
13958            }
13959            LanguageServerState::Running { server, .. } => {
13960                server.add_workspace_folder(uri);
13961            }
13962        }
13963    }
13964    fn _remove_workspace_folder(&self, uri: Uri) {
13965        match self {
13966            LanguageServerState::Starting {
13967                pending_workspace_folders,
13968                ..
13969            } => {
13970                pending_workspace_folders.lock().remove(&uri);
13971            }
13972            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13973        }
13974    }
13975}
13976
13977impl std::fmt::Debug for LanguageServerState {
13978    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13979        match self {
13980            LanguageServerState::Starting { .. } => {
13981                f.debug_struct("LanguageServerState::Starting").finish()
13982            }
13983            LanguageServerState::Running { .. } => {
13984                f.debug_struct("LanguageServerState::Running").finish()
13985            }
13986        }
13987    }
13988}
13989
13990#[derive(Clone, Debug, Serialize)]
13991pub struct LanguageServerProgress {
13992    pub is_disk_based_diagnostics_progress: bool,
13993    pub is_cancellable: bool,
13994    pub title: Option<String>,
13995    pub message: Option<String>,
13996    pub percentage: Option<usize>,
13997    #[serde(skip_serializing)]
13998    pub last_update_at: Instant,
13999}
14000
14001#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
14002pub struct DiagnosticSummary {
14003    pub error_count: usize,
14004    pub warning_count: usize,
14005}
14006
14007impl DiagnosticSummary {
14008    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
14009        let mut this = Self {
14010            error_count: 0,
14011            warning_count: 0,
14012        };
14013
14014        for entry in diagnostics {
14015            if entry.diagnostic.is_primary {
14016                match entry.diagnostic.severity {
14017                    DiagnosticSeverity::ERROR => this.error_count += 1,
14018                    DiagnosticSeverity::WARNING => this.warning_count += 1,
14019                    _ => {}
14020                }
14021            }
14022        }
14023
14024        this
14025    }
14026
14027    pub fn is_empty(&self) -> bool {
14028        self.error_count == 0 && self.warning_count == 0
14029    }
14030
14031    pub fn to_proto(
14032        self,
14033        language_server_id: LanguageServerId,
14034        path: &RelPath,
14035    ) -> proto::DiagnosticSummary {
14036        proto::DiagnosticSummary {
14037            path: path.to_proto(),
14038            language_server_id: language_server_id.0 as u64,
14039            error_count: self.error_count as u32,
14040            warning_count: self.warning_count as u32,
14041        }
14042    }
14043}
14044
14045#[derive(Clone, Debug)]
14046pub enum CompletionDocumentation {
14047    /// There is no documentation for this completion.
14048    Undocumented,
14049    /// A single line of documentation.
14050    SingleLine(SharedString),
14051    /// Multiple lines of plain text documentation.
14052    MultiLinePlainText(SharedString),
14053    /// Markdown documentation.
14054    MultiLineMarkdown(SharedString),
14055    /// Both single line and multiple lines of plain text documentation.
14056    SingleLineAndMultiLinePlainText {
14057        single_line: SharedString,
14058        plain_text: Option<SharedString>,
14059    },
14060}
14061
14062impl CompletionDocumentation {
14063    #[cfg(any(test, feature = "test-support"))]
14064    pub fn text(&self) -> SharedString {
14065        match self {
14066            CompletionDocumentation::Undocumented => "".into(),
14067            CompletionDocumentation::SingleLine(s) => s.clone(),
14068            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
14069            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
14070            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
14071                single_line.clone()
14072            }
14073        }
14074    }
14075}
14076
14077impl From<lsp::Documentation> for CompletionDocumentation {
14078    fn from(docs: lsp::Documentation) -> Self {
14079        match docs {
14080            lsp::Documentation::String(text) => {
14081                if text.lines().count() <= 1 {
14082                    CompletionDocumentation::SingleLine(text.trim().to_string().into())
14083                } else {
14084                    CompletionDocumentation::MultiLinePlainText(text.into())
14085                }
14086            }
14087
14088            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
14089                lsp::MarkupKind::PlainText => {
14090                    if value.lines().count() <= 1 {
14091                        CompletionDocumentation::SingleLine(value.into())
14092                    } else {
14093                        CompletionDocumentation::MultiLinePlainText(value.into())
14094                    }
14095                }
14096
14097                lsp::MarkupKind::Markdown => {
14098                    CompletionDocumentation::MultiLineMarkdown(value.into())
14099                }
14100            },
14101        }
14102    }
14103}
14104
14105pub enum ResolvedHint {
14106    Resolved(InlayHint),
14107    Resolving(Shared<Task<()>>),
14108}
14109
14110pub fn glob_literal_prefix(glob: &Path) -> PathBuf {
14111    glob.components()
14112        .take_while(|component| match component {
14113            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
14114            _ => true,
14115        })
14116        .collect()
14117}
14118
14119pub struct SshLspAdapter {
14120    name: LanguageServerName,
14121    binary: LanguageServerBinary,
14122    initialization_options: Option<String>,
14123    code_action_kinds: Option<Vec<CodeActionKind>>,
14124}
14125
14126impl SshLspAdapter {
14127    pub fn new(
14128        name: LanguageServerName,
14129        binary: LanguageServerBinary,
14130        initialization_options: Option<String>,
14131        code_action_kinds: Option<String>,
14132    ) -> Self {
14133        Self {
14134            name,
14135            binary,
14136            initialization_options,
14137            code_action_kinds: code_action_kinds
14138                .as_ref()
14139                .and_then(|c| serde_json::from_str(c).ok()),
14140        }
14141    }
14142}
14143
14144impl LspInstaller for SshLspAdapter {
14145    type BinaryVersion = ();
14146    async fn check_if_user_installed(
14147        &self,
14148        _: &dyn LspAdapterDelegate,
14149        _: Option<Toolchain>,
14150        _: &AsyncApp,
14151    ) -> Option<LanguageServerBinary> {
14152        Some(self.binary.clone())
14153    }
14154
14155    async fn cached_server_binary(
14156        &self,
14157        _: PathBuf,
14158        _: &dyn LspAdapterDelegate,
14159    ) -> Option<LanguageServerBinary> {
14160        None
14161    }
14162
14163    async fn fetch_latest_server_version(
14164        &self,
14165        _: &dyn LspAdapterDelegate,
14166        _: bool,
14167        _: &mut AsyncApp,
14168    ) -> Result<()> {
14169        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
14170    }
14171
14172    async fn fetch_server_binary(
14173        &self,
14174        _: (),
14175        _: PathBuf,
14176        _: &dyn LspAdapterDelegate,
14177    ) -> Result<LanguageServerBinary> {
14178        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
14179    }
14180}
14181
14182#[async_trait(?Send)]
14183impl LspAdapter for SshLspAdapter {
14184    fn name(&self) -> LanguageServerName {
14185        self.name.clone()
14186    }
14187
14188    async fn initialization_options(
14189        self: Arc<Self>,
14190        _: &Arc<dyn LspAdapterDelegate>,
14191    ) -> Result<Option<serde_json::Value>> {
14192        let Some(options) = &self.initialization_options else {
14193            return Ok(None);
14194        };
14195        let result = serde_json::from_str(options)?;
14196        Ok(result)
14197    }
14198
14199    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
14200        self.code_action_kinds.clone()
14201    }
14202}
14203
14204pub fn language_server_settings<'a>(
14205    delegate: &'a dyn LspAdapterDelegate,
14206    language: &LanguageServerName,
14207    cx: &'a App,
14208) -> Option<&'a LspSettings> {
14209    language_server_settings_for(
14210        SettingsLocation {
14211            worktree_id: delegate.worktree_id(),
14212            path: RelPath::empty(),
14213        },
14214        language,
14215        cx,
14216    )
14217}
14218
14219pub fn language_server_settings_for<'a>(
14220    location: SettingsLocation<'a>,
14221    language: &LanguageServerName,
14222    cx: &'a App,
14223) -> Option<&'a LspSettings> {
14224    ProjectSettings::get(Some(location), cx).lsp.get(language)
14225}
14226
14227pub struct LocalLspAdapterDelegate {
14228    lsp_store: WeakEntity<LspStore>,
14229    worktree: worktree::Snapshot,
14230    fs: Arc<dyn Fs>,
14231    http_client: Arc<dyn HttpClient>,
14232    language_registry: Arc<LanguageRegistry>,
14233    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
14234}
14235
14236impl LocalLspAdapterDelegate {
14237    pub fn new(
14238        language_registry: Arc<LanguageRegistry>,
14239        environment: &Entity<ProjectEnvironment>,
14240        lsp_store: WeakEntity<LspStore>,
14241        worktree: &Entity<Worktree>,
14242        http_client: Arc<dyn HttpClient>,
14243        fs: Arc<dyn Fs>,
14244        cx: &mut App,
14245    ) -> Arc<Self> {
14246        let load_shell_env_task =
14247            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
14248
14249        Arc::new(Self {
14250            lsp_store,
14251            worktree: worktree.read(cx).snapshot(),
14252            fs,
14253            http_client,
14254            language_registry,
14255            load_shell_env_task,
14256        })
14257    }
14258
14259    pub fn from_local_lsp(
14260        local: &LocalLspStore,
14261        worktree: &Entity<Worktree>,
14262        cx: &mut App,
14263    ) -> Arc<Self> {
14264        Self::new(
14265            local.languages.clone(),
14266            &local.environment,
14267            local.weak.clone(),
14268            worktree,
14269            local.http_client.clone(),
14270            local.fs.clone(),
14271            cx,
14272        )
14273    }
14274}
14275
14276#[async_trait]
14277impl LspAdapterDelegate for LocalLspAdapterDelegate {
14278    fn show_notification(&self, message: &str, cx: &mut App) {
14279        self.lsp_store
14280            .update(cx, |_, cx| {
14281                cx.emit(LspStoreEvent::Notification(message.to_owned()))
14282            })
14283            .ok();
14284    }
14285
14286    fn http_client(&self) -> Arc<dyn HttpClient> {
14287        self.http_client.clone()
14288    }
14289
14290    fn worktree_id(&self) -> WorktreeId {
14291        self.worktree.id()
14292    }
14293
14294    fn worktree_root_path(&self) -> &Path {
14295        self.worktree.abs_path().as_ref()
14296    }
14297
14298    fn resolve_executable_path(&self, path: PathBuf) -> PathBuf {
14299        self.worktree.resolve_executable_path(path)
14300    }
14301
14302    async fn shell_env(&self) -> HashMap<String, String> {
14303        let task = self.load_shell_env_task.clone();
14304        task.await.unwrap_or_default()
14305    }
14306
14307    async fn npm_package_installed_version(
14308        &self,
14309        package_name: &str,
14310    ) -> Result<Option<(PathBuf, Version)>> {
14311        let local_package_directory = self.worktree_root_path();
14312        let node_modules_directory = local_package_directory.join("node_modules");
14313
14314        if let Some(version) =
14315            read_package_installed_version(node_modules_directory.clone(), package_name).await?
14316        {
14317            return Ok(Some((node_modules_directory, version)));
14318        }
14319        let Some(npm) = self.which("npm".as_ref()).await else {
14320            log::warn!(
14321                "Failed to find npm executable for {:?}",
14322                local_package_directory
14323            );
14324            return Ok(None);
14325        };
14326
14327        let env = self.shell_env().await;
14328        let output = util::command::new_smol_command(&npm)
14329            .args(["root", "-g"])
14330            .envs(env)
14331            .current_dir(local_package_directory)
14332            .output()
14333            .await?;
14334        let global_node_modules =
14335            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
14336
14337        if let Some(version) =
14338            read_package_installed_version(global_node_modules.clone(), package_name).await?
14339        {
14340            return Ok(Some((global_node_modules, version)));
14341        }
14342        return Ok(None);
14343    }
14344
14345    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
14346        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
14347        if self.fs.is_file(&worktree_abs_path).await {
14348            worktree_abs_path.pop();
14349        }
14350
14351        let env = self.shell_env().await;
14352
14353        let shell_path = env.get("PATH").cloned();
14354
14355        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
14356    }
14357
14358    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
14359        let mut working_dir = self.worktree_root_path().to_path_buf();
14360        if self.fs.is_file(&working_dir).await {
14361            working_dir.pop();
14362        }
14363        let output = util::command::new_smol_command(&command.path)
14364            .args(command.arguments)
14365            .envs(command.env.clone().unwrap_or_default())
14366            .current_dir(working_dir)
14367            .output()
14368            .await?;
14369
14370        anyhow::ensure!(
14371            output.status.success(),
14372            "{}, stdout: {:?}, stderr: {:?}",
14373            output.status,
14374            String::from_utf8_lossy(&output.stdout),
14375            String::from_utf8_lossy(&output.stderr)
14376        );
14377        Ok(())
14378    }
14379
14380    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
14381        self.language_registry
14382            .update_lsp_binary_status(server_name, status);
14383    }
14384
14385    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
14386        self.language_registry
14387            .all_lsp_adapters()
14388            .into_iter()
14389            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
14390            .collect()
14391    }
14392
14393    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
14394        let dir = self.language_registry.language_server_download_dir(name)?;
14395
14396        if !dir.exists() {
14397            smol::fs::create_dir_all(&dir)
14398                .await
14399                .context("failed to create container directory")
14400                .log_err()?;
14401        }
14402
14403        Some(dir)
14404    }
14405
14406    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
14407        let entry = self
14408            .worktree
14409            .entry_for_path(path)
14410            .with_context(|| format!("no worktree entry for path {path:?}"))?;
14411        let abs_path = self.worktree.absolutize(&entry.path);
14412        self.fs.load(&abs_path).await
14413    }
14414}
14415
14416async fn populate_labels_for_symbols(
14417    symbols: Vec<CoreSymbol>,
14418    language_registry: &Arc<LanguageRegistry>,
14419    lsp_adapter: Option<Arc<CachedLspAdapter>>,
14420    output: &mut Vec<Symbol>,
14421) {
14422    #[allow(clippy::mutable_key_type)]
14423    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
14424
14425    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
14426    for symbol in symbols {
14427        let Some(file_name) = symbol.path.file_name() else {
14428            continue;
14429        };
14430        let language = language_registry
14431            .load_language_for_file_path(Path::new(file_name))
14432            .await
14433            .ok()
14434            .or_else(|| {
14435                unknown_paths.insert(file_name.into());
14436                None
14437            });
14438        symbols_by_language
14439            .entry(language)
14440            .or_default()
14441            .push(symbol);
14442    }
14443
14444    for unknown_path in unknown_paths {
14445        log::info!("no language found for symbol in file {unknown_path:?}");
14446    }
14447
14448    let mut label_params = Vec::new();
14449    for (language, mut symbols) in symbols_by_language {
14450        label_params.clear();
14451        label_params.extend(
14452            symbols
14453                .iter_mut()
14454                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
14455        );
14456
14457        let mut labels = Vec::new();
14458        if let Some(language) = language {
14459            let lsp_adapter = lsp_adapter.clone().or_else(|| {
14460                language_registry
14461                    .lsp_adapters(&language.name())
14462                    .first()
14463                    .cloned()
14464            });
14465            if let Some(lsp_adapter) = lsp_adapter {
14466                labels = lsp_adapter
14467                    .labels_for_symbols(&label_params, &language)
14468                    .await
14469                    .log_err()
14470                    .unwrap_or_default();
14471            }
14472        }
14473
14474        for ((symbol, (name, _)), label) in symbols
14475            .into_iter()
14476            .zip(label_params.drain(..))
14477            .zip(labels.into_iter().chain(iter::repeat(None)))
14478        {
14479            output.push(Symbol {
14480                language_server_name: symbol.language_server_name,
14481                source_worktree_id: symbol.source_worktree_id,
14482                source_language_server_id: symbol.source_language_server_id,
14483                path: symbol.path,
14484                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
14485                name,
14486                kind: symbol.kind,
14487                range: symbol.range,
14488            });
14489        }
14490    }
14491}
14492
14493fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
14494    match server.capabilities().text_document_sync.as_ref()? {
14495        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
14496            // Server wants didSave but didn't specify includeText.
14497            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
14498            // Server doesn't want didSave at all.
14499            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
14500            // Server provided SaveOptions.
14501            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
14502                Some(save_options.include_text.unwrap_or(false))
14503            }
14504        },
14505        // We do not have any save info. Kind affects didChange only.
14506        lsp::TextDocumentSyncCapability::Kind(_) => None,
14507    }
14508}
14509
14510/// Completion items are displayed in a `UniformList`.
14511/// Usually, those items are single-line strings, but in LSP responses,
14512/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
14513/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
14514/// 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,
14515/// breaking the completions menu presentation.
14516///
14517/// 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.
14518pub fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
14519    let mut new_text = String::with_capacity(label.text.len());
14520    let mut offset_map = vec![0; label.text.len() + 1];
14521    let mut last_char_was_space = false;
14522    let mut new_idx = 0;
14523    let chars = label.text.char_indices().fuse();
14524    let mut newlines_removed = false;
14525
14526    for (idx, c) in chars {
14527        offset_map[idx] = new_idx;
14528
14529        match c {
14530            '\n' if last_char_was_space => {
14531                newlines_removed = true;
14532            }
14533            '\t' | ' ' if last_char_was_space => {}
14534            '\n' if !last_char_was_space => {
14535                new_text.push(' ');
14536                new_idx += 1;
14537                last_char_was_space = true;
14538                newlines_removed = true;
14539            }
14540            ' ' | '\t' => {
14541                new_text.push(' ');
14542                new_idx += 1;
14543                last_char_was_space = true;
14544            }
14545            _ => {
14546                new_text.push(c);
14547                new_idx += c.len_utf8();
14548                last_char_was_space = false;
14549            }
14550        }
14551    }
14552    offset_map[label.text.len()] = new_idx;
14553
14554    // Only modify the label if newlines were removed.
14555    if !newlines_removed {
14556        return;
14557    }
14558
14559    let last_index = new_idx;
14560    let mut run_ranges_errors = Vec::new();
14561    label.runs.retain_mut(|(range, _)| {
14562        match offset_map.get(range.start) {
14563            Some(&start) => range.start = start,
14564            None => {
14565                run_ranges_errors.push(range.clone());
14566                return false;
14567            }
14568        }
14569
14570        match offset_map.get(range.end) {
14571            Some(&end) => range.end = end,
14572            None => {
14573                run_ranges_errors.push(range.clone());
14574                range.end = last_index;
14575            }
14576        }
14577        true
14578    });
14579    if !run_ranges_errors.is_empty() {
14580        log::error!(
14581            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
14582            label.text
14583        );
14584    }
14585
14586    let mut wrong_filter_range = None;
14587    if label.filter_range == (0..label.text.len()) {
14588        label.filter_range = 0..new_text.len();
14589    } else {
14590        let mut original_filter_range = Some(label.filter_range.clone());
14591        match offset_map.get(label.filter_range.start) {
14592            Some(&start) => label.filter_range.start = start,
14593            None => {
14594                wrong_filter_range = original_filter_range.take();
14595                label.filter_range.start = last_index;
14596            }
14597        }
14598
14599        match offset_map.get(label.filter_range.end) {
14600            Some(&end) => label.filter_range.end = end,
14601            None => {
14602                wrong_filter_range = original_filter_range.take();
14603                label.filter_range.end = last_index;
14604            }
14605        }
14606    }
14607    if let Some(wrong_filter_range) = wrong_filter_range {
14608        log::error!(
14609            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
14610            label.text
14611        );
14612    }
14613
14614    label.text = new_text;
14615}