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        inlay_hint_cache::BufferChunk,
   33        log_store::{GlobalLogStore, LanguageServerKind},
   34    },
   35    manifest_tree::{
   36        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   37        ManifestTree,
   38    },
   39    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   40    project_settings::{LspSettings, ProjectSettings},
   41    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   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, Task,
   59    WeakEntity,
   60};
   61use http_client::HttpClient;
   62use itertools::Itertools as _;
   63use language::{
   64    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, CodeLabel, Diagnostic,
   65    DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language, LanguageName,
   66    LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller, ManifestDelegate,
   67    ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Toolchain,
   68    Transaction, Unclipped,
   69    language_settings::{FormatOnSave, Formatter, LanguageSettings, language_settings},
   70    point_to_lsp,
   71    proto::{
   72        deserialize_anchor, deserialize_lsp_edit, deserialize_version, serialize_anchor,
   73        serialize_lsp_edit, serialize_version,
   74    },
   75    range_from_lsp, range_to_lsp,
   76};
   77use lsp::{
   78    AdapterServerCapabilities, CodeActionKind, CompletionContext, DiagnosticServerCapabilities,
   79    DiagnosticSeverity, DiagnosticTag, DidChangeWatchedFilesRegistrationOptions, Edit,
   80    FileOperationFilter, FileOperationPatternKind, FileOperationRegistrationOptions, FileRename,
   81    FileSystemWatcher, LSP_REQUEST_TIMEOUT, LanguageServer, LanguageServerBinary,
   82    LanguageServerBinaryOptions, LanguageServerId, LanguageServerName, LanguageServerSelector,
   83    LspRequestFuture, MessageActionItem, MessageType, OneOf, RenameFilesParams, SymbolKind,
   84    TextDocumentSyncSaveOptions, TextEdit, Uri, WillRenameFiles, WorkDoneProgressCancelParams,
   85    WorkspaceFolder, notification::DidRenameFiles,
   86};
   87use node_runtime::read_package_installed_version;
   88use parking_lot::Mutex;
   89use postage::{mpsc, sink::Sink, stream::Stream, watch};
   90use rand::prelude::*;
   91use rpc::{
   92    AnyProtoClient, ErrorCode, ErrorExt as _,
   93    proto::{LspRequestId, LspRequestMessage as _},
   94};
   95use serde::Serialize;
   96use settings::{Settings, SettingsLocation, SettingsStore};
   97use sha2::{Digest, Sha256};
   98use smol::channel::Sender;
   99use snippet::Snippet;
  100use std::{
  101    any::TypeId,
  102    borrow::Cow,
  103    cell::RefCell,
  104    cmp::{Ordering, Reverse},
  105    convert::TryInto,
  106    ffi::OsStr,
  107    future::ready,
  108    iter, mem,
  109    ops::{ControlFlow, Range},
  110    path::{self, Path, PathBuf},
  111    pin::pin,
  112    rc::Rc,
  113    sync::{
  114        Arc,
  115        atomic::{self, AtomicUsize},
  116    },
  117    time::{Duration, Instant},
  118};
  119use sum_tree::Dimensions;
  120use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, Point, ToPoint as _};
  121
  122use util::{
  123    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  124    paths::{PathStyle, SanitizedPath},
  125    post_inc,
  126    rel_path::RelPath,
  127};
  128
  129pub use fs::*;
  130pub use language::Location;
  131pub use lsp_store::inlay_hint_cache::{CacheInlayHints, InvalidationStrategy};
  132#[cfg(any(test, feature = "test-support"))]
  133pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  134pub use worktree::{
  135    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  136    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  137};
  138
  139const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  140pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  141const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  142
  143#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  144pub enum ProgressToken {
  145    Number(i32),
  146    String(SharedString),
  147}
  148
  149impl std::fmt::Display for ProgressToken {
  150    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  151        match self {
  152            Self::Number(number) => write!(f, "{number}"),
  153            Self::String(string) => write!(f, "{string}"),
  154        }
  155    }
  156}
  157
  158impl ProgressToken {
  159    fn from_lsp(value: lsp::NumberOrString) -> Self {
  160        match value {
  161            lsp::NumberOrString::Number(number) => Self::Number(number),
  162            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  163        }
  164    }
  165
  166    fn to_lsp(&self) -> lsp::NumberOrString {
  167        match self {
  168            Self::Number(number) => lsp::NumberOrString::Number(*number),
  169            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  170        }
  171    }
  172
  173    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  174        Some(match value.value? {
  175            proto::progress_token::Value::Number(number) => Self::Number(number),
  176            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  177        })
  178    }
  179
  180    fn to_proto(&self) -> proto::ProgressToken {
  181        proto::ProgressToken {
  182            value: Some(match self {
  183                Self::Number(number) => proto::progress_token::Value::Number(*number),
  184                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  185            }),
  186        }
  187    }
  188}
  189
  190#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  191pub enum FormatTrigger {
  192    Save,
  193    Manual,
  194}
  195
  196pub enum LspFormatTarget {
  197    Buffers,
  198    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  199}
  200
  201pub type OpenLspBufferHandle = Entity<Entity<Buffer>>;
  202
  203impl FormatTrigger {
  204    fn from_proto(value: i32) -> FormatTrigger {
  205        match value {
  206            0 => FormatTrigger::Save,
  207            1 => FormatTrigger::Manual,
  208            _ => FormatTrigger::Save,
  209        }
  210    }
  211}
  212
  213#[derive(Clone)]
  214struct UnifiedLanguageServer {
  215    id: LanguageServerId,
  216    project_roots: HashSet<Arc<RelPath>>,
  217}
  218
  219#[derive(Clone, Hash, PartialEq, Eq)]
  220struct LanguageServerSeed {
  221    worktree_id: WorktreeId,
  222    name: LanguageServerName,
  223    toolchain: Option<Toolchain>,
  224    settings: Arc<LspSettings>,
  225}
  226
  227#[derive(Debug)]
  228pub struct DocumentDiagnosticsUpdate<'a, D> {
  229    pub diagnostics: D,
  230    pub result_id: Option<String>,
  231    pub server_id: LanguageServerId,
  232    pub disk_based_sources: Cow<'a, [String]>,
  233}
  234
  235pub struct DocumentDiagnostics {
  236    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  237    document_abs_path: PathBuf,
  238    version: Option<i32>,
  239}
  240
  241#[derive(Default)]
  242struct DynamicRegistrations {
  243    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  244    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  245}
  246
  247pub struct LocalLspStore {
  248    weak: WeakEntity<LspStore>,
  249    worktree_store: Entity<WorktreeStore>,
  250    toolchain_store: Entity<LocalToolchainStore>,
  251    http_client: Arc<dyn HttpClient>,
  252    environment: Entity<ProjectEnvironment>,
  253    fs: Arc<dyn Fs>,
  254    languages: Arc<LanguageRegistry>,
  255    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  256    yarn: Entity<YarnPathStore>,
  257    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  258    buffers_being_formatted: HashSet<BufferId>,
  259    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  260    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  261    watched_manifest_filenames: HashSet<ManifestName>,
  262    language_server_paths_watched_for_rename:
  263        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  264    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  265    supplementary_language_servers:
  266        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  267    prettier_store: Entity<PrettierStore>,
  268    next_diagnostic_group_id: usize,
  269    diagnostics: HashMap<
  270        WorktreeId,
  271        HashMap<
  272            Arc<RelPath>,
  273            Vec<(
  274                LanguageServerId,
  275                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  276            )>,
  277        >,
  278    >,
  279    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  280    _subscription: gpui::Subscription,
  281    lsp_tree: LanguageServerTree,
  282    registered_buffers: HashMap<BufferId, usize>,
  283    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  284    buffer_pull_diagnostics_result_ids: HashMap<LanguageServerId, HashMap<PathBuf, Option<String>>>,
  285}
  286
  287impl LocalLspStore {
  288    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  289    pub fn running_language_server_for_id(
  290        &self,
  291        id: LanguageServerId,
  292    ) -> Option<&Arc<LanguageServer>> {
  293        let language_server_state = self.language_servers.get(&id)?;
  294
  295        match language_server_state {
  296            LanguageServerState::Running { server, .. } => Some(server),
  297            LanguageServerState::Starting { .. } => None,
  298        }
  299    }
  300
  301    fn get_or_insert_language_server(
  302        &mut self,
  303        worktree_handle: &Entity<Worktree>,
  304        delegate: Arc<LocalLspAdapterDelegate>,
  305        disposition: &Arc<LaunchDisposition>,
  306        language_name: &LanguageName,
  307        cx: &mut App,
  308    ) -> LanguageServerId {
  309        let key = LanguageServerSeed {
  310            worktree_id: worktree_handle.read(cx).id(),
  311            name: disposition.server_name.clone(),
  312            settings: disposition.settings.clone(),
  313            toolchain: disposition.toolchain.clone(),
  314        };
  315        if let Some(state) = self.language_server_ids.get_mut(&key) {
  316            state.project_roots.insert(disposition.path.path.clone());
  317            state.id
  318        } else {
  319            let adapter = self
  320                .languages
  321                .lsp_adapters(language_name)
  322                .into_iter()
  323                .find(|adapter| adapter.name() == disposition.server_name)
  324                .expect("To find LSP adapter");
  325            let new_language_server_id = self.start_language_server(
  326                worktree_handle,
  327                delegate,
  328                adapter,
  329                disposition.settings.clone(),
  330                key.clone(),
  331                cx,
  332            );
  333            if let Some(state) = self.language_server_ids.get_mut(&key) {
  334                state.project_roots.insert(disposition.path.path.clone());
  335            } else {
  336                debug_assert!(
  337                    false,
  338                    "Expected `start_language_server` to ensure that `key` exists in a map"
  339                );
  340            }
  341            new_language_server_id
  342        }
  343    }
  344
  345    fn start_language_server(
  346        &mut self,
  347        worktree_handle: &Entity<Worktree>,
  348        delegate: Arc<LocalLspAdapterDelegate>,
  349        adapter: Arc<CachedLspAdapter>,
  350        settings: Arc<LspSettings>,
  351        key: LanguageServerSeed,
  352        cx: &mut App,
  353    ) -> LanguageServerId {
  354        let worktree = worktree_handle.read(cx);
  355
  356        let root_path = worktree.abs_path();
  357        let toolchain = key.toolchain.clone();
  358        let override_options = settings.initialization_options.clone();
  359
  360        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  361
  362        let server_id = self.languages.next_language_server_id();
  363        log::trace!(
  364            "attempting to start language server {:?}, path: {root_path:?}, id: {server_id}",
  365            adapter.name.0
  366        );
  367
  368        let binary = self.get_language_server_binary(
  369            adapter.clone(),
  370            settings,
  371            toolchain.clone(),
  372            delegate.clone(),
  373            true,
  374            cx,
  375        );
  376        let pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>> = Default::default();
  377
  378        let pending_server = cx.spawn({
  379            let adapter = adapter.clone();
  380            let server_name = adapter.name.clone();
  381            let stderr_capture = stderr_capture.clone();
  382            #[cfg(any(test, feature = "test-support"))]
  383            let lsp_store = self.weak.clone();
  384            let pending_workspace_folders = pending_workspace_folders.clone();
  385            async move |cx| {
  386                let binary = binary.await?;
  387                #[cfg(any(test, feature = "test-support"))]
  388                if let Some(server) = lsp_store
  389                    .update(&mut cx.clone(), |this, cx| {
  390                        this.languages.create_fake_language_server(
  391                            server_id,
  392                            &server_name,
  393                            binary.clone(),
  394                            &mut cx.to_async(),
  395                        )
  396                    })
  397                    .ok()
  398                    .flatten()
  399                {
  400                    return Ok(server);
  401                }
  402
  403                let code_action_kinds = adapter.code_action_kinds();
  404                lsp::LanguageServer::new(
  405                    stderr_capture,
  406                    server_id,
  407                    server_name,
  408                    binary,
  409                    &root_path,
  410                    code_action_kinds,
  411                    Some(pending_workspace_folders),
  412                    cx,
  413                )
  414            }
  415        });
  416
  417        let startup = {
  418            let server_name = adapter.name.0.clone();
  419            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  420            let key = key.clone();
  421            let adapter = adapter.clone();
  422            let lsp_store = self.weak.clone();
  423            let pending_workspace_folders = pending_workspace_folders.clone();
  424
  425            let pull_diagnostics = ProjectSettings::get_global(cx)
  426                .diagnostics
  427                .lsp_pull_diagnostics
  428                .enabled;
  429            cx.spawn(async move |cx| {
  430                let result = async {
  431                    let language_server = pending_server.await?;
  432
  433                    let workspace_config = Self::workspace_configuration_for_adapter(
  434                        adapter.adapter.clone(),
  435                        &delegate,
  436                        toolchain,
  437                        cx,
  438                    )
  439                    .await?;
  440
  441                    let mut initialization_options = Self::initialization_options_for_adapter(
  442                        adapter.adapter.clone(),
  443                        &delegate,
  444                    )
  445                    .await?;
  446
  447                    match (&mut initialization_options, override_options) {
  448                        (Some(initialization_options), Some(override_options)) => {
  449                            merge_json_value_into(override_options, initialization_options);
  450                        }
  451                        (None, override_options) => initialization_options = override_options,
  452                        _ => {}
  453                    }
  454
  455                    let initialization_params = cx.update(|cx| {
  456                        let mut params =
  457                            language_server.default_initialize_params(pull_diagnostics, cx);
  458                        params.initialization_options = initialization_options;
  459                        adapter.adapter.prepare_initialize_params(params, cx)
  460                    })??;
  461
  462                    Self::setup_lsp_messages(
  463                        lsp_store.clone(),
  464                        &language_server,
  465                        delegate.clone(),
  466                        adapter.clone(),
  467                    );
  468
  469                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  470                        settings: workspace_config,
  471                    };
  472                    let language_server = cx
  473                        .update(|cx| {
  474                            language_server.initialize(
  475                                initialization_params,
  476                                Arc::new(did_change_configuration_params.clone()),
  477                                cx,
  478                            )
  479                        })?
  480                        .await
  481                        .inspect_err(|_| {
  482                            if let Some(lsp_store) = lsp_store.upgrade() {
  483                                lsp_store
  484                                    .update(cx, |lsp_store, cx| {
  485                                        lsp_store.cleanup_lsp_data(server_id);
  486                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  487                                    })
  488                                    .ok();
  489                            }
  490                        })?;
  491
  492                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  493                        did_change_configuration_params,
  494                    )?;
  495
  496                    anyhow::Ok(language_server)
  497                }
  498                .await;
  499
  500                match result {
  501                    Ok(server) => {
  502                        lsp_store
  503                            .update(cx, |lsp_store, cx| {
  504                                lsp_store.insert_newly_running_language_server(
  505                                    adapter,
  506                                    server.clone(),
  507                                    server_id,
  508                                    key,
  509                                    pending_workspace_folders,
  510                                    cx,
  511                                );
  512                            })
  513                            .ok();
  514                        stderr_capture.lock().take();
  515                        Some(server)
  516                    }
  517
  518                    Err(err) => {
  519                        let log = stderr_capture.lock().take().unwrap_or_default();
  520                        delegate.update_status(
  521                            adapter.name(),
  522                            BinaryStatus::Failed {
  523                                error: if log.is_empty() {
  524                                    format!("{err:#}")
  525                                } else {
  526                                    format!("{err:#}\n-- stderr --\n{log}")
  527                                },
  528                            },
  529                        );
  530                        log::error!("Failed to start language server {server_name:?}: {err:?}");
  531                        if !log.is_empty() {
  532                            log::error!("server stderr: {log}");
  533                        }
  534                        None
  535                    }
  536                }
  537            })
  538        };
  539        let state = LanguageServerState::Starting {
  540            startup,
  541            pending_workspace_folders,
  542        };
  543
  544        self.languages
  545            .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  546
  547        self.language_servers.insert(server_id, state);
  548        self.language_server_ids
  549            .entry(key)
  550            .or_insert(UnifiedLanguageServer {
  551                id: server_id,
  552                project_roots: Default::default(),
  553            });
  554        server_id
  555    }
  556
  557    fn get_language_server_binary(
  558        &self,
  559        adapter: Arc<CachedLspAdapter>,
  560        settings: Arc<LspSettings>,
  561        toolchain: Option<Toolchain>,
  562        delegate: Arc<dyn LspAdapterDelegate>,
  563        allow_binary_download: bool,
  564        cx: &mut App,
  565    ) -> Task<Result<LanguageServerBinary>> {
  566        if let Some(settings) = settings.binary.as_ref()
  567            && settings.path.is_some()
  568        {
  569            let settings = settings.clone();
  570
  571            return cx.background_spawn(async move {
  572                let mut env = delegate.shell_env().await;
  573                env.extend(settings.env.unwrap_or_default());
  574
  575                Ok(LanguageServerBinary {
  576                    path: PathBuf::from(&settings.path.unwrap()),
  577                    env: Some(env),
  578                    arguments: settings
  579                        .arguments
  580                        .unwrap_or_default()
  581                        .iter()
  582                        .map(Into::into)
  583                        .collect(),
  584                })
  585            });
  586        }
  587        let lsp_binary_options = LanguageServerBinaryOptions {
  588            allow_path_lookup: !settings
  589                .binary
  590                .as_ref()
  591                .and_then(|b| b.ignore_system_version)
  592                .unwrap_or_default(),
  593            allow_binary_download,
  594            pre_release: settings
  595                .fetch
  596                .as_ref()
  597                .and_then(|f| f.pre_release)
  598                .unwrap_or(false),
  599        };
  600
  601        cx.spawn(async move |cx| {
  602            let binary_result = adapter
  603                .clone()
  604                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  605                .await;
  606
  607            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  608
  609            let mut binary = binary_result?;
  610            let mut shell_env = delegate.shell_env().await;
  611
  612            shell_env.extend(binary.env.unwrap_or_default());
  613
  614            if let Some(settings) = settings.binary.as_ref() {
  615                if let Some(arguments) = &settings.arguments {
  616                    binary.arguments = arguments.iter().map(Into::into).collect();
  617                }
  618                if let Some(env) = &settings.env {
  619                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  620                }
  621            }
  622
  623            binary.env = Some(shell_env);
  624            Ok(binary)
  625        })
  626    }
  627
  628    fn setup_lsp_messages(
  629        lsp_store: WeakEntity<LspStore>,
  630        language_server: &LanguageServer,
  631        delegate: Arc<dyn LspAdapterDelegate>,
  632        adapter: Arc<CachedLspAdapter>,
  633    ) {
  634        let name = language_server.name();
  635        let server_id = language_server.server_id();
  636        language_server
  637            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  638                let adapter = adapter.clone();
  639                let this = lsp_store.clone();
  640                move |mut params, cx| {
  641                    let adapter = adapter.clone();
  642                    if let Some(this) = this.upgrade() {
  643                        this.update(cx, |this, cx| {
  644                            {
  645                                let buffer = params
  646                                    .uri
  647                                    .to_file_path()
  648                                    .map(|file_path| this.get_buffer(&file_path, cx))
  649                                    .ok()
  650                                    .flatten();
  651                                adapter.process_diagnostics(&mut params, server_id, buffer);
  652                            }
  653
  654                            this.merge_lsp_diagnostics(
  655                                DiagnosticSourceKind::Pushed,
  656                                vec![DocumentDiagnosticsUpdate {
  657                                    server_id,
  658                                    diagnostics: params,
  659                                    result_id: None,
  660                                    disk_based_sources: Cow::Borrowed(
  661                                        &adapter.disk_based_diagnostic_sources,
  662                                    ),
  663                                }],
  664                                |_, diagnostic, cx| match diagnostic.source_kind {
  665                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  666                                        adapter.retain_old_diagnostic(diagnostic, cx)
  667                                    }
  668                                    DiagnosticSourceKind::Pulled => true,
  669                                },
  670                                cx,
  671                            )
  672                            .log_err();
  673                        })
  674                        .ok();
  675                    }
  676                }
  677            })
  678            .detach();
  679        language_server
  680            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  681                let adapter = adapter.adapter.clone();
  682                let delegate = delegate.clone();
  683                let this = lsp_store.clone();
  684                move |params, cx| {
  685                    let adapter = adapter.clone();
  686                    let delegate = delegate.clone();
  687                    let this = this.clone();
  688                    let mut cx = cx.clone();
  689                    async move {
  690                        let toolchain_for_id = this
  691                            .update(&mut cx, |this, _| {
  692                                this.as_local()?.language_server_ids.iter().find_map(
  693                                    |(seed, value)| {
  694                                        (value.id == server_id).then(|| seed.toolchain.clone())
  695                                    },
  696                                )
  697                            })?
  698                            .context("Expected the LSP store to be in a local mode")?;
  699                        let workspace_config = Self::workspace_configuration_for_adapter(
  700                            adapter.clone(),
  701                            &delegate,
  702                            toolchain_for_id,
  703                            &mut cx,
  704                        )
  705                        .await?;
  706
  707                        Ok(params
  708                            .items
  709                            .into_iter()
  710                            .map(|item| {
  711                                if let Some(section) = &item.section {
  712                                    workspace_config
  713                                        .get(section)
  714                                        .cloned()
  715                                        .unwrap_or(serde_json::Value::Null)
  716                                } else {
  717                                    workspace_config.clone()
  718                                }
  719                            })
  720                            .collect())
  721                    }
  722                }
  723            })
  724            .detach();
  725
  726        language_server
  727            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  728                let this = lsp_store.clone();
  729                move |_, cx| {
  730                    let this = this.clone();
  731                    let cx = cx.clone();
  732                    async move {
  733                        let Some(server) =
  734                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  735                        else {
  736                            return Ok(None);
  737                        };
  738                        let root = server.workspace_folders();
  739                        Ok(Some(
  740                            root.into_iter()
  741                                .map(|uri| WorkspaceFolder {
  742                                    uri,
  743                                    name: Default::default(),
  744                                })
  745                                .collect(),
  746                        ))
  747                    }
  748                }
  749            })
  750            .detach();
  751        // Even though we don't have handling for these requests, respond to them to
  752        // avoid stalling any language server like `gopls` which waits for a response
  753        // to these requests when initializing.
  754        language_server
  755            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  756                let this = lsp_store.clone();
  757                move |params, cx| {
  758                    let this = this.clone();
  759                    let mut cx = cx.clone();
  760                    async move {
  761                        this.update(&mut cx, |this, _| {
  762                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  763                            {
  764                                status
  765                                    .progress_tokens
  766                                    .insert(ProgressToken::from_lsp(params.token));
  767                            }
  768                        })?;
  769
  770                        Ok(())
  771                    }
  772                }
  773            })
  774            .detach();
  775
  776        language_server
  777            .on_request::<lsp::request::RegisterCapability, _, _>({
  778                let lsp_store = lsp_store.clone();
  779                move |params, cx| {
  780                    let lsp_store = lsp_store.clone();
  781                    let mut cx = cx.clone();
  782                    async move {
  783                        lsp_store
  784                            .update(&mut cx, |lsp_store, cx| {
  785                                if lsp_store.as_local().is_some() {
  786                                    match lsp_store
  787                                        .register_server_capabilities(server_id, params, cx)
  788                                    {
  789                                        Ok(()) => {}
  790                                        Err(e) => {
  791                                            log::error!(
  792                                                "Failed to register server capabilities: {e:#}"
  793                                            );
  794                                        }
  795                                    };
  796                                }
  797                            })
  798                            .ok();
  799                        Ok(())
  800                    }
  801                }
  802            })
  803            .detach();
  804
  805        language_server
  806            .on_request::<lsp::request::UnregisterCapability, _, _>({
  807                let lsp_store = lsp_store.clone();
  808                move |params, cx| {
  809                    let lsp_store = lsp_store.clone();
  810                    let mut cx = cx.clone();
  811                    async move {
  812                        lsp_store
  813                            .update(&mut cx, |lsp_store, cx| {
  814                                if lsp_store.as_local().is_some() {
  815                                    match lsp_store
  816                                        .unregister_server_capabilities(server_id, params, cx)
  817                                    {
  818                                        Ok(()) => {}
  819                                        Err(e) => {
  820                                            log::error!(
  821                                                "Failed to unregister server capabilities: {e:#}"
  822                                            );
  823                                        }
  824                                    }
  825                                }
  826                            })
  827                            .ok();
  828                        Ok(())
  829                    }
  830                }
  831            })
  832            .detach();
  833
  834        language_server
  835            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  836                let this = lsp_store.clone();
  837                move |params, cx| {
  838                    let mut cx = cx.clone();
  839                    let this = this.clone();
  840                    async move {
  841                        LocalLspStore::on_lsp_workspace_edit(
  842                            this.clone(),
  843                            params,
  844                            server_id,
  845                            &mut cx,
  846                        )
  847                        .await
  848                    }
  849                }
  850            })
  851            .detach();
  852
  853        language_server
  854            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  855                let lsp_store = lsp_store.clone();
  856                move |(), cx| {
  857                    let this = lsp_store.clone();
  858                    let mut cx = cx.clone();
  859                    async move {
  860                        this.update(&mut cx, |lsp_store, cx| {
  861                            cx.emit(LspStoreEvent::RefreshInlayHints(server_id));
  862                            lsp_store
  863                                .downstream_client
  864                                .as_ref()
  865                                .map(|(client, project_id)| {
  866                                    client.send(proto::RefreshInlayHints {
  867                                        project_id: *project_id,
  868                                        server_id: server_id.to_proto(),
  869                                    })
  870                                })
  871                        })?
  872                        .transpose()?;
  873                        Ok(())
  874                    }
  875                }
  876            })
  877            .detach();
  878
  879        language_server
  880            .on_request::<lsp::request::CodeLensRefresh, _, _>({
  881                let this = lsp_store.clone();
  882                move |(), cx| {
  883                    let this = this.clone();
  884                    let mut cx = cx.clone();
  885                    async move {
  886                        this.update(&mut cx, |this, cx| {
  887                            cx.emit(LspStoreEvent::RefreshCodeLens);
  888                            this.downstream_client.as_ref().map(|(client, project_id)| {
  889                                client.send(proto::RefreshCodeLens {
  890                                    project_id: *project_id,
  891                                })
  892                            })
  893                        })?
  894                        .transpose()?;
  895                        Ok(())
  896                    }
  897                }
  898            })
  899            .detach();
  900
  901        language_server
  902            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
  903                let this = lsp_store.clone();
  904                move |(), cx| {
  905                    let this = this.clone();
  906                    let mut cx = cx.clone();
  907                    async move {
  908                        this.update(&mut cx, |lsp_store, _| {
  909                            lsp_store.pull_workspace_diagnostics(server_id);
  910                            lsp_store
  911                                .downstream_client
  912                                .as_ref()
  913                                .map(|(client, project_id)| {
  914                                    client.send(proto::PullWorkspaceDiagnostics {
  915                                        project_id: *project_id,
  916                                        server_id: server_id.to_proto(),
  917                                    })
  918                                })
  919                        })?
  920                        .transpose()?;
  921                        Ok(())
  922                    }
  923                }
  924            })
  925            .detach();
  926
  927        language_server
  928            .on_request::<lsp::request::ShowMessageRequest, _, _>({
  929                let this = lsp_store.clone();
  930                let name = name.to_string();
  931                move |params, cx| {
  932                    let this = this.clone();
  933                    let name = name.to_string();
  934                    let mut cx = cx.clone();
  935                    async move {
  936                        let actions = params.actions.unwrap_or_default();
  937                        let (tx, rx) = smol::channel::bounded(1);
  938                        let request = LanguageServerPromptRequest {
  939                            level: match params.typ {
  940                                lsp::MessageType::ERROR => PromptLevel::Critical,
  941                                lsp::MessageType::WARNING => PromptLevel::Warning,
  942                                _ => PromptLevel::Info,
  943                            },
  944                            message: params.message,
  945                            actions,
  946                            response_channel: tx,
  947                            lsp_name: name.clone(),
  948                        };
  949
  950                        let did_update = this
  951                            .update(&mut cx, |_, cx| {
  952                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
  953                            })
  954                            .is_ok();
  955                        if did_update {
  956                            let response = rx.recv().await.ok();
  957                            Ok(response)
  958                        } else {
  959                            Ok(None)
  960                        }
  961                    }
  962                }
  963            })
  964            .detach();
  965        language_server
  966            .on_notification::<lsp::notification::ShowMessage, _>({
  967                let this = lsp_store.clone();
  968                let name = name.to_string();
  969                move |params, cx| {
  970                    let this = this.clone();
  971                    let name = name.to_string();
  972                    let mut cx = cx.clone();
  973
  974                    let (tx, _) = smol::channel::bounded(1);
  975                    let request = LanguageServerPromptRequest {
  976                        level: match params.typ {
  977                            lsp::MessageType::ERROR => PromptLevel::Critical,
  978                            lsp::MessageType::WARNING => PromptLevel::Warning,
  979                            _ => PromptLevel::Info,
  980                        },
  981                        message: params.message,
  982                        actions: vec![],
  983                        response_channel: tx,
  984                        lsp_name: name,
  985                    };
  986
  987                    let _ = this.update(&mut cx, |_, cx| {
  988                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
  989                    });
  990                }
  991            })
  992            .detach();
  993
  994        let disk_based_diagnostics_progress_token =
  995            adapter.disk_based_diagnostics_progress_token.clone();
  996
  997        language_server
  998            .on_notification::<lsp::notification::Progress, _>({
  999                let this = lsp_store.clone();
 1000                move |params, cx| {
 1001                    if let Some(this) = this.upgrade() {
 1002                        this.update(cx, |this, cx| {
 1003                            this.on_lsp_progress(
 1004                                params,
 1005                                server_id,
 1006                                disk_based_diagnostics_progress_token.clone(),
 1007                                cx,
 1008                            );
 1009                        })
 1010                        .ok();
 1011                    }
 1012                }
 1013            })
 1014            .detach();
 1015
 1016        language_server
 1017            .on_notification::<lsp::notification::LogMessage, _>({
 1018                let this = lsp_store.clone();
 1019                move |params, cx| {
 1020                    if let Some(this) = this.upgrade() {
 1021                        this.update(cx, |_, cx| {
 1022                            cx.emit(LspStoreEvent::LanguageServerLog(
 1023                                server_id,
 1024                                LanguageServerLogType::Log(params.typ),
 1025                                params.message,
 1026                            ));
 1027                        })
 1028                        .ok();
 1029                    }
 1030                }
 1031            })
 1032            .detach();
 1033
 1034        language_server
 1035            .on_notification::<lsp::notification::LogTrace, _>({
 1036                let this = lsp_store.clone();
 1037                move |params, cx| {
 1038                    let mut cx = cx.clone();
 1039                    if let Some(this) = this.upgrade() {
 1040                        this.update(&mut cx, |_, cx| {
 1041                            cx.emit(LspStoreEvent::LanguageServerLog(
 1042                                server_id,
 1043                                LanguageServerLogType::Trace {
 1044                                    verbose_info: params.verbose,
 1045                                },
 1046                                params.message,
 1047                            ));
 1048                        })
 1049                        .ok();
 1050                    }
 1051                }
 1052            })
 1053            .detach();
 1054
 1055        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1056        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1057        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1058        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1059    }
 1060
 1061    fn shutdown_language_servers_on_quit(
 1062        &mut self,
 1063        _: &mut Context<LspStore>,
 1064    ) -> impl Future<Output = ()> + use<> {
 1065        let shutdown_futures = self
 1066            .language_servers
 1067            .drain()
 1068            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1069            .collect::<Vec<_>>();
 1070
 1071        async move {
 1072            join_all(shutdown_futures).await;
 1073        }
 1074    }
 1075
 1076    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1077        match server_state {
 1078            LanguageServerState::Running { server, .. } => {
 1079                if let Some(shutdown) = server.shutdown() {
 1080                    shutdown.await;
 1081                }
 1082            }
 1083            LanguageServerState::Starting { startup, .. } => {
 1084                if let Some(server) = startup.await
 1085                    && let Some(shutdown) = server.shutdown()
 1086                {
 1087                    shutdown.await;
 1088                }
 1089            }
 1090        }
 1091        Ok(())
 1092    }
 1093
 1094    fn language_servers_for_worktree(
 1095        &self,
 1096        worktree_id: WorktreeId,
 1097    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1098        self.language_server_ids
 1099            .iter()
 1100            .filter_map(move |(seed, state)| {
 1101                if seed.worktree_id != worktree_id {
 1102                    return None;
 1103                }
 1104
 1105                if let Some(LanguageServerState::Running { server, .. }) =
 1106                    self.language_servers.get(&state.id)
 1107                {
 1108                    Some(server)
 1109                } else {
 1110                    None
 1111                }
 1112            })
 1113    }
 1114
 1115    fn language_server_ids_for_project_path(
 1116        &self,
 1117        project_path: ProjectPath,
 1118        language: &Language,
 1119        cx: &mut App,
 1120    ) -> Vec<LanguageServerId> {
 1121        let Some(worktree) = self
 1122            .worktree_store
 1123            .read(cx)
 1124            .worktree_for_id(project_path.worktree_id, cx)
 1125        else {
 1126            return Vec::new();
 1127        };
 1128        let delegate: Arc<dyn ManifestDelegate> =
 1129            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1130
 1131        self.lsp_tree
 1132            .get(
 1133                project_path,
 1134                language.name(),
 1135                language.manifest(),
 1136                &delegate,
 1137                cx,
 1138            )
 1139            .collect::<Vec<_>>()
 1140    }
 1141
 1142    fn language_server_ids_for_buffer(
 1143        &self,
 1144        buffer: &Buffer,
 1145        cx: &mut App,
 1146    ) -> Vec<LanguageServerId> {
 1147        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1148            let worktree_id = file.worktree_id(cx);
 1149
 1150            let path: Arc<RelPath> = file
 1151                .path()
 1152                .parent()
 1153                .map(Arc::from)
 1154                .unwrap_or_else(|| file.path().clone());
 1155            let worktree_path = ProjectPath { worktree_id, path };
 1156            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1157        } else {
 1158            Vec::new()
 1159        }
 1160    }
 1161
 1162    fn language_servers_for_buffer<'a>(
 1163        &'a self,
 1164        buffer: &'a Buffer,
 1165        cx: &'a mut App,
 1166    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1167        self.language_server_ids_for_buffer(buffer, cx)
 1168            .into_iter()
 1169            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1170                LanguageServerState::Running {
 1171                    adapter, server, ..
 1172                } => Some((adapter, server)),
 1173                _ => None,
 1174            })
 1175    }
 1176
 1177    async fn execute_code_action_kind_locally(
 1178        lsp_store: WeakEntity<LspStore>,
 1179        mut buffers: Vec<Entity<Buffer>>,
 1180        kind: CodeActionKind,
 1181        push_to_history: bool,
 1182        cx: &mut AsyncApp,
 1183    ) -> anyhow::Result<ProjectTransaction> {
 1184        // Do not allow multiple concurrent code actions requests for the
 1185        // same buffer.
 1186        lsp_store.update(cx, |this, cx| {
 1187            let this = this.as_local_mut().unwrap();
 1188            buffers.retain(|buffer| {
 1189                this.buffers_being_formatted
 1190                    .insert(buffer.read(cx).remote_id())
 1191            });
 1192        })?;
 1193        let _cleanup = defer({
 1194            let this = lsp_store.clone();
 1195            let mut cx = cx.clone();
 1196            let buffers = &buffers;
 1197            move || {
 1198                this.update(&mut cx, |this, cx| {
 1199                    let this = this.as_local_mut().unwrap();
 1200                    for buffer in buffers {
 1201                        this.buffers_being_formatted
 1202                            .remove(&buffer.read(cx).remote_id());
 1203                    }
 1204                })
 1205                .ok();
 1206            }
 1207        });
 1208        let mut project_transaction = ProjectTransaction::default();
 1209
 1210        for buffer in &buffers {
 1211            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1212                buffer.update(cx, |buffer, cx| {
 1213                    lsp_store
 1214                        .as_local()
 1215                        .unwrap()
 1216                        .language_servers_for_buffer(buffer, cx)
 1217                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1218                        .collect::<Vec<_>>()
 1219                })
 1220            })?;
 1221            for (_, language_server) in adapters_and_servers.iter() {
 1222                let actions = Self::get_server_code_actions_from_action_kinds(
 1223                    &lsp_store,
 1224                    language_server.server_id(),
 1225                    vec![kind.clone()],
 1226                    buffer,
 1227                    cx,
 1228                )
 1229                .await?;
 1230                Self::execute_code_actions_on_server(
 1231                    &lsp_store,
 1232                    language_server,
 1233                    actions,
 1234                    push_to_history,
 1235                    &mut project_transaction,
 1236                    cx,
 1237                )
 1238                .await?;
 1239            }
 1240        }
 1241        Ok(project_transaction)
 1242    }
 1243
 1244    async fn format_locally(
 1245        lsp_store: WeakEntity<LspStore>,
 1246        mut buffers: Vec<FormattableBuffer>,
 1247        push_to_history: bool,
 1248        trigger: FormatTrigger,
 1249        logger: zlog::Logger,
 1250        cx: &mut AsyncApp,
 1251    ) -> anyhow::Result<ProjectTransaction> {
 1252        // Do not allow multiple concurrent formatting requests for the
 1253        // same buffer.
 1254        lsp_store.update(cx, |this, cx| {
 1255            let this = this.as_local_mut().unwrap();
 1256            buffers.retain(|buffer| {
 1257                this.buffers_being_formatted
 1258                    .insert(buffer.handle.read(cx).remote_id())
 1259            });
 1260        })?;
 1261
 1262        let _cleanup = defer({
 1263            let this = lsp_store.clone();
 1264            let mut cx = cx.clone();
 1265            let buffers = &buffers;
 1266            move || {
 1267                this.update(&mut cx, |this, cx| {
 1268                    let this = this.as_local_mut().unwrap();
 1269                    for buffer in buffers {
 1270                        this.buffers_being_formatted
 1271                            .remove(&buffer.handle.read(cx).remote_id());
 1272                    }
 1273                })
 1274                .ok();
 1275            }
 1276        });
 1277
 1278        let mut project_transaction = ProjectTransaction::default();
 1279
 1280        for buffer in &buffers {
 1281            zlog::debug!(
 1282                logger =>
 1283                "formatting buffer '{:?}'",
 1284                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1285            );
 1286            // Create an empty transaction to hold all of the formatting edits.
 1287            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1288                // ensure no transactions created while formatting are
 1289                // grouped with the previous transaction in the history
 1290                // based on the transaction group interval
 1291                buffer.finalize_last_transaction();
 1292                buffer
 1293                    .start_transaction()
 1294                    .context("transaction already open")?;
 1295                buffer.end_transaction(cx);
 1296                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1297                buffer.finalize_last_transaction();
 1298                anyhow::Ok(transaction_id)
 1299            })??;
 1300
 1301            let result = Self::format_buffer_locally(
 1302                lsp_store.clone(),
 1303                buffer,
 1304                formatting_transaction_id,
 1305                trigger,
 1306                logger,
 1307                cx,
 1308            )
 1309            .await;
 1310
 1311            buffer.handle.update(cx, |buffer, cx| {
 1312                let Some(formatting_transaction) =
 1313                    buffer.get_transaction(formatting_transaction_id).cloned()
 1314                else {
 1315                    zlog::warn!(logger => "no formatting transaction");
 1316                    return;
 1317                };
 1318                if formatting_transaction.edit_ids.is_empty() {
 1319                    zlog::debug!(logger => "no changes made while formatting");
 1320                    buffer.forget_transaction(formatting_transaction_id);
 1321                    return;
 1322                }
 1323                if !push_to_history {
 1324                    zlog::trace!(logger => "forgetting format transaction");
 1325                    buffer.forget_transaction(formatting_transaction.id);
 1326                }
 1327                project_transaction
 1328                    .0
 1329                    .insert(cx.entity(), formatting_transaction);
 1330            })?;
 1331
 1332            result?;
 1333        }
 1334
 1335        Ok(project_transaction)
 1336    }
 1337
 1338    async fn format_buffer_locally(
 1339        lsp_store: WeakEntity<LspStore>,
 1340        buffer: &FormattableBuffer,
 1341        formatting_transaction_id: clock::Lamport,
 1342        trigger: FormatTrigger,
 1343        logger: zlog::Logger,
 1344        cx: &mut AsyncApp,
 1345    ) -> Result<()> {
 1346        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1347            buffer.handle.update(cx, |buffer, cx| {
 1348                let adapters_and_servers = lsp_store
 1349                    .as_local()
 1350                    .unwrap()
 1351                    .language_servers_for_buffer(buffer, cx)
 1352                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1353                    .collect::<Vec<_>>();
 1354                let settings =
 1355                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1356                        .into_owned();
 1357                (adapters_and_servers, settings)
 1358            })
 1359        })?;
 1360
 1361        /// Apply edits to the buffer that will become part of the formatting transaction.
 1362        /// Fails if the buffer has been edited since the start of that transaction.
 1363        fn extend_formatting_transaction(
 1364            buffer: &FormattableBuffer,
 1365            formatting_transaction_id: text::TransactionId,
 1366            cx: &mut AsyncApp,
 1367            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1368        ) -> anyhow::Result<()> {
 1369            buffer.handle.update(cx, |buffer, cx| {
 1370                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1371                if last_transaction_id != Some(formatting_transaction_id) {
 1372                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1373                }
 1374                buffer.start_transaction();
 1375                operation(buffer, cx);
 1376                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1377                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1378                }
 1379                Ok(())
 1380            })?
 1381        }
 1382
 1383        // handle whitespace formatting
 1384        if settings.remove_trailing_whitespace_on_save {
 1385            zlog::trace!(logger => "removing trailing whitespace");
 1386            let diff = buffer
 1387                .handle
 1388                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))?
 1389                .await;
 1390            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1391                buffer.apply_diff(diff, cx);
 1392            })?;
 1393        }
 1394
 1395        if settings.ensure_final_newline_on_save {
 1396            zlog::trace!(logger => "ensuring final newline");
 1397            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1398                buffer.ensure_final_newline(cx);
 1399            })?;
 1400        }
 1401
 1402        // Formatter for `code_actions_on_format` that runs before
 1403        // the rest of the formatters
 1404        let mut code_actions_on_format_formatters = None;
 1405        let should_run_code_actions_on_format = !matches!(
 1406            (trigger, &settings.format_on_save),
 1407            (FormatTrigger::Save, &FormatOnSave::Off)
 1408        );
 1409        if should_run_code_actions_on_format {
 1410            let have_code_actions_to_run_on_format = settings
 1411                .code_actions_on_format
 1412                .values()
 1413                .any(|enabled| *enabled);
 1414            if have_code_actions_to_run_on_format {
 1415                zlog::trace!(logger => "going to run code actions on format");
 1416                code_actions_on_format_formatters = Some(
 1417                    settings
 1418                        .code_actions_on_format
 1419                        .iter()
 1420                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1421                        .cloned()
 1422                        .map(Formatter::CodeAction)
 1423                        .collect::<Vec<_>>(),
 1424                );
 1425            }
 1426        }
 1427
 1428        let formatters = match (trigger, &settings.format_on_save) {
 1429            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1430            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1431                settings.formatter.as_ref()
 1432            }
 1433        };
 1434
 1435        let formatters = code_actions_on_format_formatters
 1436            .iter()
 1437            .flatten()
 1438            .chain(formatters);
 1439
 1440        for formatter in formatters {
 1441            let formatter = if formatter == &Formatter::Auto {
 1442                if settings.prettier.allowed {
 1443                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1444                    &Formatter::Prettier
 1445                } else {
 1446                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1447                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1448                }
 1449            } else {
 1450                formatter
 1451            };
 1452            match formatter {
 1453                Formatter::Auto => unreachable!("Auto resolved above"),
 1454                Formatter::Prettier => {
 1455                    let logger = zlog::scoped!(logger => "prettier");
 1456                    zlog::trace!(logger => "formatting");
 1457                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1458
 1459                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1460                        lsp_store.prettier_store().unwrap().downgrade()
 1461                    })?;
 1462                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1463                        .await
 1464                        .transpose()?;
 1465                    let Some(diff) = diff else {
 1466                        zlog::trace!(logger => "No changes");
 1467                        continue;
 1468                    };
 1469
 1470                    extend_formatting_transaction(
 1471                        buffer,
 1472                        formatting_transaction_id,
 1473                        cx,
 1474                        |buffer, cx| {
 1475                            buffer.apply_diff(diff, cx);
 1476                        },
 1477                    )?;
 1478                }
 1479                Formatter::External { command, arguments } => {
 1480                    let logger = zlog::scoped!(logger => "command");
 1481                    zlog::trace!(logger => "formatting");
 1482                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1483
 1484                    let diff = Self::format_via_external_command(
 1485                        buffer,
 1486                        command.as_ref(),
 1487                        arguments.as_deref(),
 1488                        cx,
 1489                    )
 1490                    .await
 1491                    .with_context(|| {
 1492                        format!("Failed to format buffer via external command: {}", command)
 1493                    })?;
 1494                    let Some(diff) = diff else {
 1495                        zlog::trace!(logger => "No changes");
 1496                        continue;
 1497                    };
 1498
 1499                    extend_formatting_transaction(
 1500                        buffer,
 1501                        formatting_transaction_id,
 1502                        cx,
 1503                        |buffer, cx| {
 1504                            buffer.apply_diff(diff, cx);
 1505                        },
 1506                    )?;
 1507                }
 1508                Formatter::LanguageServer(specifier) => {
 1509                    let logger = zlog::scoped!(logger => "language-server");
 1510                    zlog::trace!(logger => "formatting");
 1511                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1512
 1513                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1514                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1515                        continue;
 1516                    };
 1517
 1518                    let language_server = match specifier {
 1519                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1520                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1521                                if adapter.name.0.as_ref() == name {
 1522                                    Some(server.clone())
 1523                                } else {
 1524                                    None
 1525                                }
 1526                            })
 1527                        }
 1528                        settings::LanguageServerFormatterSpecifier::Current => {
 1529                            adapters_and_servers.first().map(|e| e.1.clone())
 1530                        }
 1531                    };
 1532
 1533                    let Some(language_server) = language_server else {
 1534                        log::debug!(
 1535                            "No language server found to format buffer '{:?}'. Skipping",
 1536                            buffer_path_abs.as_path().to_string_lossy()
 1537                        );
 1538                        continue;
 1539                    };
 1540
 1541                    zlog::trace!(
 1542                        logger =>
 1543                        "Formatting buffer '{:?}' using language server '{:?}'",
 1544                        buffer_path_abs.as_path().to_string_lossy(),
 1545                        language_server.name()
 1546                    );
 1547
 1548                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1549                        zlog::trace!(logger => "formatting ranges");
 1550                        Self::format_ranges_via_lsp(
 1551                            &lsp_store,
 1552                            &buffer.handle,
 1553                            ranges,
 1554                            buffer_path_abs,
 1555                            &language_server,
 1556                            &settings,
 1557                            cx,
 1558                        )
 1559                        .await
 1560                        .context("Failed to format ranges via language server")?
 1561                    } else {
 1562                        zlog::trace!(logger => "formatting full");
 1563                        Self::format_via_lsp(
 1564                            &lsp_store,
 1565                            &buffer.handle,
 1566                            buffer_path_abs,
 1567                            &language_server,
 1568                            &settings,
 1569                            cx,
 1570                        )
 1571                        .await
 1572                        .context("failed to format via language server")?
 1573                    };
 1574
 1575                    if edits.is_empty() {
 1576                        zlog::trace!(logger => "No changes");
 1577                        continue;
 1578                    }
 1579                    extend_formatting_transaction(
 1580                        buffer,
 1581                        formatting_transaction_id,
 1582                        cx,
 1583                        |buffer, cx| {
 1584                            buffer.edit(edits, None, cx);
 1585                        },
 1586                    )?;
 1587                }
 1588                Formatter::CodeAction(code_action_name) => {
 1589                    let logger = zlog::scoped!(logger => "code-actions");
 1590                    zlog::trace!(logger => "formatting");
 1591                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1592
 1593                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1594                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1595                        continue;
 1596                    };
 1597
 1598                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1599                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1600
 1601                    let mut actions_and_servers = Vec::new();
 1602
 1603                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1604                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1605                            &lsp_store,
 1606                            language_server.server_id(),
 1607                            vec![code_action_kind.clone()],
 1608                            &buffer.handle,
 1609                            cx,
 1610                        )
 1611                        .await
 1612                        .with_context(|| {
 1613                            format!(
 1614                                "Failed to resolve code action {:?} with language server {}",
 1615                                code_action_kind,
 1616                                language_server.name()
 1617                            )
 1618                        });
 1619                        let Ok(actions) = actions_result else {
 1620                            // note: it may be better to set result to the error and break formatters here
 1621                            // but for now we try to execute the actions that we can resolve and skip the rest
 1622                            zlog::error!(
 1623                                logger =>
 1624                                "Failed to resolve code action {:?} with language server {}",
 1625                                code_action_kind,
 1626                                language_server.name()
 1627                            );
 1628                            continue;
 1629                        };
 1630                        for action in actions {
 1631                            actions_and_servers.push((action, index));
 1632                        }
 1633                    }
 1634
 1635                    if actions_and_servers.is_empty() {
 1636                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1637                        continue;
 1638                    }
 1639
 1640                    'actions: for (mut action, server_index) in actions_and_servers {
 1641                        let server = &adapters_and_servers[server_index].1;
 1642
 1643                        let describe_code_action = |action: &CodeAction| {
 1644                            format!(
 1645                                "code action '{}' with title \"{}\" on server {}",
 1646                                action
 1647                                    .lsp_action
 1648                                    .action_kind()
 1649                                    .unwrap_or("unknown".into())
 1650                                    .as_str(),
 1651                                action.lsp_action.title(),
 1652                                server.name(),
 1653                            )
 1654                        };
 1655
 1656                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1657
 1658                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1659                            zlog::error!(
 1660                                logger =>
 1661                                "Failed to resolve {}. Error: {}",
 1662                                describe_code_action(&action),
 1663                                err
 1664                            );
 1665                            continue;
 1666                        }
 1667
 1668                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1669                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1670                            // but filters out and logs warnings for code actions that require unreasonably
 1671                            // difficult handling on our part, such as:
 1672                            // - applying edits that call commands
 1673                            //   which can result in arbitrary workspace edits being sent from the server that
 1674                            //   have no way of being tied back to the command that initiated them (i.e. we
 1675                            //   can't know which edits are part of the format request, or if the server is done sending
 1676                            //   actions in response to the command)
 1677                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1678                            //   as we then would need to handle such changes correctly in the local history as well
 1679                            //   as the remote history through the ProjectTransaction
 1680                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1681                            // Supporting these actions is not impossible, but not supported as of yet.
 1682                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1683                                zlog::trace!(
 1684                                    logger =>
 1685                                    "No changes for code action. Skipping {}",
 1686                                    describe_code_action(&action),
 1687                                );
 1688                                continue;
 1689                            }
 1690
 1691                            let mut operations = Vec::new();
 1692                            if let Some(document_changes) = edit.document_changes {
 1693                                match document_changes {
 1694                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1695                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1696                                    ),
 1697                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1698                                }
 1699                            } else if let Some(changes) = edit.changes {
 1700                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1701                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1702                                        text_document:
 1703                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1704                                                uri,
 1705                                                version: None,
 1706                                            },
 1707                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1708                                    })
 1709                                }));
 1710                            }
 1711
 1712                            let mut edits = Vec::with_capacity(operations.len());
 1713
 1714                            if operations.is_empty() {
 1715                                zlog::trace!(
 1716                                    logger =>
 1717                                    "No changes for code action. Skipping {}",
 1718                                    describe_code_action(&action),
 1719                                );
 1720                                continue;
 1721                            }
 1722                            for operation in operations {
 1723                                let op = match operation {
 1724                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1725                                    lsp::DocumentChangeOperation::Op(_) => {
 1726                                        zlog::warn!(
 1727                                            logger =>
 1728                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1729                                            describe_code_action(&action),
 1730                                        );
 1731                                        continue 'actions;
 1732                                    }
 1733                                };
 1734                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1735                                    zlog::warn!(
 1736                                        logger =>
 1737                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1738                                        &op.text_document.uri,
 1739                                        describe_code_action(&action),
 1740                                    );
 1741                                    continue 'actions;
 1742                                };
 1743                                if &file_path != buffer_path_abs {
 1744                                    zlog::warn!(
 1745                                        logger =>
 1746                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1747                                        file_path,
 1748                                        buffer_path_abs,
 1749                                        describe_code_action(&action),
 1750                                    );
 1751                                    continue 'actions;
 1752                                }
 1753
 1754                                let mut lsp_edits = Vec::new();
 1755                                for edit in op.edits {
 1756                                    match edit {
 1757                                        Edit::Plain(edit) => {
 1758                                            if !lsp_edits.contains(&edit) {
 1759                                                lsp_edits.push(edit);
 1760                                            }
 1761                                        }
 1762                                        Edit::Annotated(edit) => {
 1763                                            if !lsp_edits.contains(&edit.text_edit) {
 1764                                                lsp_edits.push(edit.text_edit);
 1765                                            }
 1766                                        }
 1767                                        Edit::Snippet(_) => {
 1768                                            zlog::warn!(
 1769                                                logger =>
 1770                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1771                                                describe_code_action(&action),
 1772                                            );
 1773                                            continue 'actions;
 1774                                        }
 1775                                    }
 1776                                }
 1777                                let edits_result = lsp_store
 1778                                    .update(cx, |lsp_store, cx| {
 1779                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1780                                            &buffer.handle,
 1781                                            lsp_edits,
 1782                                            server.server_id(),
 1783                                            op.text_document.version,
 1784                                            cx,
 1785                                        )
 1786                                    })?
 1787                                    .await;
 1788                                let Ok(resolved_edits) = edits_result else {
 1789                                    zlog::warn!(
 1790                                        logger =>
 1791                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1792                                        buffer_path_abs.as_path(),
 1793                                        describe_code_action(&action),
 1794                                    );
 1795                                    continue 'actions;
 1796                                };
 1797                                edits.extend(resolved_edits);
 1798                            }
 1799
 1800                            if edits.is_empty() {
 1801                                zlog::warn!(logger => "No edits resolved from LSP");
 1802                                continue;
 1803                            }
 1804
 1805                            extend_formatting_transaction(
 1806                                buffer,
 1807                                formatting_transaction_id,
 1808                                cx,
 1809                                |buffer, cx| {
 1810                                    zlog::info!(
 1811                                        "Applying edits {edits:?}. Content: {:?}",
 1812                                        buffer.text()
 1813                                    );
 1814                                    buffer.edit(edits, None, cx);
 1815                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 1816                                },
 1817                            )?;
 1818                        }
 1819
 1820                        if let Some(command) = action.lsp_action.command() {
 1821                            zlog::warn!(
 1822                                logger =>
 1823                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1824                                &command.command,
 1825                            );
 1826
 1827                            // bail early if command is invalid
 1828                            let server_capabilities = server.capabilities();
 1829                            let available_commands = server_capabilities
 1830                                .execute_command_provider
 1831                                .as_ref()
 1832                                .map(|options| options.commands.as_slice())
 1833                                .unwrap_or_default();
 1834                            if !available_commands.contains(&command.command) {
 1835                                zlog::warn!(
 1836                                    logger =>
 1837                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1838                                    command.command,
 1839                                    server.name(),
 1840                                );
 1841                                continue;
 1842                            }
 1843
 1844                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 1845                            extend_formatting_transaction(
 1846                                buffer,
 1847                                formatting_transaction_id,
 1848                                cx,
 1849                                |_, _| {},
 1850                            )?;
 1851                            zlog::info!(logger => "Executing command {}", &command.command);
 1852
 1853                            lsp_store.update(cx, |this, _| {
 1854                                this.as_local_mut()
 1855                                    .unwrap()
 1856                                    .last_workspace_edits_by_language_server
 1857                                    .remove(&server.server_id());
 1858                            })?;
 1859
 1860                            let execute_command_result = server
 1861                                .request::<lsp::request::ExecuteCommand>(
 1862                                    lsp::ExecuteCommandParams {
 1863                                        command: command.command.clone(),
 1864                                        arguments: command.arguments.clone().unwrap_or_default(),
 1865                                        ..Default::default()
 1866                                    },
 1867                                )
 1868                                .await
 1869                                .into_response();
 1870
 1871                            if execute_command_result.is_err() {
 1872                                zlog::error!(
 1873                                    logger =>
 1874                                    "Failed to execute command '{}' as part of {}",
 1875                                    &command.command,
 1876                                    describe_code_action(&action),
 1877                                );
 1878                                continue 'actions;
 1879                            }
 1880
 1881                            let mut project_transaction_command =
 1882                                lsp_store.update(cx, |this, _| {
 1883                                    this.as_local_mut()
 1884                                        .unwrap()
 1885                                        .last_workspace_edits_by_language_server
 1886                                        .remove(&server.server_id())
 1887                                        .unwrap_or_default()
 1888                                })?;
 1889
 1890                            if let Some(transaction) =
 1891                                project_transaction_command.0.remove(&buffer.handle)
 1892                            {
 1893                                zlog::trace!(
 1894                                    logger =>
 1895                                    "Successfully captured {} edits that resulted from command {}",
 1896                                    transaction.edit_ids.len(),
 1897                                    &command.command,
 1898                                );
 1899                                let transaction_id_project_transaction = transaction.id;
 1900                                buffer.handle.update(cx, |buffer, _| {
 1901                                    // it may have been removed from history if push_to_history was
 1902                                    // false in deserialize_workspace_edit. If so push it so we
 1903                                    // can merge it with the format transaction
 1904                                    // and pop the combined transaction off the history stack
 1905                                    // later if push_to_history is false
 1906                                    if buffer.get_transaction(transaction.id).is_none() {
 1907                                        buffer.push_transaction(transaction, Instant::now());
 1908                                    }
 1909                                    buffer.merge_transactions(
 1910                                        transaction_id_project_transaction,
 1911                                        formatting_transaction_id,
 1912                                    );
 1913                                })?;
 1914                            }
 1915
 1916                            if !project_transaction_command.0.is_empty() {
 1917                                let mut extra_buffers = String::new();
 1918                                for buffer in project_transaction_command.0.keys() {
 1919                                    buffer
 1920                                        .read_with(cx, |b, cx| {
 1921                                            if let Some(path) = b.project_path(cx) {
 1922                                                if !extra_buffers.is_empty() {
 1923                                                    extra_buffers.push_str(", ");
 1924                                                }
 1925                                                extra_buffers.push_str(path.path.as_unix_str());
 1926                                            }
 1927                                        })
 1928                                        .ok();
 1929                                }
 1930                                zlog::warn!(
 1931                                    logger =>
 1932                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 1933                                    &command.command,
 1934                                    extra_buffers,
 1935                                );
 1936                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 1937                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 1938                                // add it so it's included, and merge it into the format transaction when its created later
 1939                            }
 1940                        }
 1941                    }
 1942                }
 1943            }
 1944        }
 1945
 1946        Ok(())
 1947    }
 1948
 1949    pub async fn format_ranges_via_lsp(
 1950        this: &WeakEntity<LspStore>,
 1951        buffer_handle: &Entity<Buffer>,
 1952        ranges: &[Range<Anchor>],
 1953        abs_path: &Path,
 1954        language_server: &Arc<LanguageServer>,
 1955        settings: &LanguageSettings,
 1956        cx: &mut AsyncApp,
 1957    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 1958        let capabilities = &language_server.capabilities();
 1959        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 1960        if range_formatting_provider == Some(&OneOf::Left(false)) {
 1961            anyhow::bail!(
 1962                "{} language server does not support range formatting",
 1963                language_server.name()
 1964            );
 1965        }
 1966
 1967        let uri = file_path_to_lsp_url(abs_path)?;
 1968        let text_document = lsp::TextDocumentIdentifier::new(uri);
 1969
 1970        let lsp_edits = {
 1971            let mut lsp_ranges = Vec::new();
 1972            this.update(cx, |_this, cx| {
 1973                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 1974                // not have been sent to the language server. This seems like a fairly systemic
 1975                // issue, though, the resolution probably is not specific to formatting.
 1976                //
 1977                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 1978                // LSP.
 1979                let snapshot = buffer_handle.read(cx).snapshot();
 1980                for range in ranges {
 1981                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 1982                }
 1983                anyhow::Ok(())
 1984            })??;
 1985
 1986            let mut edits = None;
 1987            for range in lsp_ranges {
 1988                if let Some(mut edit) = language_server
 1989                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 1990                        text_document: text_document.clone(),
 1991                        range,
 1992                        options: lsp_command::lsp_formatting_options(settings),
 1993                        work_done_progress_params: Default::default(),
 1994                    })
 1995                    .await
 1996                    .into_response()?
 1997                {
 1998                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 1999                }
 2000            }
 2001            edits
 2002        };
 2003
 2004        if let Some(lsp_edits) = lsp_edits {
 2005            this.update(cx, |this, cx| {
 2006                this.as_local_mut().unwrap().edits_from_lsp(
 2007                    buffer_handle,
 2008                    lsp_edits,
 2009                    language_server.server_id(),
 2010                    None,
 2011                    cx,
 2012                )
 2013            })?
 2014            .await
 2015        } else {
 2016            Ok(Vec::with_capacity(0))
 2017        }
 2018    }
 2019
 2020    async fn format_via_lsp(
 2021        this: &WeakEntity<LspStore>,
 2022        buffer: &Entity<Buffer>,
 2023        abs_path: &Path,
 2024        language_server: &Arc<LanguageServer>,
 2025        settings: &LanguageSettings,
 2026        cx: &mut AsyncApp,
 2027    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2028        let logger = zlog::scoped!("lsp_format");
 2029        zlog::info!(logger => "Formatting via LSP");
 2030
 2031        let uri = file_path_to_lsp_url(abs_path)?;
 2032        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2033        let capabilities = &language_server.capabilities();
 2034
 2035        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2036        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2037
 2038        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2039            let _timer = zlog::time!(logger => "format-full");
 2040            language_server
 2041                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 2042                    text_document,
 2043                    options: lsp_command::lsp_formatting_options(settings),
 2044                    work_done_progress_params: Default::default(),
 2045                })
 2046                .await
 2047                .into_response()?
 2048        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2049            let _timer = zlog::time!(logger => "format-range");
 2050            let buffer_start = lsp::Position::new(0, 0);
 2051            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 2052            language_server
 2053                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2054                    text_document: text_document.clone(),
 2055                    range: lsp::Range::new(buffer_start, buffer_end),
 2056                    options: lsp_command::lsp_formatting_options(settings),
 2057                    work_done_progress_params: Default::default(),
 2058                })
 2059                .await
 2060                .into_response()?
 2061        } else {
 2062            None
 2063        };
 2064
 2065        if let Some(lsp_edits) = lsp_edits {
 2066            this.update(cx, |this, cx| {
 2067                this.as_local_mut().unwrap().edits_from_lsp(
 2068                    buffer,
 2069                    lsp_edits,
 2070                    language_server.server_id(),
 2071                    None,
 2072                    cx,
 2073                )
 2074            })?
 2075            .await
 2076        } else {
 2077            Ok(Vec::with_capacity(0))
 2078        }
 2079    }
 2080
 2081    async fn format_via_external_command(
 2082        buffer: &FormattableBuffer,
 2083        command: &str,
 2084        arguments: Option<&[String]>,
 2085        cx: &mut AsyncApp,
 2086    ) -> Result<Option<Diff>> {
 2087        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2088            let file = File::from_dyn(buffer.file())?;
 2089            let worktree = file.worktree.read(cx);
 2090            let mut worktree_path = worktree.abs_path().to_path_buf();
 2091            if worktree.root_entry()?.is_file() {
 2092                worktree_path.pop();
 2093            }
 2094            Some(worktree_path)
 2095        })?;
 2096
 2097        let mut child = util::command::new_smol_command(command);
 2098
 2099        if let Some(buffer_env) = buffer.env.as_ref() {
 2100            child.envs(buffer_env);
 2101        }
 2102
 2103        if let Some(working_dir_path) = working_dir_path {
 2104            child.current_dir(working_dir_path);
 2105        }
 2106
 2107        if let Some(arguments) = arguments {
 2108            child.args(arguments.iter().map(|arg| {
 2109                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2110                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2111                } else {
 2112                    arg.replace("{buffer_path}", "Untitled")
 2113                }
 2114            }));
 2115        }
 2116
 2117        let mut child = child
 2118            .stdin(smol::process::Stdio::piped())
 2119            .stdout(smol::process::Stdio::piped())
 2120            .stderr(smol::process::Stdio::piped())
 2121            .spawn()?;
 2122
 2123        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2124        let text = buffer
 2125            .handle
 2126            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2127        for chunk in text.chunks() {
 2128            stdin.write_all(chunk.as_bytes()).await?;
 2129        }
 2130        stdin.flush().await?;
 2131
 2132        let output = child.output().await?;
 2133        anyhow::ensure!(
 2134            output.status.success(),
 2135            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2136            output.status.code(),
 2137            String::from_utf8_lossy(&output.stdout),
 2138            String::from_utf8_lossy(&output.stderr),
 2139        );
 2140
 2141        let stdout = String::from_utf8(output.stdout)?;
 2142        Ok(Some(
 2143            buffer
 2144                .handle
 2145                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2146                .await,
 2147        ))
 2148    }
 2149
 2150    async fn try_resolve_code_action(
 2151        lang_server: &LanguageServer,
 2152        action: &mut CodeAction,
 2153    ) -> anyhow::Result<()> {
 2154        match &mut action.lsp_action {
 2155            LspAction::Action(lsp_action) => {
 2156                if !action.resolved
 2157                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2158                    && lsp_action.data.is_some()
 2159                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2160                {
 2161                    *lsp_action = Box::new(
 2162                        lang_server
 2163                            .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2164                            .await
 2165                            .into_response()?,
 2166                    );
 2167                }
 2168            }
 2169            LspAction::CodeLens(lens) => {
 2170                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2171                    *lens = lang_server
 2172                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2173                        .await
 2174                        .into_response()?;
 2175                }
 2176            }
 2177            LspAction::Command(_) => {}
 2178        }
 2179
 2180        action.resolved = true;
 2181        anyhow::Ok(())
 2182    }
 2183
 2184    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2185        let buffer = buffer_handle.read(cx);
 2186
 2187        let file = buffer.file().cloned();
 2188
 2189        let Some(file) = File::from_dyn(file.as_ref()) else {
 2190            return;
 2191        };
 2192        if !file.is_local() {
 2193            return;
 2194        }
 2195        let path = ProjectPath::from_file(file, cx);
 2196        let worktree_id = file.worktree_id(cx);
 2197        let language = buffer.language().cloned();
 2198
 2199        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2200            for (server_id, diagnostics) in
 2201                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2202            {
 2203                self.update_buffer_diagnostics(
 2204                    buffer_handle,
 2205                    server_id,
 2206                    None,
 2207                    None,
 2208                    diagnostics,
 2209                    Vec::new(),
 2210                    cx,
 2211                )
 2212                .log_err();
 2213            }
 2214        }
 2215        let Some(language) = language else {
 2216            return;
 2217        };
 2218        let Some(snapshot) = self
 2219            .worktree_store
 2220            .read(cx)
 2221            .worktree_for_id(worktree_id, cx)
 2222            .map(|worktree| worktree.read(cx).snapshot())
 2223        else {
 2224            return;
 2225        };
 2226        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2227
 2228        for server_id in
 2229            self.lsp_tree
 2230                .get(path, language.name(), language.manifest(), &delegate, cx)
 2231        {
 2232            let server = self
 2233                .language_servers
 2234                .get(&server_id)
 2235                .and_then(|server_state| {
 2236                    if let LanguageServerState::Running { server, .. } = server_state {
 2237                        Some(server.clone())
 2238                    } else {
 2239                        None
 2240                    }
 2241                });
 2242            let server = match server {
 2243                Some(server) => server,
 2244                None => continue,
 2245            };
 2246
 2247            buffer_handle.update(cx, |buffer, cx| {
 2248                buffer.set_completion_triggers(
 2249                    server.server_id(),
 2250                    server
 2251                        .capabilities()
 2252                        .completion_provider
 2253                        .as_ref()
 2254                        .and_then(|provider| {
 2255                            provider
 2256                                .trigger_characters
 2257                                .as_ref()
 2258                                .map(|characters| characters.iter().cloned().collect())
 2259                        })
 2260                        .unwrap_or_default(),
 2261                    cx,
 2262                );
 2263            });
 2264        }
 2265    }
 2266
 2267    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2268        buffer.update(cx, |buffer, cx| {
 2269            let Some(language) = buffer.language() else {
 2270                return;
 2271            };
 2272            let path = ProjectPath {
 2273                worktree_id: old_file.worktree_id(cx),
 2274                path: old_file.path.clone(),
 2275            };
 2276            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2277                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2278                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2279            }
 2280        });
 2281    }
 2282
 2283    fn update_buffer_diagnostics(
 2284        &mut self,
 2285        buffer: &Entity<Buffer>,
 2286        server_id: LanguageServerId,
 2287        result_id: Option<String>,
 2288        version: Option<i32>,
 2289        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2290        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2291        cx: &mut Context<LspStore>,
 2292    ) -> Result<()> {
 2293        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2294            Ordering::Equal
 2295                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2296                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2297                .then_with(|| a.severity.cmp(&b.severity))
 2298                .then_with(|| a.message.cmp(&b.message))
 2299        }
 2300
 2301        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2302        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2303        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2304
 2305        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2306            Ordering::Equal
 2307                .then_with(|| a.range.start.cmp(&b.range.start))
 2308                .then_with(|| b.range.end.cmp(&a.range.end))
 2309                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2310        });
 2311
 2312        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2313
 2314        let edits_since_save = std::cell::LazyCell::new(|| {
 2315            let saved_version = buffer.read(cx).saved_version();
 2316            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2317        });
 2318
 2319        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2320
 2321        for (new_diagnostic, entry) in diagnostics {
 2322            let start;
 2323            let end;
 2324            if new_diagnostic && entry.diagnostic.is_disk_based {
 2325                // Some diagnostics are based on files on disk instead of buffers'
 2326                // current contents. Adjust these diagnostics' ranges to reflect
 2327                // any unsaved edits.
 2328                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2329                // and were properly adjusted on reuse.
 2330                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2331                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2332            } else {
 2333                start = entry.range.start;
 2334                end = entry.range.end;
 2335            }
 2336
 2337            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2338                ..snapshot.clip_point_utf16(end, Bias::Right);
 2339
 2340            // Expand empty ranges by one codepoint
 2341            if range.start == range.end {
 2342                // This will be go to the next boundary when being clipped
 2343                range.end.column += 1;
 2344                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2345                if range.start == range.end && range.end.column > 0 {
 2346                    range.start.column -= 1;
 2347                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2348                }
 2349            }
 2350
 2351            sanitized_diagnostics.push(DiagnosticEntry {
 2352                range,
 2353                diagnostic: entry.diagnostic,
 2354            });
 2355        }
 2356        drop(edits_since_save);
 2357
 2358        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2359        buffer.update(cx, |buffer, cx| {
 2360            if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2361                self.buffer_pull_diagnostics_result_ids
 2362                    .entry(server_id)
 2363                    .or_default()
 2364                    .insert(abs_path, result_id);
 2365            }
 2366
 2367            buffer.update_diagnostics(server_id, set, cx)
 2368        });
 2369
 2370        Ok(())
 2371    }
 2372
 2373    fn register_language_server_for_invisible_worktree(
 2374        &mut self,
 2375        worktree: &Entity<Worktree>,
 2376        language_server_id: LanguageServerId,
 2377        cx: &mut App,
 2378    ) {
 2379        let worktree = worktree.read(cx);
 2380        let worktree_id = worktree.id();
 2381        debug_assert!(!worktree.is_visible());
 2382        let Some(mut origin_seed) = self
 2383            .language_server_ids
 2384            .iter()
 2385            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2386        else {
 2387            return;
 2388        };
 2389        origin_seed.worktree_id = worktree_id;
 2390        self.language_server_ids
 2391            .entry(origin_seed)
 2392            .or_insert_with(|| UnifiedLanguageServer {
 2393                id: language_server_id,
 2394                project_roots: Default::default(),
 2395            });
 2396    }
 2397
 2398    fn register_buffer_with_language_servers(
 2399        &mut self,
 2400        buffer_handle: &Entity<Buffer>,
 2401        only_register_servers: HashSet<LanguageServerSelector>,
 2402        cx: &mut Context<LspStore>,
 2403    ) {
 2404        let buffer = buffer_handle.read(cx);
 2405        let buffer_id = buffer.remote_id();
 2406
 2407        let Some(file) = File::from_dyn(buffer.file()) else {
 2408            return;
 2409        };
 2410        if !file.is_local() {
 2411            return;
 2412        }
 2413
 2414        let abs_path = file.abs_path(cx);
 2415        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2416            return;
 2417        };
 2418        let initial_snapshot = buffer.text_snapshot();
 2419        let worktree_id = file.worktree_id(cx);
 2420
 2421        let Some(language) = buffer.language().cloned() else {
 2422            return;
 2423        };
 2424        let path: Arc<RelPath> = file
 2425            .path()
 2426            .parent()
 2427            .map(Arc::from)
 2428            .unwrap_or_else(|| file.path().clone());
 2429        let Some(worktree) = self
 2430            .worktree_store
 2431            .read(cx)
 2432            .worktree_for_id(worktree_id, cx)
 2433        else {
 2434            return;
 2435        };
 2436        let language_name = language.name();
 2437        let (reused, delegate, servers) = self
 2438            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2439            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2440            .unwrap_or_else(|| {
 2441                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2442                let delegate: Arc<dyn ManifestDelegate> =
 2443                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2444
 2445                let servers = self
 2446                    .lsp_tree
 2447                    .walk(
 2448                        ProjectPath { worktree_id, path },
 2449                        language.name(),
 2450                        language.manifest(),
 2451                        &delegate,
 2452                        cx,
 2453                    )
 2454                    .collect::<Vec<_>>();
 2455                (false, lsp_delegate, servers)
 2456            });
 2457        let servers_and_adapters = servers
 2458            .into_iter()
 2459            .filter_map(|server_node| {
 2460                if reused && server_node.server_id().is_none() {
 2461                    return None;
 2462                }
 2463                if !only_register_servers.is_empty() {
 2464                    if let Some(server_id) = server_node.server_id()
 2465                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2466                    {
 2467                        return None;
 2468                    }
 2469                    if let Some(name) = server_node.name()
 2470                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2471                    {
 2472                        return None;
 2473                    }
 2474                }
 2475
 2476                let server_id = server_node.server_id_or_init(|disposition| {
 2477                    let path = &disposition.path;
 2478
 2479                    {
 2480                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2481
 2482                        let server_id = self.get_or_insert_language_server(
 2483                            &worktree,
 2484                            delegate.clone(),
 2485                            disposition,
 2486                            &language_name,
 2487                            cx,
 2488                        );
 2489
 2490                        if let Some(state) = self.language_servers.get(&server_id)
 2491                            && let Ok(uri) = uri
 2492                        {
 2493                            state.add_workspace_folder(uri);
 2494                        };
 2495                        server_id
 2496                    }
 2497                })?;
 2498                let server_state = self.language_servers.get(&server_id)?;
 2499                if let LanguageServerState::Running {
 2500                    server, adapter, ..
 2501                } = server_state
 2502                {
 2503                    Some((server.clone(), adapter.clone()))
 2504                } else {
 2505                    None
 2506                }
 2507            })
 2508            .collect::<Vec<_>>();
 2509        for (server, adapter) in servers_and_adapters {
 2510            buffer_handle.update(cx, |buffer, cx| {
 2511                buffer.set_completion_triggers(
 2512                    server.server_id(),
 2513                    server
 2514                        .capabilities()
 2515                        .completion_provider
 2516                        .as_ref()
 2517                        .and_then(|provider| {
 2518                            provider
 2519                                .trigger_characters
 2520                                .as_ref()
 2521                                .map(|characters| characters.iter().cloned().collect())
 2522                        })
 2523                        .unwrap_or_default(),
 2524                    cx,
 2525                );
 2526            });
 2527
 2528            let snapshot = LspBufferSnapshot {
 2529                version: 0,
 2530                snapshot: initial_snapshot.clone(),
 2531            };
 2532
 2533            let mut registered = false;
 2534            self.buffer_snapshots
 2535                .entry(buffer_id)
 2536                .or_default()
 2537                .entry(server.server_id())
 2538                .or_insert_with(|| {
 2539                    registered = true;
 2540                    server.register_buffer(
 2541                        uri.clone(),
 2542                        adapter.language_id(&language.name()),
 2543                        0,
 2544                        initial_snapshot.text(),
 2545                    );
 2546
 2547                    vec![snapshot]
 2548                });
 2549
 2550            self.buffers_opened_in_servers
 2551                .entry(buffer_id)
 2552                .or_default()
 2553                .insert(server.server_id());
 2554            if registered {
 2555                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2556                    language_server_id: server.server_id(),
 2557                    name: None,
 2558                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2559                        proto::RegisteredForBuffer {
 2560                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2561                            buffer_id: buffer_id.to_proto(),
 2562                        },
 2563                    ),
 2564                });
 2565            }
 2566        }
 2567    }
 2568
 2569    fn reuse_existing_language_server<'lang_name>(
 2570        &self,
 2571        server_tree: &LanguageServerTree,
 2572        worktree: &Entity<Worktree>,
 2573        language_name: &'lang_name LanguageName,
 2574        cx: &mut App,
 2575    ) -> Option<(
 2576        Arc<LocalLspAdapterDelegate>,
 2577        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2578    )> {
 2579        if worktree.read(cx).is_visible() {
 2580            return None;
 2581        }
 2582
 2583        let worktree_store = self.worktree_store.read(cx);
 2584        let servers = server_tree
 2585            .instances
 2586            .iter()
 2587            .filter(|(worktree_id, _)| {
 2588                worktree_store
 2589                    .worktree_for_id(**worktree_id, cx)
 2590                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2591            })
 2592            .flat_map(|(worktree_id, servers)| {
 2593                servers
 2594                    .roots
 2595                    .iter()
 2596                    .flat_map(|(_, language_servers)| language_servers)
 2597                    .map(move |(_, (server_node, server_languages))| {
 2598                        (worktree_id, server_node, server_languages)
 2599                    })
 2600                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2601                    .map(|(worktree_id, server_node, _)| {
 2602                        (
 2603                            *worktree_id,
 2604                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2605                        )
 2606                    })
 2607            })
 2608            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2609                acc.entry(worktree_id)
 2610                    .or_insert_with(Vec::new)
 2611                    .push(server_node);
 2612                acc
 2613            })
 2614            .into_values()
 2615            .max_by_key(|servers| servers.len())?;
 2616
 2617        let worktree_id = worktree.read(cx).id();
 2618        let apply = move |tree: &mut LanguageServerTree| {
 2619            for server_node in &servers {
 2620                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2621            }
 2622            servers
 2623        };
 2624
 2625        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2626        Some((delegate, apply))
 2627    }
 2628
 2629    pub(crate) fn unregister_old_buffer_from_language_servers(
 2630        &mut self,
 2631        buffer: &Entity<Buffer>,
 2632        old_file: &File,
 2633        cx: &mut App,
 2634    ) {
 2635        let old_path = match old_file.as_local() {
 2636            Some(local) => local.abs_path(cx),
 2637            None => return,
 2638        };
 2639
 2640        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2641            debug_panic!("{old_path:?} is not parseable as an URI");
 2642            return;
 2643        };
 2644        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2645    }
 2646
 2647    pub(crate) fn unregister_buffer_from_language_servers(
 2648        &mut self,
 2649        buffer: &Entity<Buffer>,
 2650        file_url: &lsp::Uri,
 2651        cx: &mut App,
 2652    ) {
 2653        buffer.update(cx, |buffer, cx| {
 2654            let _ = self.buffer_snapshots.remove(&buffer.remote_id());
 2655
 2656            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2657                language_server.unregister_buffer(file_url.clone());
 2658            }
 2659        });
 2660    }
 2661
 2662    fn buffer_snapshot_for_lsp_version(
 2663        &mut self,
 2664        buffer: &Entity<Buffer>,
 2665        server_id: LanguageServerId,
 2666        version: Option<i32>,
 2667        cx: &App,
 2668    ) -> Result<TextBufferSnapshot> {
 2669        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2670
 2671        if let Some(version) = version {
 2672            let buffer_id = buffer.read(cx).remote_id();
 2673            let snapshots = if let Some(snapshots) = self
 2674                .buffer_snapshots
 2675                .get_mut(&buffer_id)
 2676                .and_then(|m| m.get_mut(&server_id))
 2677            {
 2678                snapshots
 2679            } else if version == 0 {
 2680                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2681                // We detect this case and treat it as if the version was `None`.
 2682                return Ok(buffer.read(cx).text_snapshot());
 2683            } else {
 2684                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2685            };
 2686
 2687            let found_snapshot = snapshots
 2688                    .binary_search_by_key(&version, |e| e.version)
 2689                    .map(|ix| snapshots[ix].snapshot.clone())
 2690                    .map_err(|_| {
 2691                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2692                    })?;
 2693
 2694            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2695            Ok(found_snapshot)
 2696        } else {
 2697            Ok((buffer.read(cx)).text_snapshot())
 2698        }
 2699    }
 2700
 2701    async fn get_server_code_actions_from_action_kinds(
 2702        lsp_store: &WeakEntity<LspStore>,
 2703        language_server_id: LanguageServerId,
 2704        code_action_kinds: Vec<lsp::CodeActionKind>,
 2705        buffer: &Entity<Buffer>,
 2706        cx: &mut AsyncApp,
 2707    ) -> Result<Vec<CodeAction>> {
 2708        let actions = lsp_store
 2709            .update(cx, move |this, cx| {
 2710                let request = GetCodeActions {
 2711                    range: text::Anchor::MIN..text::Anchor::MAX,
 2712                    kinds: Some(code_action_kinds),
 2713                };
 2714                let server = LanguageServerToQuery::Other(language_server_id);
 2715                this.request_lsp(buffer.clone(), server, request, cx)
 2716            })?
 2717            .await?;
 2718        Ok(actions)
 2719    }
 2720
 2721    pub async fn execute_code_actions_on_server(
 2722        lsp_store: &WeakEntity<LspStore>,
 2723        language_server: &Arc<LanguageServer>,
 2724
 2725        actions: Vec<CodeAction>,
 2726        push_to_history: bool,
 2727        project_transaction: &mut ProjectTransaction,
 2728        cx: &mut AsyncApp,
 2729    ) -> anyhow::Result<()> {
 2730        for mut action in actions {
 2731            Self::try_resolve_code_action(language_server, &mut action)
 2732                .await
 2733                .context("resolving a formatting code action")?;
 2734
 2735            if let Some(edit) = action.lsp_action.edit() {
 2736                if edit.changes.is_none() && edit.document_changes.is_none() {
 2737                    continue;
 2738                }
 2739
 2740                let new = Self::deserialize_workspace_edit(
 2741                    lsp_store.upgrade().context("project dropped")?,
 2742                    edit.clone(),
 2743                    push_to_history,
 2744                    language_server.clone(),
 2745                    cx,
 2746                )
 2747                .await?;
 2748                project_transaction.0.extend(new.0);
 2749            }
 2750
 2751            if let Some(command) = action.lsp_action.command() {
 2752                let server_capabilities = language_server.capabilities();
 2753                let available_commands = server_capabilities
 2754                    .execute_command_provider
 2755                    .as_ref()
 2756                    .map(|options| options.commands.as_slice())
 2757                    .unwrap_or_default();
 2758                if available_commands.contains(&command.command) {
 2759                    lsp_store.update(cx, |lsp_store, _| {
 2760                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2761                            mode.last_workspace_edits_by_language_server
 2762                                .remove(&language_server.server_id());
 2763                        }
 2764                    })?;
 2765
 2766                    language_server
 2767                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2768                            command: command.command.clone(),
 2769                            arguments: command.arguments.clone().unwrap_or_default(),
 2770                            ..Default::default()
 2771                        })
 2772                        .await
 2773                        .into_response()
 2774                        .context("execute command")?;
 2775
 2776                    lsp_store.update(cx, |this, _| {
 2777                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2778                            project_transaction.0.extend(
 2779                                mode.last_workspace_edits_by_language_server
 2780                                    .remove(&language_server.server_id())
 2781                                    .unwrap_or_default()
 2782                                    .0,
 2783                            )
 2784                        }
 2785                    })?;
 2786                } else {
 2787                    log::warn!(
 2788                        "Cannot execute a command {} not listed in the language server capabilities",
 2789                        command.command
 2790                    )
 2791                }
 2792            }
 2793        }
 2794        Ok(())
 2795    }
 2796
 2797    pub async fn deserialize_text_edits(
 2798        this: Entity<LspStore>,
 2799        buffer_to_edit: Entity<Buffer>,
 2800        edits: Vec<lsp::TextEdit>,
 2801        push_to_history: bool,
 2802        _: Arc<CachedLspAdapter>,
 2803        language_server: Arc<LanguageServer>,
 2804        cx: &mut AsyncApp,
 2805    ) -> Result<Option<Transaction>> {
 2806        let edits = this
 2807            .update(cx, |this, cx| {
 2808                this.as_local_mut().unwrap().edits_from_lsp(
 2809                    &buffer_to_edit,
 2810                    edits,
 2811                    language_server.server_id(),
 2812                    None,
 2813                    cx,
 2814                )
 2815            })?
 2816            .await?;
 2817
 2818        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2819            buffer.finalize_last_transaction();
 2820            buffer.start_transaction();
 2821            for (range, text) in edits {
 2822                buffer.edit([(range, text)], None, cx);
 2823            }
 2824
 2825            if buffer.end_transaction(cx).is_some() {
 2826                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2827                if !push_to_history {
 2828                    buffer.forget_transaction(transaction.id);
 2829                }
 2830                Some(transaction)
 2831            } else {
 2832                None
 2833            }
 2834        })?;
 2835
 2836        Ok(transaction)
 2837    }
 2838
 2839    #[allow(clippy::type_complexity)]
 2840    pub(crate) fn edits_from_lsp(
 2841        &mut self,
 2842        buffer: &Entity<Buffer>,
 2843        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2844        server_id: LanguageServerId,
 2845        version: Option<i32>,
 2846        cx: &mut Context<LspStore>,
 2847    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 2848        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 2849        cx.background_spawn(async move {
 2850            let snapshot = snapshot?;
 2851            let mut lsp_edits = lsp_edits
 2852                .into_iter()
 2853                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 2854                .collect::<Vec<_>>();
 2855
 2856            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 2857
 2858            let mut lsp_edits = lsp_edits.into_iter().peekable();
 2859            let mut edits = Vec::new();
 2860            while let Some((range, mut new_text)) = lsp_edits.next() {
 2861                // Clip invalid ranges provided by the language server.
 2862                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 2863                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 2864
 2865                // Combine any LSP edits that are adjacent.
 2866                //
 2867                // Also, combine LSP edits that are separated from each other by only
 2868                // a newline. This is important because for some code actions,
 2869                // Rust-analyzer rewrites the entire buffer via a series of edits that
 2870                // are separated by unchanged newline characters.
 2871                //
 2872                // In order for the diffing logic below to work properly, any edits that
 2873                // cancel each other out must be combined into one.
 2874                while let Some((next_range, next_text)) = lsp_edits.peek() {
 2875                    if next_range.start.0 > range.end {
 2876                        if next_range.start.0.row > range.end.row + 1
 2877                            || next_range.start.0.column > 0
 2878                            || snapshot.clip_point_utf16(
 2879                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 2880                                Bias::Left,
 2881                            ) > range.end
 2882                        {
 2883                            break;
 2884                        }
 2885                        new_text.push('\n');
 2886                    }
 2887                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 2888                    new_text.push_str(next_text);
 2889                    lsp_edits.next();
 2890                }
 2891
 2892                // For multiline edits, perform a diff of the old and new text so that
 2893                // we can identify the changes more precisely, preserving the locations
 2894                // of any anchors positioned in the unchanged regions.
 2895                if range.end.row > range.start.row {
 2896                    let offset = range.start.to_offset(&snapshot);
 2897                    let old_text = snapshot.text_for_range(range).collect::<String>();
 2898                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 2899                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 2900                        (
 2901                            snapshot.anchor_after(offset + range.start)
 2902                                ..snapshot.anchor_before(offset + range.end),
 2903                            replacement,
 2904                        )
 2905                    }));
 2906                } else if range.end == range.start {
 2907                    let anchor = snapshot.anchor_after(range.start);
 2908                    edits.push((anchor..anchor, new_text.into()));
 2909                } else {
 2910                    let edit_start = snapshot.anchor_after(range.start);
 2911                    let edit_end = snapshot.anchor_before(range.end);
 2912                    edits.push((edit_start..edit_end, new_text.into()));
 2913                }
 2914            }
 2915
 2916            Ok(edits)
 2917        })
 2918    }
 2919
 2920    pub(crate) async fn deserialize_workspace_edit(
 2921        this: Entity<LspStore>,
 2922        edit: lsp::WorkspaceEdit,
 2923        push_to_history: bool,
 2924        language_server: Arc<LanguageServer>,
 2925        cx: &mut AsyncApp,
 2926    ) -> Result<ProjectTransaction> {
 2927        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 2928
 2929        let mut operations = Vec::new();
 2930        if let Some(document_changes) = edit.document_changes {
 2931            match document_changes {
 2932                lsp::DocumentChanges::Edits(edits) => {
 2933                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 2934                }
 2935                lsp::DocumentChanges::Operations(ops) => operations = ops,
 2936            }
 2937        } else if let Some(changes) = edit.changes {
 2938            operations.extend(changes.into_iter().map(|(uri, edits)| {
 2939                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 2940                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 2941                        uri,
 2942                        version: None,
 2943                    },
 2944                    edits: edits.into_iter().map(Edit::Plain).collect(),
 2945                })
 2946            }));
 2947        }
 2948
 2949        let mut project_transaction = ProjectTransaction::default();
 2950        for operation in operations {
 2951            match operation {
 2952                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 2953                    let abs_path = op
 2954                        .uri
 2955                        .to_file_path()
 2956                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2957
 2958                    if let Some(parent_path) = abs_path.parent() {
 2959                        fs.create_dir(parent_path).await?;
 2960                    }
 2961                    if abs_path.ends_with("/") {
 2962                        fs.create_dir(&abs_path).await?;
 2963                    } else {
 2964                        fs.create_file(
 2965                            &abs_path,
 2966                            op.options
 2967                                .map(|options| fs::CreateOptions {
 2968                                    overwrite: options.overwrite.unwrap_or(false),
 2969                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 2970                                })
 2971                                .unwrap_or_default(),
 2972                        )
 2973                        .await?;
 2974                    }
 2975                }
 2976
 2977                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 2978                    let source_abs_path = op
 2979                        .old_uri
 2980                        .to_file_path()
 2981                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2982                    let target_abs_path = op
 2983                        .new_uri
 2984                        .to_file_path()
 2985                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2986                    fs.rename(
 2987                        &source_abs_path,
 2988                        &target_abs_path,
 2989                        op.options
 2990                            .map(|options| fs::RenameOptions {
 2991                                overwrite: options.overwrite.unwrap_or(false),
 2992                                ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 2993                            })
 2994                            .unwrap_or_default(),
 2995                    )
 2996                    .await?;
 2997                }
 2998
 2999                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3000                    let abs_path = op
 3001                        .uri
 3002                        .to_file_path()
 3003                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3004                    let options = op
 3005                        .options
 3006                        .map(|options| fs::RemoveOptions {
 3007                            recursive: options.recursive.unwrap_or(false),
 3008                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3009                        })
 3010                        .unwrap_or_default();
 3011                    if abs_path.ends_with("/") {
 3012                        fs.remove_dir(&abs_path, options).await?;
 3013                    } else {
 3014                        fs.remove_file(&abs_path, options).await?;
 3015                    }
 3016                }
 3017
 3018                lsp::DocumentChangeOperation::Edit(op) => {
 3019                    let buffer_to_edit = this
 3020                        .update(cx, |this, cx| {
 3021                            this.open_local_buffer_via_lsp(
 3022                                op.text_document.uri.clone(),
 3023                                language_server.server_id(),
 3024                                cx,
 3025                            )
 3026                        })?
 3027                        .await?;
 3028
 3029                    let edits = this
 3030                        .update(cx, |this, cx| {
 3031                            let path = buffer_to_edit.read(cx).project_path(cx);
 3032                            let active_entry = this.active_entry;
 3033                            let is_active_entry = path.is_some_and(|project_path| {
 3034                                this.worktree_store
 3035                                    .read(cx)
 3036                                    .entry_for_path(&project_path, cx)
 3037                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3038                            });
 3039                            let local = this.as_local_mut().unwrap();
 3040
 3041                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3042                            for edit in op.edits {
 3043                                match edit {
 3044                                    Edit::Plain(edit) => {
 3045                                        if !edits.contains(&edit) {
 3046                                            edits.push(edit)
 3047                                        }
 3048                                    }
 3049                                    Edit::Annotated(edit) => {
 3050                                        if !edits.contains(&edit.text_edit) {
 3051                                            edits.push(edit.text_edit)
 3052                                        }
 3053                                    }
 3054                                    Edit::Snippet(edit) => {
 3055                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3056                                        else {
 3057                                            continue;
 3058                                        };
 3059
 3060                                        if is_active_entry {
 3061                                            snippet_edits.push((edit.range, snippet));
 3062                                        } else {
 3063                                            // Since this buffer is not focused, apply a normal edit.
 3064                                            let new_edit = TextEdit {
 3065                                                range: edit.range,
 3066                                                new_text: snippet.text,
 3067                                            };
 3068                                            if !edits.contains(&new_edit) {
 3069                                                edits.push(new_edit);
 3070                                            }
 3071                                        }
 3072                                    }
 3073                                }
 3074                            }
 3075                            if !snippet_edits.is_empty() {
 3076                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3077                                let version = if let Some(buffer_version) = op.text_document.version
 3078                                {
 3079                                    local
 3080                                        .buffer_snapshot_for_lsp_version(
 3081                                            &buffer_to_edit,
 3082                                            language_server.server_id(),
 3083                                            Some(buffer_version),
 3084                                            cx,
 3085                                        )
 3086                                        .ok()
 3087                                        .map(|snapshot| snapshot.version)
 3088                                } else {
 3089                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3090                                };
 3091
 3092                                let most_recent_edit =
 3093                                    version.and_then(|version| version.most_recent());
 3094                                // Check if the edit that triggered that edit has been made by this participant.
 3095
 3096                                if let Some(most_recent_edit) = most_recent_edit {
 3097                                    cx.emit(LspStoreEvent::SnippetEdit {
 3098                                        buffer_id,
 3099                                        edits: snippet_edits,
 3100                                        most_recent_edit,
 3101                                    });
 3102                                }
 3103                            }
 3104
 3105                            local.edits_from_lsp(
 3106                                &buffer_to_edit,
 3107                                edits,
 3108                                language_server.server_id(),
 3109                                op.text_document.version,
 3110                                cx,
 3111                            )
 3112                        })?
 3113                        .await?;
 3114
 3115                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3116                        buffer.finalize_last_transaction();
 3117                        buffer.start_transaction();
 3118                        for (range, text) in edits {
 3119                            buffer.edit([(range, text)], None, cx);
 3120                        }
 3121
 3122                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3123                            if push_to_history {
 3124                                buffer.finalize_last_transaction();
 3125                                buffer.get_transaction(transaction_id).cloned()
 3126                            } else {
 3127                                buffer.forget_transaction(transaction_id)
 3128                            }
 3129                        })
 3130                    })?;
 3131                    if let Some(transaction) = transaction {
 3132                        project_transaction.0.insert(buffer_to_edit, transaction);
 3133                    }
 3134                }
 3135            }
 3136        }
 3137
 3138        Ok(project_transaction)
 3139    }
 3140
 3141    async fn on_lsp_workspace_edit(
 3142        this: WeakEntity<LspStore>,
 3143        params: lsp::ApplyWorkspaceEditParams,
 3144        server_id: LanguageServerId,
 3145        cx: &mut AsyncApp,
 3146    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3147        let this = this.upgrade().context("project project closed")?;
 3148        let language_server = this
 3149            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3150            .context("language server not found")?;
 3151        let transaction = Self::deserialize_workspace_edit(
 3152            this.clone(),
 3153            params.edit,
 3154            true,
 3155            language_server.clone(),
 3156            cx,
 3157        )
 3158        .await
 3159        .log_err();
 3160        this.update(cx, |this, _| {
 3161            if let Some(transaction) = transaction {
 3162                this.as_local_mut()
 3163                    .unwrap()
 3164                    .last_workspace_edits_by_language_server
 3165                    .insert(server_id, transaction);
 3166            }
 3167        })?;
 3168        Ok(lsp::ApplyWorkspaceEditResponse {
 3169            applied: true,
 3170            failed_change: None,
 3171            failure_reason: None,
 3172        })
 3173    }
 3174
 3175    fn remove_worktree(
 3176        &mut self,
 3177        id_to_remove: WorktreeId,
 3178        cx: &mut Context<LspStore>,
 3179    ) -> Vec<LanguageServerId> {
 3180        self.diagnostics.remove(&id_to_remove);
 3181        self.prettier_store.update(cx, |prettier_store, cx| {
 3182            prettier_store.remove_worktree(id_to_remove, cx);
 3183        });
 3184
 3185        let mut servers_to_remove = BTreeSet::default();
 3186        let mut servers_to_preserve = HashSet::default();
 3187        for (seed, state) in &self.language_server_ids {
 3188            if seed.worktree_id == id_to_remove {
 3189                servers_to_remove.insert(state.id);
 3190            } else {
 3191                servers_to_preserve.insert(state.id);
 3192            }
 3193        }
 3194        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3195        self.language_server_ids
 3196            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3197        for server_id_to_remove in &servers_to_remove {
 3198            self.language_server_watched_paths
 3199                .remove(server_id_to_remove);
 3200            self.language_server_paths_watched_for_rename
 3201                .remove(server_id_to_remove);
 3202            self.last_workspace_edits_by_language_server
 3203                .remove(server_id_to_remove);
 3204            self.language_servers.remove(server_id_to_remove);
 3205            self.buffer_pull_diagnostics_result_ids
 3206                .remove(server_id_to_remove);
 3207            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3208                buffer_servers.remove(server_id_to_remove);
 3209            }
 3210            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3211        }
 3212        servers_to_remove.into_iter().collect()
 3213    }
 3214
 3215    fn rebuild_watched_paths_inner<'a>(
 3216        &'a self,
 3217        language_server_id: LanguageServerId,
 3218        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3219        cx: &mut Context<LspStore>,
 3220    ) -> LanguageServerWatchedPathsBuilder {
 3221        let worktrees = self
 3222            .worktree_store
 3223            .read(cx)
 3224            .worktrees()
 3225            .filter_map(|worktree| {
 3226                self.language_servers_for_worktree(worktree.read(cx).id())
 3227                    .find(|server| server.server_id() == language_server_id)
 3228                    .map(|_| worktree)
 3229            })
 3230            .collect::<Vec<_>>();
 3231
 3232        let mut worktree_globs = HashMap::default();
 3233        let mut abs_globs = HashMap::default();
 3234        log::trace!(
 3235            "Processing new watcher paths for language server with id {}",
 3236            language_server_id
 3237        );
 3238
 3239        for watcher in watchers {
 3240            if let Some((worktree, literal_prefix, pattern)) =
 3241                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3242            {
 3243                worktree.update(cx, |worktree, _| {
 3244                    if let Some((tree, glob)) =
 3245                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3246                    {
 3247                        tree.add_path_prefix_to_scan(literal_prefix);
 3248                        worktree_globs
 3249                            .entry(tree.id())
 3250                            .or_insert_with(GlobSetBuilder::new)
 3251                            .add(glob);
 3252                    }
 3253                });
 3254            } else {
 3255                let (path, pattern) = match &watcher.glob_pattern {
 3256                    lsp::GlobPattern::String(s) => {
 3257                        let watcher_path = SanitizedPath::new(s);
 3258                        let path = glob_literal_prefix(watcher_path.as_path());
 3259                        let pattern = watcher_path
 3260                            .as_path()
 3261                            .strip_prefix(&path)
 3262                            .map(|p| p.to_string_lossy().into_owned())
 3263                            .unwrap_or_else(|e| {
 3264                                debug_panic!(
 3265                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3266                                    s,
 3267                                    path.display(),
 3268                                    e
 3269                                );
 3270                                watcher_path.as_path().to_string_lossy().into_owned()
 3271                            });
 3272                        (path, pattern)
 3273                    }
 3274                    lsp::GlobPattern::Relative(rp) => {
 3275                        let Ok(mut base_uri) = match &rp.base_uri {
 3276                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3277                            lsp::OneOf::Right(base_uri) => base_uri,
 3278                        }
 3279                        .to_file_path() else {
 3280                            continue;
 3281                        };
 3282
 3283                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3284                        let pattern = Path::new(&rp.pattern)
 3285                            .strip_prefix(&path)
 3286                            .map(|p| p.to_string_lossy().into_owned())
 3287                            .unwrap_or_else(|e| {
 3288                                debug_panic!(
 3289                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3290                                    rp.pattern,
 3291                                    path.display(),
 3292                                    e
 3293                                );
 3294                                rp.pattern.clone()
 3295                            });
 3296                        base_uri.push(path);
 3297                        (base_uri, pattern)
 3298                    }
 3299                };
 3300
 3301                if let Some(glob) = Glob::new(&pattern).log_err() {
 3302                    if !path
 3303                        .components()
 3304                        .any(|c| matches!(c, path::Component::Normal(_)))
 3305                    {
 3306                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3307                        // rather than adding a new watcher for `/`.
 3308                        for worktree in &worktrees {
 3309                            worktree_globs
 3310                                .entry(worktree.read(cx).id())
 3311                                .or_insert_with(GlobSetBuilder::new)
 3312                                .add(glob.clone());
 3313                        }
 3314                    } else {
 3315                        abs_globs
 3316                            .entry(path.into())
 3317                            .or_insert_with(GlobSetBuilder::new)
 3318                            .add(glob);
 3319                    }
 3320                }
 3321            }
 3322        }
 3323
 3324        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3325        for (worktree_id, builder) in worktree_globs {
 3326            if let Ok(globset) = builder.build() {
 3327                watch_builder.watch_worktree(worktree_id, globset);
 3328            }
 3329        }
 3330        for (abs_path, builder) in abs_globs {
 3331            if let Ok(globset) = builder.build() {
 3332                watch_builder.watch_abs_path(abs_path, globset);
 3333            }
 3334        }
 3335        watch_builder
 3336    }
 3337
 3338    fn worktree_and_path_for_file_watcher(
 3339        worktrees: &[Entity<Worktree>],
 3340        watcher: &FileSystemWatcher,
 3341        cx: &App,
 3342    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3343        worktrees.iter().find_map(|worktree| {
 3344            let tree = worktree.read(cx);
 3345            let worktree_root_path = tree.abs_path();
 3346            let path_style = tree.path_style();
 3347            match &watcher.glob_pattern {
 3348                lsp::GlobPattern::String(s) => {
 3349                    let watcher_path = SanitizedPath::new(s);
 3350                    let relative = watcher_path
 3351                        .as_path()
 3352                        .strip_prefix(&worktree_root_path)
 3353                        .ok()?;
 3354                    let literal_prefix = glob_literal_prefix(relative);
 3355                    Some((
 3356                        worktree.clone(),
 3357                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3358                        relative.to_string_lossy().into_owned(),
 3359                    ))
 3360                }
 3361                lsp::GlobPattern::Relative(rp) => {
 3362                    let base_uri = match &rp.base_uri {
 3363                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3364                        lsp::OneOf::Right(base_uri) => base_uri,
 3365                    }
 3366                    .to_file_path()
 3367                    .ok()?;
 3368                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3369                    let mut literal_prefix = relative.to_owned();
 3370                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3371                    Some((
 3372                        worktree.clone(),
 3373                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3374                        rp.pattern.clone(),
 3375                    ))
 3376                }
 3377            }
 3378        })
 3379    }
 3380
 3381    fn rebuild_watched_paths(
 3382        &mut self,
 3383        language_server_id: LanguageServerId,
 3384        cx: &mut Context<LspStore>,
 3385    ) {
 3386        let Some(registrations) = self
 3387            .language_server_dynamic_registrations
 3388            .get(&language_server_id)
 3389        else {
 3390            return;
 3391        };
 3392
 3393        let watch_builder = self.rebuild_watched_paths_inner(
 3394            language_server_id,
 3395            registrations.did_change_watched_files.values().flatten(),
 3396            cx,
 3397        );
 3398        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3399        self.language_server_watched_paths
 3400            .insert(language_server_id, watcher);
 3401
 3402        cx.notify();
 3403    }
 3404
 3405    fn on_lsp_did_change_watched_files(
 3406        &mut self,
 3407        language_server_id: LanguageServerId,
 3408        registration_id: &str,
 3409        params: DidChangeWatchedFilesRegistrationOptions,
 3410        cx: &mut Context<LspStore>,
 3411    ) {
 3412        let registrations = self
 3413            .language_server_dynamic_registrations
 3414            .entry(language_server_id)
 3415            .or_default();
 3416
 3417        registrations
 3418            .did_change_watched_files
 3419            .insert(registration_id.to_string(), params.watchers);
 3420
 3421        self.rebuild_watched_paths(language_server_id, cx);
 3422    }
 3423
 3424    fn on_lsp_unregister_did_change_watched_files(
 3425        &mut self,
 3426        language_server_id: LanguageServerId,
 3427        registration_id: &str,
 3428        cx: &mut Context<LspStore>,
 3429    ) {
 3430        let registrations = self
 3431            .language_server_dynamic_registrations
 3432            .entry(language_server_id)
 3433            .or_default();
 3434
 3435        if registrations
 3436            .did_change_watched_files
 3437            .remove(registration_id)
 3438            .is_some()
 3439        {
 3440            log::info!(
 3441                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3442                language_server_id,
 3443                registration_id
 3444            );
 3445        } else {
 3446            log::warn!(
 3447                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3448                language_server_id,
 3449                registration_id
 3450            );
 3451        }
 3452
 3453        self.rebuild_watched_paths(language_server_id, cx);
 3454    }
 3455
 3456    async fn initialization_options_for_adapter(
 3457        adapter: Arc<dyn LspAdapter>,
 3458        delegate: &Arc<dyn LspAdapterDelegate>,
 3459    ) -> Result<Option<serde_json::Value>> {
 3460        let Some(mut initialization_config) =
 3461            adapter.clone().initialization_options(delegate).await?
 3462        else {
 3463            return Ok(None);
 3464        };
 3465
 3466        for other_adapter in delegate.registered_lsp_adapters() {
 3467            if other_adapter.name() == adapter.name() {
 3468                continue;
 3469            }
 3470            if let Ok(Some(target_config)) = other_adapter
 3471                .clone()
 3472                .additional_initialization_options(adapter.name(), delegate)
 3473                .await
 3474            {
 3475                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3476            }
 3477        }
 3478
 3479        Ok(Some(initialization_config))
 3480    }
 3481
 3482    async fn workspace_configuration_for_adapter(
 3483        adapter: Arc<dyn LspAdapter>,
 3484        delegate: &Arc<dyn LspAdapterDelegate>,
 3485        toolchain: Option<Toolchain>,
 3486        cx: &mut AsyncApp,
 3487    ) -> Result<serde_json::Value> {
 3488        let mut workspace_config = adapter
 3489            .clone()
 3490            .workspace_configuration(delegate, toolchain, cx)
 3491            .await?;
 3492
 3493        for other_adapter in delegate.registered_lsp_adapters() {
 3494            if other_adapter.name() == adapter.name() {
 3495                continue;
 3496            }
 3497            if let Ok(Some(target_config)) = other_adapter
 3498                .clone()
 3499                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3500                .await
 3501            {
 3502                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3503            }
 3504        }
 3505
 3506        Ok(workspace_config)
 3507    }
 3508
 3509    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3510        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3511            Some(server.clone())
 3512        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3513            Some(Arc::clone(server))
 3514        } else {
 3515            None
 3516        }
 3517    }
 3518}
 3519
 3520fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3521    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3522        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3523            language_server_id: server.server_id(),
 3524            name: Some(server.name()),
 3525            message: proto::update_language_server::Variant::MetadataUpdated(
 3526                proto::ServerMetadataUpdated {
 3527                    capabilities: Some(capabilities),
 3528                },
 3529            ),
 3530        });
 3531    }
 3532}
 3533
 3534#[derive(Debug)]
 3535pub struct FormattableBuffer {
 3536    handle: Entity<Buffer>,
 3537    abs_path: Option<PathBuf>,
 3538    env: Option<HashMap<String, String>>,
 3539    ranges: Option<Vec<Range<Anchor>>>,
 3540}
 3541
 3542pub struct RemoteLspStore {
 3543    upstream_client: Option<AnyProtoClient>,
 3544    upstream_project_id: u64,
 3545}
 3546
 3547pub(crate) enum LspStoreMode {
 3548    Local(LocalLspStore),   // ssh host and collab host
 3549    Remote(RemoteLspStore), // collab guest
 3550}
 3551
 3552impl LspStoreMode {
 3553    fn is_local(&self) -> bool {
 3554        matches!(self, LspStoreMode::Local(_))
 3555    }
 3556}
 3557
 3558pub struct LspStore {
 3559    mode: LspStoreMode,
 3560    last_formatting_failure: Option<String>,
 3561    downstream_client: Option<(AnyProtoClient, u64)>,
 3562    nonce: u128,
 3563    buffer_store: Entity<BufferStore>,
 3564    worktree_store: Entity<WorktreeStore>,
 3565    pub languages: Arc<LanguageRegistry>,
 3566    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3567    active_entry: Option<ProjectEntryId>,
 3568    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3569    _maintain_buffer_languages: Task<()>,
 3570    diagnostic_summaries:
 3571        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3572    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3573    lsp_data: HashMap<BufferId, BufferLspData>,
 3574    next_hint_id: Arc<AtomicUsize>,
 3575}
 3576
 3577#[derive(Debug)]
 3578pub struct BufferLspData {
 3579    buffer_version: Global,
 3580    document_colors: Option<DocumentColorData>,
 3581    code_lens: Option<CodeLensData>,
 3582    inlay_hints: BufferInlayHints,
 3583    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3584    chunk_lsp_requests: HashMap<LspKey, HashMap<BufferChunk, LspRequestId>>,
 3585}
 3586
 3587#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3588struct LspKey {
 3589    request_type: TypeId,
 3590    server_queried: Option<LanguageServerId>,
 3591}
 3592
 3593impl BufferLspData {
 3594    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3595        Self {
 3596            buffer_version: buffer.read(cx).version(),
 3597            document_colors: None,
 3598            code_lens: None,
 3599            inlay_hints: BufferInlayHints::new(buffer, cx),
 3600            lsp_requests: HashMap::default(),
 3601            chunk_lsp_requests: HashMap::default(),
 3602        }
 3603    }
 3604
 3605    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3606        if let Some(document_colors) = &mut self.document_colors {
 3607            document_colors.colors.remove(&for_server);
 3608            document_colors.cache_version += 1;
 3609        }
 3610
 3611        if let Some(code_lens) = &mut self.code_lens {
 3612            code_lens.lens.remove(&for_server);
 3613        }
 3614
 3615        self.inlay_hints.remove_server_data(for_server);
 3616    }
 3617
 3618    #[cfg(any(test, feature = "test-support"))]
 3619    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3620        &self.inlay_hints
 3621    }
 3622}
 3623
 3624#[derive(Debug, Default, Clone)]
 3625pub struct DocumentColors {
 3626    pub colors: HashSet<DocumentColor>,
 3627    pub cache_version: Option<usize>,
 3628}
 3629
 3630type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3631type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3632
 3633#[derive(Debug, Default)]
 3634struct DocumentColorData {
 3635    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3636    cache_version: usize,
 3637    colors_update: Option<(Global, DocumentColorTask)>,
 3638}
 3639
 3640#[derive(Debug, Default)]
 3641struct CodeLensData {
 3642    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3643    update: Option<(Global, CodeLensTask)>,
 3644}
 3645
 3646#[derive(Debug)]
 3647pub enum LspStoreEvent {
 3648    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3649    LanguageServerRemoved(LanguageServerId),
 3650    LanguageServerUpdate {
 3651        language_server_id: LanguageServerId,
 3652        name: Option<LanguageServerName>,
 3653        message: proto::update_language_server::Variant,
 3654    },
 3655    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3656    LanguageServerPrompt(LanguageServerPromptRequest),
 3657    LanguageDetected {
 3658        buffer: Entity<Buffer>,
 3659        new_language: Option<Arc<Language>>,
 3660    },
 3661    Notification(String),
 3662    RefreshInlayHints(LanguageServerId),
 3663    RefreshCodeLens,
 3664    DiagnosticsUpdated {
 3665        server_id: LanguageServerId,
 3666        paths: Vec<ProjectPath>,
 3667    },
 3668    DiskBasedDiagnosticsStarted {
 3669        language_server_id: LanguageServerId,
 3670    },
 3671    DiskBasedDiagnosticsFinished {
 3672        language_server_id: LanguageServerId,
 3673    },
 3674    SnippetEdit {
 3675        buffer_id: BufferId,
 3676        edits: Vec<(lsp::Range, Snippet)>,
 3677        most_recent_edit: clock::Lamport,
 3678    },
 3679}
 3680
 3681#[derive(Clone, Debug, Serialize)]
 3682pub struct LanguageServerStatus {
 3683    pub name: LanguageServerName,
 3684    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 3685    pub has_pending_diagnostic_updates: bool,
 3686    progress_tokens: HashSet<ProgressToken>,
 3687    pub worktree: Option<WorktreeId>,
 3688}
 3689
 3690#[derive(Clone, Debug)]
 3691struct CoreSymbol {
 3692    pub language_server_name: LanguageServerName,
 3693    pub source_worktree_id: WorktreeId,
 3694    pub source_language_server_id: LanguageServerId,
 3695    pub path: SymbolLocation,
 3696    pub name: String,
 3697    pub kind: lsp::SymbolKind,
 3698    pub range: Range<Unclipped<PointUtf16>>,
 3699}
 3700
 3701#[derive(Clone, Debug, PartialEq, Eq)]
 3702pub enum SymbolLocation {
 3703    InProject(ProjectPath),
 3704    OutsideProject {
 3705        abs_path: Arc<Path>,
 3706        signature: [u8; 32],
 3707    },
 3708}
 3709
 3710impl SymbolLocation {
 3711    fn file_name(&self) -> Option<&str> {
 3712        match self {
 3713            Self::InProject(path) => path.path.file_name(),
 3714            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3715        }
 3716    }
 3717}
 3718
 3719impl LspStore {
 3720    pub fn init(client: &AnyProtoClient) {
 3721        client.add_entity_request_handler(Self::handle_lsp_query);
 3722        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3723        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3724        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3725        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3726        client.add_entity_message_handler(Self::handle_start_language_server);
 3727        client.add_entity_message_handler(Self::handle_update_language_server);
 3728        client.add_entity_message_handler(Self::handle_language_server_log);
 3729        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3730        client.add_entity_request_handler(Self::handle_format_buffers);
 3731        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3732        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3733        client.add_entity_request_handler(Self::handle_apply_code_action);
 3734        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3735        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3736        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3737        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3738        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3739        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3740        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3741        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3742        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3743        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3744        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3745        client.add_entity_request_handler(Self::handle_lsp_command::<GetCompletions>);
 3746        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3747        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3748        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3749        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3750        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3751
 3752        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3753        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3754        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3755        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3756        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3757        client.add_entity_request_handler(
 3758            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3759        );
 3760        client.add_entity_request_handler(
 3761            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3762        );
 3763        client.add_entity_request_handler(
 3764            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3765        );
 3766    }
 3767
 3768    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3769        match &self.mode {
 3770            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3771            _ => None,
 3772        }
 3773    }
 3774
 3775    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3776        match &self.mode {
 3777            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3778            _ => None,
 3779        }
 3780    }
 3781
 3782    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3783        match &mut self.mode {
 3784            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3785            _ => None,
 3786        }
 3787    }
 3788
 3789    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3790        match &self.mode {
 3791            LspStoreMode::Remote(RemoteLspStore {
 3792                upstream_client: Some(upstream_client),
 3793                upstream_project_id,
 3794                ..
 3795            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3796
 3797            LspStoreMode::Remote(RemoteLspStore {
 3798                upstream_client: None,
 3799                ..
 3800            }) => None,
 3801            LspStoreMode::Local(_) => None,
 3802        }
 3803    }
 3804
 3805    pub fn new_local(
 3806        buffer_store: Entity<BufferStore>,
 3807        worktree_store: Entity<WorktreeStore>,
 3808        prettier_store: Entity<PrettierStore>,
 3809        toolchain_store: Entity<LocalToolchainStore>,
 3810        environment: Entity<ProjectEnvironment>,
 3811        manifest_tree: Entity<ManifestTree>,
 3812        languages: Arc<LanguageRegistry>,
 3813        http_client: Arc<dyn HttpClient>,
 3814        fs: Arc<dyn Fs>,
 3815        cx: &mut Context<Self>,
 3816    ) -> Self {
 3817        let yarn = YarnPathStore::new(fs.clone(), cx);
 3818        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3819            .detach();
 3820        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3821            .detach();
 3822        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 3823            .detach();
 3824        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 3825            .detach();
 3826        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 3827            .detach();
 3828        subscribe_to_binary_statuses(&languages, cx).detach();
 3829
 3830        let _maintain_workspace_config = {
 3831            let (sender, receiver) = watch::channel();
 3832            (Self::maintain_workspace_config(receiver, cx), sender)
 3833        };
 3834
 3835        Self {
 3836            mode: LspStoreMode::Local(LocalLspStore {
 3837                weak: cx.weak_entity(),
 3838                worktree_store: worktree_store.clone(),
 3839
 3840                supplementary_language_servers: Default::default(),
 3841                languages: languages.clone(),
 3842                language_server_ids: Default::default(),
 3843                language_servers: Default::default(),
 3844                last_workspace_edits_by_language_server: Default::default(),
 3845                language_server_watched_paths: Default::default(),
 3846                language_server_paths_watched_for_rename: Default::default(),
 3847                language_server_dynamic_registrations: Default::default(),
 3848                buffers_being_formatted: Default::default(),
 3849                buffer_snapshots: Default::default(),
 3850                prettier_store,
 3851                environment,
 3852                http_client,
 3853                fs,
 3854                yarn,
 3855                next_diagnostic_group_id: Default::default(),
 3856                diagnostics: Default::default(),
 3857                _subscription: cx.on_app_quit(|this, cx| {
 3858                    this.as_local_mut()
 3859                        .unwrap()
 3860                        .shutdown_language_servers_on_quit(cx)
 3861                }),
 3862                lsp_tree: LanguageServerTree::new(
 3863                    manifest_tree,
 3864                    languages.clone(),
 3865                    toolchain_store.clone(),
 3866                ),
 3867                toolchain_store,
 3868                registered_buffers: HashMap::default(),
 3869                buffers_opened_in_servers: HashMap::default(),
 3870                buffer_pull_diagnostics_result_ids: HashMap::default(),
 3871                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 3872                    .manifest_file_names(),
 3873            }),
 3874            last_formatting_failure: None,
 3875            downstream_client: None,
 3876            buffer_store,
 3877            worktree_store,
 3878            languages: languages.clone(),
 3879            language_server_statuses: Default::default(),
 3880            nonce: StdRng::from_os_rng().random(),
 3881            diagnostic_summaries: HashMap::default(),
 3882            lsp_server_capabilities: HashMap::default(),
 3883            lsp_data: HashMap::default(),
 3884            next_hint_id: Arc::default(),
 3885            active_entry: None,
 3886            _maintain_workspace_config,
 3887            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 3888        }
 3889    }
 3890
 3891    fn send_lsp_proto_request<R: LspCommand>(
 3892        &self,
 3893        buffer: Entity<Buffer>,
 3894        client: AnyProtoClient,
 3895        upstream_project_id: u64,
 3896        request: R,
 3897        cx: &mut Context<LspStore>,
 3898    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 3899        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 3900            return Task::ready(Ok(R::Response::default()));
 3901        }
 3902        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 3903        cx.spawn(async move |this, cx| {
 3904            let response = client.request(message).await?;
 3905            let this = this.upgrade().context("project dropped")?;
 3906            request
 3907                .response_from_proto(response, this, buffer, cx.clone())
 3908                .await
 3909        })
 3910    }
 3911
 3912    pub(super) fn new_remote(
 3913        buffer_store: Entity<BufferStore>,
 3914        worktree_store: Entity<WorktreeStore>,
 3915        languages: Arc<LanguageRegistry>,
 3916        upstream_client: AnyProtoClient,
 3917        project_id: u64,
 3918        cx: &mut Context<Self>,
 3919    ) -> Self {
 3920        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3921            .detach();
 3922        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3923            .detach();
 3924        subscribe_to_binary_statuses(&languages, cx).detach();
 3925        let _maintain_workspace_config = {
 3926            let (sender, receiver) = watch::channel();
 3927            (Self::maintain_workspace_config(receiver, cx), sender)
 3928        };
 3929        Self {
 3930            mode: LspStoreMode::Remote(RemoteLspStore {
 3931                upstream_client: Some(upstream_client),
 3932                upstream_project_id: project_id,
 3933            }),
 3934            downstream_client: None,
 3935            last_formatting_failure: None,
 3936            buffer_store,
 3937            worktree_store,
 3938            languages: languages.clone(),
 3939            language_server_statuses: Default::default(),
 3940            nonce: StdRng::from_os_rng().random(),
 3941            diagnostic_summaries: HashMap::default(),
 3942            lsp_server_capabilities: HashMap::default(),
 3943            next_hint_id: Arc::default(),
 3944            lsp_data: HashMap::default(),
 3945            active_entry: None,
 3946
 3947            _maintain_workspace_config,
 3948            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 3949        }
 3950    }
 3951
 3952    fn on_buffer_store_event(
 3953        &mut self,
 3954        _: Entity<BufferStore>,
 3955        event: &BufferStoreEvent,
 3956        cx: &mut Context<Self>,
 3957    ) {
 3958        match event {
 3959            BufferStoreEvent::BufferAdded(buffer) => {
 3960                self.on_buffer_added(buffer, cx).log_err();
 3961            }
 3962            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 3963                let buffer_id = buffer.read(cx).remote_id();
 3964                if let Some(local) = self.as_local_mut()
 3965                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 3966                {
 3967                    local.reset_buffer(buffer, old_file, cx);
 3968
 3969                    if local.registered_buffers.contains_key(&buffer_id) {
 3970                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 3971                    }
 3972                }
 3973
 3974                self.detect_language_for_buffer(buffer, cx);
 3975                if let Some(local) = self.as_local_mut() {
 3976                    local.initialize_buffer(buffer, cx);
 3977                    if local.registered_buffers.contains_key(&buffer_id) {
 3978                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 3979                    }
 3980                }
 3981            }
 3982            _ => {}
 3983        }
 3984    }
 3985
 3986    fn on_worktree_store_event(
 3987        &mut self,
 3988        _: Entity<WorktreeStore>,
 3989        event: &WorktreeStoreEvent,
 3990        cx: &mut Context<Self>,
 3991    ) {
 3992        match event {
 3993            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 3994                if !worktree.read(cx).is_local() {
 3995                    return;
 3996                }
 3997                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 3998                    worktree::Event::UpdatedEntries(changes) => {
 3999                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4000                    }
 4001                    worktree::Event::UpdatedGitRepositories(_)
 4002                    | worktree::Event::DeletedEntry(_) => {}
 4003                })
 4004                .detach()
 4005            }
 4006            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4007            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4008                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4009            }
 4010            WorktreeStoreEvent::WorktreeReleased(..)
 4011            | WorktreeStoreEvent::WorktreeOrderChanged
 4012            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4013            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4014            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4015        }
 4016    }
 4017
 4018    fn on_prettier_store_event(
 4019        &mut self,
 4020        _: Entity<PrettierStore>,
 4021        event: &PrettierStoreEvent,
 4022        cx: &mut Context<Self>,
 4023    ) {
 4024        match event {
 4025            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4026                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4027            }
 4028            PrettierStoreEvent::LanguageServerAdded {
 4029                new_server_id,
 4030                name,
 4031                prettier_server,
 4032            } => {
 4033                self.register_supplementary_language_server(
 4034                    *new_server_id,
 4035                    name.clone(),
 4036                    prettier_server.clone(),
 4037                    cx,
 4038                );
 4039            }
 4040        }
 4041    }
 4042
 4043    fn on_toolchain_store_event(
 4044        &mut self,
 4045        _: Entity<LocalToolchainStore>,
 4046        event: &ToolchainStoreEvent,
 4047        _: &mut Context<Self>,
 4048    ) {
 4049        if let ToolchainStoreEvent::ToolchainActivated = event {
 4050            self.request_workspace_config_refresh()
 4051        }
 4052    }
 4053
 4054    fn request_workspace_config_refresh(&mut self) {
 4055        *self._maintain_workspace_config.1.borrow_mut() = ();
 4056    }
 4057
 4058    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4059        self.as_local().map(|local| local.prettier_store.clone())
 4060    }
 4061
 4062    fn on_buffer_event(
 4063        &mut self,
 4064        buffer: Entity<Buffer>,
 4065        event: &language::BufferEvent,
 4066        cx: &mut Context<Self>,
 4067    ) {
 4068        match event {
 4069            language::BufferEvent::Edited => {
 4070                self.on_buffer_edited(buffer, cx);
 4071            }
 4072
 4073            language::BufferEvent::Saved => {
 4074                self.on_buffer_saved(buffer, cx);
 4075            }
 4076
 4077            _ => {}
 4078        }
 4079    }
 4080
 4081    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4082        buffer
 4083            .read(cx)
 4084            .set_language_registry(self.languages.clone());
 4085
 4086        cx.subscribe(buffer, |this, buffer, event, cx| {
 4087            this.on_buffer_event(buffer, event, cx);
 4088        })
 4089        .detach();
 4090
 4091        self.detect_language_for_buffer(buffer, cx);
 4092        if let Some(local) = self.as_local_mut() {
 4093            local.initialize_buffer(buffer, cx);
 4094        }
 4095
 4096        Ok(())
 4097    }
 4098
 4099    pub(crate) fn register_buffer_with_language_servers(
 4100        &mut self,
 4101        buffer: &Entity<Buffer>,
 4102        only_register_servers: HashSet<LanguageServerSelector>,
 4103        ignore_refcounts: bool,
 4104        cx: &mut Context<Self>,
 4105    ) -> OpenLspBufferHandle {
 4106        let buffer_id = buffer.read(cx).remote_id();
 4107        let handle = cx.new(|_| buffer.clone());
 4108        if let Some(local) = self.as_local_mut() {
 4109            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4110            if !ignore_refcounts {
 4111                *refcount += 1;
 4112            }
 4113
 4114            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4115            // 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
 4116            // 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
 4117            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4118            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4119                return handle;
 4120            };
 4121            if !file.is_local() {
 4122                return handle;
 4123            }
 4124
 4125            if ignore_refcounts || *refcount == 1 {
 4126                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4127            }
 4128            if !ignore_refcounts {
 4129                cx.observe_release(&handle, move |lsp_store, buffer, cx| {
 4130                    let refcount = {
 4131                        let local = lsp_store.as_local_mut().unwrap();
 4132                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4133                            debug_panic!("bad refcounting");
 4134                            return;
 4135                        };
 4136
 4137                        *refcount -= 1;
 4138                        *refcount
 4139                    };
 4140                    if refcount == 0 {
 4141                        lsp_store.lsp_data.remove(&buffer_id);
 4142                        let local = lsp_store.as_local_mut().unwrap();
 4143                        local.registered_buffers.remove(&buffer_id);
 4144                        local.buffers_opened_in_servers.remove(&buffer_id);
 4145                        if let Some(file) = File::from_dyn(buffer.read(cx).file()).cloned() {
 4146                            local.unregister_old_buffer_from_language_servers(buffer, &file, cx);
 4147                        }
 4148                    }
 4149                })
 4150                .detach();
 4151            }
 4152        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4153            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4154            cx.background_spawn(async move {
 4155                upstream_client
 4156                    .request(proto::RegisterBufferWithLanguageServers {
 4157                        project_id: upstream_project_id,
 4158                        buffer_id,
 4159                        only_servers: only_register_servers
 4160                            .into_iter()
 4161                            .map(|selector| {
 4162                                let selector = match selector {
 4163                                    LanguageServerSelector::Id(language_server_id) => {
 4164                                        proto::language_server_selector::Selector::ServerId(
 4165                                            language_server_id.to_proto(),
 4166                                        )
 4167                                    }
 4168                                    LanguageServerSelector::Name(language_server_name) => {
 4169                                        proto::language_server_selector::Selector::Name(
 4170                                            language_server_name.to_string(),
 4171                                        )
 4172                                    }
 4173                                };
 4174                                proto::LanguageServerSelector {
 4175                                    selector: Some(selector),
 4176                                }
 4177                            })
 4178                            .collect(),
 4179                    })
 4180                    .await
 4181            })
 4182            .detach();
 4183        } else {
 4184            panic!("oops!");
 4185        }
 4186        handle
 4187    }
 4188
 4189    fn maintain_buffer_languages(
 4190        languages: Arc<LanguageRegistry>,
 4191        cx: &mut Context<Self>,
 4192    ) -> Task<()> {
 4193        let mut subscription = languages.subscribe();
 4194        let mut prev_reload_count = languages.reload_count();
 4195        cx.spawn(async move |this, cx| {
 4196            while let Some(()) = subscription.next().await {
 4197                if let Some(this) = this.upgrade() {
 4198                    // If the language registry has been reloaded, then remove and
 4199                    // re-assign the languages on all open buffers.
 4200                    let reload_count = languages.reload_count();
 4201                    if reload_count > prev_reload_count {
 4202                        prev_reload_count = reload_count;
 4203                        this.update(cx, |this, cx| {
 4204                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4205                                for buffer in buffer_store.buffers() {
 4206                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4207                                    {
 4208                                        buffer
 4209                                            .update(cx, |buffer, cx| buffer.set_language(None, cx));
 4210                                        if let Some(local) = this.as_local_mut() {
 4211                                            local.reset_buffer(&buffer, &f, cx);
 4212
 4213                                            if local
 4214                                                .registered_buffers
 4215                                                .contains_key(&buffer.read(cx).remote_id())
 4216                                                && let Some(file_url) =
 4217                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4218                                            {
 4219                                                local.unregister_buffer_from_language_servers(
 4220                                                    &buffer, &file_url, cx,
 4221                                                );
 4222                                            }
 4223                                        }
 4224                                    }
 4225                                }
 4226                            });
 4227                        })
 4228                        .ok();
 4229                    }
 4230
 4231                    this.update(cx, |this, cx| {
 4232                        let mut plain_text_buffers = Vec::new();
 4233                        let mut buffers_with_unknown_injections = Vec::new();
 4234                        for handle in this.buffer_store.read(cx).buffers() {
 4235                            let buffer = handle.read(cx);
 4236                            if buffer.language().is_none()
 4237                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4238                            {
 4239                                plain_text_buffers.push(handle);
 4240                            } else if buffer.contains_unknown_injections() {
 4241                                buffers_with_unknown_injections.push(handle);
 4242                            }
 4243                        }
 4244
 4245                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4246                        // and reused later in the invisible worktrees.
 4247                        plain_text_buffers.sort_by_key(|buffer| {
 4248                            Reverse(
 4249                                File::from_dyn(buffer.read(cx).file())
 4250                                    .map(|file| file.worktree.read(cx).is_visible()),
 4251                            )
 4252                        });
 4253
 4254                        for buffer in plain_text_buffers {
 4255                            this.detect_language_for_buffer(&buffer, cx);
 4256                            if let Some(local) = this.as_local_mut() {
 4257                                local.initialize_buffer(&buffer, cx);
 4258                                if local
 4259                                    .registered_buffers
 4260                                    .contains_key(&buffer.read(cx).remote_id())
 4261                                {
 4262                                    local.register_buffer_with_language_servers(
 4263                                        &buffer,
 4264                                        HashSet::default(),
 4265                                        cx,
 4266                                    );
 4267                                }
 4268                            }
 4269                        }
 4270
 4271                        for buffer in buffers_with_unknown_injections {
 4272                            buffer.update(cx, |buffer, cx| buffer.reparse(cx));
 4273                        }
 4274                    })
 4275                    .ok();
 4276                }
 4277            }
 4278        })
 4279    }
 4280
 4281    fn detect_language_for_buffer(
 4282        &mut self,
 4283        buffer_handle: &Entity<Buffer>,
 4284        cx: &mut Context<Self>,
 4285    ) -> Option<language::AvailableLanguage> {
 4286        // If the buffer has a language, set it and start the language server if we haven't already.
 4287        let buffer = buffer_handle.read(cx);
 4288        let file = buffer.file()?;
 4289
 4290        let content = buffer.as_rope();
 4291        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4292        if let Some(available_language) = &available_language {
 4293            if let Some(Ok(Ok(new_language))) = self
 4294                .languages
 4295                .load_language(available_language)
 4296                .now_or_never()
 4297            {
 4298                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4299            }
 4300        } else {
 4301            cx.emit(LspStoreEvent::LanguageDetected {
 4302                buffer: buffer_handle.clone(),
 4303                new_language: None,
 4304            });
 4305        }
 4306
 4307        available_language
 4308    }
 4309
 4310    pub(crate) fn set_language_for_buffer(
 4311        &mut self,
 4312        buffer_entity: &Entity<Buffer>,
 4313        new_language: Arc<Language>,
 4314        cx: &mut Context<Self>,
 4315    ) {
 4316        let buffer = buffer_entity.read(cx);
 4317        let buffer_file = buffer.file().cloned();
 4318        let buffer_id = buffer.remote_id();
 4319        if let Some(local_store) = self.as_local_mut()
 4320            && local_store.registered_buffers.contains_key(&buffer_id)
 4321            && let Some(abs_path) =
 4322                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4323            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4324        {
 4325            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4326        }
 4327        buffer_entity.update(cx, |buffer, cx| {
 4328            if buffer
 4329                .language()
 4330                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4331            {
 4332                buffer.set_language(Some(new_language.clone()), cx);
 4333            }
 4334        });
 4335
 4336        let settings =
 4337            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4338        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4339
 4340        let worktree_id = if let Some(file) = buffer_file {
 4341            let worktree = file.worktree.clone();
 4342
 4343            if let Some(local) = self.as_local_mut()
 4344                && local.registered_buffers.contains_key(&buffer_id)
 4345            {
 4346                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4347            }
 4348            Some(worktree.read(cx).id())
 4349        } else {
 4350            None
 4351        };
 4352
 4353        if settings.prettier.allowed
 4354            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4355        {
 4356            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4357            if let Some(prettier_store) = prettier_store {
 4358                prettier_store.update(cx, |prettier_store, cx| {
 4359                    prettier_store.install_default_prettier(
 4360                        worktree_id,
 4361                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4362                        cx,
 4363                    )
 4364                })
 4365            }
 4366        }
 4367
 4368        cx.emit(LspStoreEvent::LanguageDetected {
 4369            buffer: buffer_entity.clone(),
 4370            new_language: Some(new_language),
 4371        })
 4372    }
 4373
 4374    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4375        self.buffer_store.clone()
 4376    }
 4377
 4378    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4379        self.active_entry = active_entry;
 4380    }
 4381
 4382    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4383        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4384            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4385        {
 4386            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4387                summaries
 4388                    .iter()
 4389                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4390            });
 4391            if let Some(summary) = summaries.next() {
 4392                client
 4393                    .send(proto::UpdateDiagnosticSummary {
 4394                        project_id: downstream_project_id,
 4395                        worktree_id: worktree.id().to_proto(),
 4396                        summary: Some(summary),
 4397                        more_summaries: summaries.collect(),
 4398                    })
 4399                    .log_err();
 4400            }
 4401        }
 4402    }
 4403
 4404    fn is_capable_for_proto_request<R>(
 4405        &self,
 4406        buffer: &Entity<Buffer>,
 4407        request: &R,
 4408        cx: &App,
 4409    ) -> bool
 4410    where
 4411        R: LspCommand,
 4412    {
 4413        self.check_if_capable_for_proto_request(
 4414            buffer,
 4415            |capabilities| {
 4416                request.check_capabilities(AdapterServerCapabilities {
 4417                    server_capabilities: capabilities.clone(),
 4418                    code_action_kinds: None,
 4419                })
 4420            },
 4421            cx,
 4422        )
 4423    }
 4424
 4425    fn check_if_capable_for_proto_request<F>(
 4426        &self,
 4427        buffer: &Entity<Buffer>,
 4428        check: F,
 4429        cx: &App,
 4430    ) -> bool
 4431    where
 4432        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4433    {
 4434        let Some(language) = buffer.read(cx).language().cloned() else {
 4435            return false;
 4436        };
 4437        let relevant_language_servers = self
 4438            .languages
 4439            .lsp_adapters(&language.name())
 4440            .into_iter()
 4441            .map(|lsp_adapter| lsp_adapter.name())
 4442            .collect::<HashSet<_>>();
 4443        self.language_server_statuses
 4444            .iter()
 4445            .filter_map(|(server_id, server_status)| {
 4446                relevant_language_servers
 4447                    .contains(&server_status.name)
 4448                    .then_some(server_id)
 4449            })
 4450            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4451            .any(check)
 4452    }
 4453
 4454    pub fn request_lsp<R>(
 4455        &mut self,
 4456        buffer: Entity<Buffer>,
 4457        server: LanguageServerToQuery,
 4458        request: R,
 4459        cx: &mut Context<Self>,
 4460    ) -> Task<Result<R::Response>>
 4461    where
 4462        R: LspCommand,
 4463        <R::LspRequest as lsp::request::Request>::Result: Send,
 4464        <R::LspRequest as lsp::request::Request>::Params: Send,
 4465    {
 4466        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4467            return self.send_lsp_proto_request(
 4468                buffer,
 4469                upstream_client,
 4470                upstream_project_id,
 4471                request,
 4472                cx,
 4473            );
 4474        }
 4475
 4476        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4477            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4478                local
 4479                    .language_servers_for_buffer(buffer, cx)
 4480                    .find(|(_, server)| {
 4481                        request.check_capabilities(server.adapter_server_capabilities())
 4482                    })
 4483                    .map(|(_, server)| server.clone())
 4484            }),
 4485            LanguageServerToQuery::Other(id) => self
 4486                .language_server_for_local_buffer(buffer, id, cx)
 4487                .and_then(|(_, server)| {
 4488                    request
 4489                        .check_capabilities(server.adapter_server_capabilities())
 4490                        .then(|| Arc::clone(server))
 4491                }),
 4492        }) else {
 4493            return Task::ready(Ok(Default::default()));
 4494        };
 4495
 4496        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4497
 4498        let Some(file) = file else {
 4499            return Task::ready(Ok(Default::default()));
 4500        };
 4501
 4502        let lsp_params = match request.to_lsp_params_or_response(
 4503            &file.abs_path(cx),
 4504            buffer.read(cx),
 4505            &language_server,
 4506            cx,
 4507        ) {
 4508            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4509            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4510
 4511            Err(err) => {
 4512                let message = format!(
 4513                    "{} via {} failed: {}",
 4514                    request.display_name(),
 4515                    language_server.name(),
 4516                    err
 4517                );
 4518                log::warn!("{message}");
 4519                return Task::ready(Err(anyhow!(message)));
 4520            }
 4521        };
 4522
 4523        let status = request.status();
 4524        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4525            return Task::ready(Ok(Default::default()));
 4526        }
 4527        cx.spawn(async move |this, cx| {
 4528            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4529
 4530            let id = lsp_request.id();
 4531            let _cleanup = if status.is_some() {
 4532                cx.update(|cx| {
 4533                    this.update(cx, |this, cx| {
 4534                        this.on_lsp_work_start(
 4535                            language_server.server_id(),
 4536                            ProgressToken::Number(id),
 4537                            LanguageServerProgress {
 4538                                is_disk_based_diagnostics_progress: false,
 4539                                is_cancellable: false,
 4540                                title: None,
 4541                                message: status.clone(),
 4542                                percentage: None,
 4543                                last_update_at: cx.background_executor().now(),
 4544                            },
 4545                            cx,
 4546                        );
 4547                    })
 4548                })
 4549                .log_err();
 4550
 4551                Some(defer(|| {
 4552                    cx.update(|cx| {
 4553                        this.update(cx, |this, cx| {
 4554                            this.on_lsp_work_end(
 4555                                language_server.server_id(),
 4556                                ProgressToken::Number(id),
 4557                                cx,
 4558                            );
 4559                        })
 4560                    })
 4561                    .log_err();
 4562                }))
 4563            } else {
 4564                None
 4565            };
 4566
 4567            let result = lsp_request.await.into_response();
 4568
 4569            let response = result.map_err(|err| {
 4570                let message = format!(
 4571                    "{} via {} failed: {}",
 4572                    request.display_name(),
 4573                    language_server.name(),
 4574                    err
 4575                );
 4576                log::warn!("{message}");
 4577                anyhow::anyhow!(message)
 4578            })?;
 4579
 4580            request
 4581                .response_from_lsp(
 4582                    response,
 4583                    this.upgrade().context("no app context")?,
 4584                    buffer,
 4585                    language_server.server_id(),
 4586                    cx.clone(),
 4587                )
 4588                .await
 4589        })
 4590    }
 4591
 4592    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4593        let mut language_formatters_to_check = Vec::new();
 4594        for buffer in self.buffer_store.read(cx).buffers() {
 4595            let buffer = buffer.read(cx);
 4596            let buffer_file = File::from_dyn(buffer.file());
 4597            let buffer_language = buffer.language();
 4598            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4599            if buffer_language.is_some() {
 4600                language_formatters_to_check.push((
 4601                    buffer_file.map(|f| f.worktree_id(cx)),
 4602                    settings.into_owned(),
 4603                ));
 4604            }
 4605        }
 4606
 4607        self.request_workspace_config_refresh();
 4608
 4609        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4610            prettier_store.update(cx, |prettier_store, cx| {
 4611                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4612            })
 4613        }
 4614
 4615        cx.notify();
 4616    }
 4617
 4618    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4619        let buffer_store = self.buffer_store.clone();
 4620        let Some(local) = self.as_local_mut() else {
 4621            return;
 4622        };
 4623        let mut adapters = BTreeMap::default();
 4624        let get_adapter = {
 4625            let languages = local.languages.clone();
 4626            let environment = local.environment.clone();
 4627            let weak = local.weak.clone();
 4628            let worktree_store = local.worktree_store.clone();
 4629            let http_client = local.http_client.clone();
 4630            let fs = local.fs.clone();
 4631            move |worktree_id, cx: &mut App| {
 4632                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4633                Some(LocalLspAdapterDelegate::new(
 4634                    languages.clone(),
 4635                    &environment,
 4636                    weak.clone(),
 4637                    &worktree,
 4638                    http_client.clone(),
 4639                    fs.clone(),
 4640                    cx,
 4641                ))
 4642            }
 4643        };
 4644
 4645        let mut messages_to_report = Vec::new();
 4646        let (new_tree, to_stop) = {
 4647            let mut rebase = local.lsp_tree.rebase();
 4648            let buffers = buffer_store
 4649                .read(cx)
 4650                .buffers()
 4651                .filter_map(|buffer| {
 4652                    let raw_buffer = buffer.read(cx);
 4653                    if !local
 4654                        .registered_buffers
 4655                        .contains_key(&raw_buffer.remote_id())
 4656                    {
 4657                        return None;
 4658                    }
 4659                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4660                    let language = raw_buffer.language().cloned()?;
 4661                    Some((file, language, raw_buffer.remote_id()))
 4662                })
 4663                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4664            for (file, language, buffer_id) in buffers {
 4665                let worktree_id = file.worktree_id(cx);
 4666                let Some(worktree) = local
 4667                    .worktree_store
 4668                    .read(cx)
 4669                    .worktree_for_id(worktree_id, cx)
 4670                else {
 4671                    continue;
 4672                };
 4673
 4674                if let Some((_, apply)) = local.reuse_existing_language_server(
 4675                    rebase.server_tree(),
 4676                    &worktree,
 4677                    &language.name(),
 4678                    cx,
 4679                ) {
 4680                    (apply)(rebase.server_tree());
 4681                } else if let Some(lsp_delegate) = adapters
 4682                    .entry(worktree_id)
 4683                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4684                    .clone()
 4685                {
 4686                    let delegate =
 4687                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4688                    let path = file
 4689                        .path()
 4690                        .parent()
 4691                        .map(Arc::from)
 4692                        .unwrap_or_else(|| file.path().clone());
 4693                    let worktree_path = ProjectPath { worktree_id, path };
 4694                    let abs_path = file.abs_path(cx);
 4695                    let nodes = rebase
 4696                        .walk(
 4697                            worktree_path,
 4698                            language.name(),
 4699                            language.manifest(),
 4700                            delegate.clone(),
 4701                            cx,
 4702                        )
 4703                        .collect::<Vec<_>>();
 4704                    for node in nodes {
 4705                        let server_id = node.server_id_or_init(|disposition| {
 4706                            let path = &disposition.path;
 4707                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 4708                            let key = LanguageServerSeed {
 4709                                worktree_id,
 4710                                name: disposition.server_name.clone(),
 4711                                settings: disposition.settings.clone(),
 4712                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4713                                    path.worktree_id,
 4714                                    &path.path,
 4715                                    language.name(),
 4716                                ),
 4717                            };
 4718                            local.language_server_ids.remove(&key);
 4719
 4720                            let server_id = local.get_or_insert_language_server(
 4721                                &worktree,
 4722                                lsp_delegate.clone(),
 4723                                disposition,
 4724                                &language.name(),
 4725                                cx,
 4726                            );
 4727                            if let Some(state) = local.language_servers.get(&server_id)
 4728                                && let Ok(uri) = uri
 4729                            {
 4730                                state.add_workspace_folder(uri);
 4731                            };
 4732                            server_id
 4733                        });
 4734
 4735                        if let Some(language_server_id) = server_id {
 4736                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 4737                                language_server_id,
 4738                                name: node.name(),
 4739                                message:
 4740                                    proto::update_language_server::Variant::RegisteredForBuffer(
 4741                                        proto::RegisteredForBuffer {
 4742                                            buffer_abs_path: abs_path
 4743                                                .to_string_lossy()
 4744                                                .into_owned(),
 4745                                            buffer_id: buffer_id.to_proto(),
 4746                                        },
 4747                                    ),
 4748                            });
 4749                        }
 4750                    }
 4751                } else {
 4752                    continue;
 4753                }
 4754            }
 4755            rebase.finish()
 4756        };
 4757        for message in messages_to_report {
 4758            cx.emit(message);
 4759        }
 4760        local.lsp_tree = new_tree;
 4761        for (id, _) in to_stop {
 4762            self.stop_local_language_server(id, cx).detach();
 4763        }
 4764    }
 4765
 4766    pub fn apply_code_action(
 4767        &self,
 4768        buffer_handle: Entity<Buffer>,
 4769        mut action: CodeAction,
 4770        push_to_history: bool,
 4771        cx: &mut Context<Self>,
 4772    ) -> Task<Result<ProjectTransaction>> {
 4773        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4774            let request = proto::ApplyCodeAction {
 4775                project_id,
 4776                buffer_id: buffer_handle.read(cx).remote_id().into(),
 4777                action: Some(Self::serialize_code_action(&action)),
 4778            };
 4779            let buffer_store = self.buffer_store();
 4780            cx.spawn(async move |_, cx| {
 4781                let response = upstream_client
 4782                    .request(request)
 4783                    .await?
 4784                    .transaction
 4785                    .context("missing transaction")?;
 4786
 4787                buffer_store
 4788                    .update(cx, |buffer_store, cx| {
 4789                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 4790                    })?
 4791                    .await
 4792            })
 4793        } else if self.mode.is_local() {
 4794            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 4795                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 4796                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 4797            }) else {
 4798                return Task::ready(Ok(ProjectTransaction::default()));
 4799            };
 4800            cx.spawn(async move |this,  cx| {
 4801                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 4802                    .await
 4803                    .context("resolving a code action")?;
 4804                if let Some(edit) = action.lsp_action.edit()
 4805                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 4806                        return LocalLspStore::deserialize_workspace_edit(
 4807                            this.upgrade().context("no app present")?,
 4808                            edit.clone(),
 4809                            push_to_history,
 4810
 4811                            lang_server.clone(),
 4812                            cx,
 4813                        )
 4814                        .await;
 4815                    }
 4816
 4817                if let Some(command) = action.lsp_action.command() {
 4818                    let server_capabilities = lang_server.capabilities();
 4819                    let available_commands = server_capabilities
 4820                        .execute_command_provider
 4821                        .as_ref()
 4822                        .map(|options| options.commands.as_slice())
 4823                        .unwrap_or_default();
 4824                    if available_commands.contains(&command.command) {
 4825                        this.update(cx, |this, _| {
 4826                            this.as_local_mut()
 4827                                .unwrap()
 4828                                .last_workspace_edits_by_language_server
 4829                                .remove(&lang_server.server_id());
 4830                        })?;
 4831
 4832                        let _result = lang_server
 4833                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 4834                                command: command.command.clone(),
 4835                                arguments: command.arguments.clone().unwrap_or_default(),
 4836                                ..lsp::ExecuteCommandParams::default()
 4837                            })
 4838                            .await.into_response()
 4839                            .context("execute command")?;
 4840
 4841                        return this.update(cx, |this, _| {
 4842                            this.as_local_mut()
 4843                                .unwrap()
 4844                                .last_workspace_edits_by_language_server
 4845                                .remove(&lang_server.server_id())
 4846                                .unwrap_or_default()
 4847                        });
 4848                    } else {
 4849                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 4850                    }
 4851                }
 4852
 4853                Ok(ProjectTransaction::default())
 4854            })
 4855        } else {
 4856            Task::ready(Err(anyhow!("no upstream client and not local")))
 4857        }
 4858    }
 4859
 4860    pub fn apply_code_action_kind(
 4861        &mut self,
 4862        buffers: HashSet<Entity<Buffer>>,
 4863        kind: CodeActionKind,
 4864        push_to_history: bool,
 4865        cx: &mut Context<Self>,
 4866    ) -> Task<anyhow::Result<ProjectTransaction>> {
 4867        if self.as_local().is_some() {
 4868            cx.spawn(async move |lsp_store, cx| {
 4869                let buffers = buffers.into_iter().collect::<Vec<_>>();
 4870                let result = LocalLspStore::execute_code_action_kind_locally(
 4871                    lsp_store.clone(),
 4872                    buffers,
 4873                    kind,
 4874                    push_to_history,
 4875                    cx,
 4876                )
 4877                .await;
 4878                lsp_store.update(cx, |lsp_store, _| {
 4879                    lsp_store.update_last_formatting_failure(&result);
 4880                })?;
 4881                result
 4882            })
 4883        } else if let Some((client, project_id)) = self.upstream_client() {
 4884            let buffer_store = self.buffer_store();
 4885            cx.spawn(async move |lsp_store, cx| {
 4886                let result = client
 4887                    .request(proto::ApplyCodeActionKind {
 4888                        project_id,
 4889                        kind: kind.as_str().to_owned(),
 4890                        buffer_ids: buffers
 4891                            .iter()
 4892                            .map(|buffer| {
 4893                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 4894                            })
 4895                            .collect::<Result<_>>()?,
 4896                    })
 4897                    .await
 4898                    .and_then(|result| result.transaction.context("missing transaction"));
 4899                lsp_store.update(cx, |lsp_store, _| {
 4900                    lsp_store.update_last_formatting_failure(&result);
 4901                })?;
 4902
 4903                let transaction_response = result?;
 4904                buffer_store
 4905                    .update(cx, |buffer_store, cx| {
 4906                        buffer_store.deserialize_project_transaction(
 4907                            transaction_response,
 4908                            push_to_history,
 4909                            cx,
 4910                        )
 4911                    })?
 4912                    .await
 4913            })
 4914        } else {
 4915            Task::ready(Ok(ProjectTransaction::default()))
 4916        }
 4917    }
 4918
 4919    pub fn resolved_hint(
 4920        &mut self,
 4921        buffer_id: BufferId,
 4922        id: InlayId,
 4923        cx: &mut Context<Self>,
 4924    ) -> Option<ResolvedHint> {
 4925        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 4926
 4927        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 4928        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 4929        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 4930        let (server_id, resolve_data) = match &hint.resolve_state {
 4931            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 4932            ResolveState::Resolving => {
 4933                return Some(ResolvedHint::Resolving(
 4934                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 4935                ));
 4936            }
 4937            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 4938        };
 4939
 4940        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 4941        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 4942        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 4943            id,
 4944            cx.spawn(async move |lsp_store, cx| {
 4945                let resolved_hint = resolve_task.await;
 4946                lsp_store
 4947                    .update(cx, |lsp_store, _| {
 4948                        if let Some(old_inlay_hint) = lsp_store
 4949                            .lsp_data
 4950                            .get_mut(&buffer_id)
 4951                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 4952                        {
 4953                            match resolved_hint {
 4954                                Ok(resolved_hint) => {
 4955                                    *old_inlay_hint = resolved_hint;
 4956                                }
 4957                                Err(e) => {
 4958                                    old_inlay_hint.resolve_state =
 4959                                        ResolveState::CanResolve(server_id, resolve_data);
 4960                                    log::error!("Inlay hint resolve failed: {e:#}");
 4961                                }
 4962                            }
 4963                        }
 4964                    })
 4965                    .ok();
 4966            })
 4967            .shared(),
 4968        );
 4969        debug_assert!(
 4970            previous_task.is_none(),
 4971            "Did not change hint's resolve state after spawning its resolve"
 4972        );
 4973        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 4974        None
 4975    }
 4976
 4977    fn resolve_inlay_hint(
 4978        &self,
 4979        mut hint: InlayHint,
 4980        buffer: Entity<Buffer>,
 4981        server_id: LanguageServerId,
 4982        cx: &mut Context<Self>,
 4983    ) -> Task<anyhow::Result<InlayHint>> {
 4984        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4985            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 4986            {
 4987                hint.resolve_state = ResolveState::Resolved;
 4988                return Task::ready(Ok(hint));
 4989            }
 4990            let request = proto::ResolveInlayHint {
 4991                project_id,
 4992                buffer_id: buffer.read(cx).remote_id().into(),
 4993                language_server_id: server_id.0 as u64,
 4994                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 4995            };
 4996            cx.background_spawn(async move {
 4997                let response = upstream_client
 4998                    .request(request)
 4999                    .await
 5000                    .context("inlay hints proto request")?;
 5001                match response.hint {
 5002                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5003                        .context("inlay hints proto resolve response conversion"),
 5004                    None => Ok(hint),
 5005                }
 5006            })
 5007        } else {
 5008            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5009                self.language_server_for_local_buffer(buffer, server_id, cx)
 5010                    .map(|(_, server)| server.clone())
 5011            }) else {
 5012                return Task::ready(Ok(hint));
 5013            };
 5014            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5015                return Task::ready(Ok(hint));
 5016            }
 5017            let buffer_snapshot = buffer.read(cx).snapshot();
 5018            cx.spawn(async move |_, cx| {
 5019                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5020                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5021                );
 5022                let resolved_hint = resolve_task
 5023                    .await
 5024                    .into_response()
 5025                    .context("inlay hint resolve LSP request")?;
 5026                let resolved_hint = InlayHints::lsp_to_project_hint(
 5027                    resolved_hint,
 5028                    &buffer,
 5029                    server_id,
 5030                    ResolveState::Resolved,
 5031                    false,
 5032                    cx,
 5033                )
 5034                .await?;
 5035                Ok(resolved_hint)
 5036            })
 5037        }
 5038    }
 5039
 5040    pub fn resolve_color_presentation(
 5041        &mut self,
 5042        mut color: DocumentColor,
 5043        buffer: Entity<Buffer>,
 5044        server_id: LanguageServerId,
 5045        cx: &mut Context<Self>,
 5046    ) -> Task<Result<DocumentColor>> {
 5047        if color.resolved {
 5048            return Task::ready(Ok(color));
 5049        }
 5050
 5051        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5052            let start = color.lsp_range.start;
 5053            let end = color.lsp_range.end;
 5054            let request = proto::GetColorPresentation {
 5055                project_id,
 5056                server_id: server_id.to_proto(),
 5057                buffer_id: buffer.read(cx).remote_id().into(),
 5058                color: Some(proto::ColorInformation {
 5059                    red: color.color.red,
 5060                    green: color.color.green,
 5061                    blue: color.color.blue,
 5062                    alpha: color.color.alpha,
 5063                    lsp_range_start: Some(proto::PointUtf16 {
 5064                        row: start.line,
 5065                        column: start.character,
 5066                    }),
 5067                    lsp_range_end: Some(proto::PointUtf16 {
 5068                        row: end.line,
 5069                        column: end.character,
 5070                    }),
 5071                }),
 5072            };
 5073            cx.background_spawn(async move {
 5074                let response = upstream_client
 5075                    .request(request)
 5076                    .await
 5077                    .context("color presentation proto request")?;
 5078                color.resolved = true;
 5079                color.color_presentations = response
 5080                    .presentations
 5081                    .into_iter()
 5082                    .map(|presentation| ColorPresentation {
 5083                        label: SharedString::from(presentation.label),
 5084                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5085                        additional_text_edits: presentation
 5086                            .additional_text_edits
 5087                            .into_iter()
 5088                            .filter_map(deserialize_lsp_edit)
 5089                            .collect(),
 5090                    })
 5091                    .collect();
 5092                Ok(color)
 5093            })
 5094        } else {
 5095            let path = match buffer
 5096                .update(cx, |buffer, cx| {
 5097                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5098                })
 5099                .context("buffer with the missing path")
 5100            {
 5101                Ok(path) => path,
 5102                Err(e) => return Task::ready(Err(e)),
 5103            };
 5104            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5105                self.language_server_for_local_buffer(buffer, server_id, cx)
 5106                    .map(|(_, server)| server.clone())
 5107            }) else {
 5108                return Task::ready(Ok(color));
 5109            };
 5110            cx.background_spawn(async move {
 5111                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5112                    lsp::ColorPresentationParams {
 5113                        text_document: make_text_document_identifier(&path)?,
 5114                        color: color.color,
 5115                        range: color.lsp_range,
 5116                        work_done_progress_params: Default::default(),
 5117                        partial_result_params: Default::default(),
 5118                    },
 5119                );
 5120                color.color_presentations = resolve_task
 5121                    .await
 5122                    .into_response()
 5123                    .context("color presentation resolve LSP request")?
 5124                    .into_iter()
 5125                    .map(|presentation| ColorPresentation {
 5126                        label: SharedString::from(presentation.label),
 5127                        text_edit: presentation.text_edit,
 5128                        additional_text_edits: presentation
 5129                            .additional_text_edits
 5130                            .unwrap_or_default(),
 5131                    })
 5132                    .collect();
 5133                color.resolved = true;
 5134                Ok(color)
 5135            })
 5136        }
 5137    }
 5138
 5139    pub(crate) fn linked_edits(
 5140        &mut self,
 5141        buffer: &Entity<Buffer>,
 5142        position: Anchor,
 5143        cx: &mut Context<Self>,
 5144    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5145        let snapshot = buffer.read(cx).snapshot();
 5146        let scope = snapshot.language_scope_at(position);
 5147        let Some(server_id) = self
 5148            .as_local()
 5149            .and_then(|local| {
 5150                buffer.update(cx, |buffer, cx| {
 5151                    local
 5152                        .language_servers_for_buffer(buffer, cx)
 5153                        .filter(|(_, server)| {
 5154                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5155                        })
 5156                        .filter(|(adapter, _)| {
 5157                            scope
 5158                                .as_ref()
 5159                                .map(|scope| scope.language_allowed(&adapter.name))
 5160                                .unwrap_or(true)
 5161                        })
 5162                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5163                        .next()
 5164                })
 5165            })
 5166            .or_else(|| {
 5167                self.upstream_client()
 5168                    .is_some()
 5169                    .then_some(LanguageServerToQuery::FirstCapable)
 5170            })
 5171            .filter(|_| {
 5172                maybe!({
 5173                    let language = buffer.read(cx).language_at(position)?;
 5174                    Some(
 5175                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5176                            .linked_edits,
 5177                    )
 5178                }) == Some(true)
 5179            })
 5180        else {
 5181            return Task::ready(Ok(Vec::new()));
 5182        };
 5183
 5184        self.request_lsp(
 5185            buffer.clone(),
 5186            server_id,
 5187            LinkedEditingRange { position },
 5188            cx,
 5189        )
 5190    }
 5191
 5192    fn apply_on_type_formatting(
 5193        &mut self,
 5194        buffer: Entity<Buffer>,
 5195        position: Anchor,
 5196        trigger: String,
 5197        cx: &mut Context<Self>,
 5198    ) -> Task<Result<Option<Transaction>>> {
 5199        if let Some((client, project_id)) = self.upstream_client() {
 5200            if !self.check_if_capable_for_proto_request(
 5201                &buffer,
 5202                |capabilities| {
 5203                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5204                },
 5205                cx,
 5206            ) {
 5207                return Task::ready(Ok(None));
 5208            }
 5209            let request = proto::OnTypeFormatting {
 5210                project_id,
 5211                buffer_id: buffer.read(cx).remote_id().into(),
 5212                position: Some(serialize_anchor(&position)),
 5213                trigger,
 5214                version: serialize_version(&buffer.read(cx).version()),
 5215            };
 5216            cx.background_spawn(async move {
 5217                client
 5218                    .request(request)
 5219                    .await?
 5220                    .transaction
 5221                    .map(language::proto::deserialize_transaction)
 5222                    .transpose()
 5223            })
 5224        } else if let Some(local) = self.as_local_mut() {
 5225            let buffer_id = buffer.read(cx).remote_id();
 5226            local.buffers_being_formatted.insert(buffer_id);
 5227            cx.spawn(async move |this, cx| {
 5228                let _cleanup = defer({
 5229                    let this = this.clone();
 5230                    let mut cx = cx.clone();
 5231                    move || {
 5232                        this.update(&mut cx, |this, _| {
 5233                            if let Some(local) = this.as_local_mut() {
 5234                                local.buffers_being_formatted.remove(&buffer_id);
 5235                            }
 5236                        })
 5237                        .ok();
 5238                    }
 5239                });
 5240
 5241                buffer
 5242                    .update(cx, |buffer, _| {
 5243                        buffer.wait_for_edits(Some(position.timestamp))
 5244                    })?
 5245                    .await?;
 5246                this.update(cx, |this, cx| {
 5247                    let position = position.to_point_utf16(buffer.read(cx));
 5248                    this.on_type_format(buffer, position, trigger, false, cx)
 5249                })?
 5250                .await
 5251            })
 5252        } else {
 5253            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5254        }
 5255    }
 5256
 5257    pub fn on_type_format<T: ToPointUtf16>(
 5258        &mut self,
 5259        buffer: Entity<Buffer>,
 5260        position: T,
 5261        trigger: String,
 5262        push_to_history: bool,
 5263        cx: &mut Context<Self>,
 5264    ) -> Task<Result<Option<Transaction>>> {
 5265        let position = position.to_point_utf16(buffer.read(cx));
 5266        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5267    }
 5268
 5269    fn on_type_format_impl(
 5270        &mut self,
 5271        buffer: Entity<Buffer>,
 5272        position: PointUtf16,
 5273        trigger: String,
 5274        push_to_history: bool,
 5275        cx: &mut Context<Self>,
 5276    ) -> Task<Result<Option<Transaction>>> {
 5277        let options = buffer.update(cx, |buffer, cx| {
 5278            lsp_command::lsp_formatting_options(
 5279                language_settings(
 5280                    buffer.language_at(position).map(|l| l.name()),
 5281                    buffer.file(),
 5282                    cx,
 5283                )
 5284                .as_ref(),
 5285            )
 5286        });
 5287
 5288        cx.spawn(async move |this, cx| {
 5289            if let Some(waiter) =
 5290                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5291            {
 5292                waiter.await?;
 5293            }
 5294            cx.update(|cx| {
 5295                this.update(cx, |this, cx| {
 5296                    this.request_lsp(
 5297                        buffer.clone(),
 5298                        LanguageServerToQuery::FirstCapable,
 5299                        OnTypeFormatting {
 5300                            position,
 5301                            trigger,
 5302                            options,
 5303                            push_to_history,
 5304                        },
 5305                        cx,
 5306                    )
 5307                })
 5308            })??
 5309            .await
 5310        })
 5311    }
 5312
 5313    pub fn definitions(
 5314        &mut self,
 5315        buffer: &Entity<Buffer>,
 5316        position: PointUtf16,
 5317        cx: &mut Context<Self>,
 5318    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5319        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5320            let request = GetDefinitions { position };
 5321            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5322                return Task::ready(Ok(None));
 5323            }
 5324            let request_task = upstream_client.request_lsp(
 5325                project_id,
 5326                None,
 5327                LSP_REQUEST_TIMEOUT,
 5328                cx.background_executor().clone(),
 5329                request.to_proto(project_id, buffer.read(cx)),
 5330            );
 5331            let buffer = buffer.clone();
 5332            cx.spawn(async move |weak_project, cx| {
 5333                let Some(project) = weak_project.upgrade() else {
 5334                    return Ok(None);
 5335                };
 5336                let Some(responses) = request_task.await? else {
 5337                    return Ok(None);
 5338                };
 5339                let actions = join_all(responses.payload.into_iter().map(|response| {
 5340                    GetDefinitions { position }.response_from_proto(
 5341                        response.response,
 5342                        project.clone(),
 5343                        buffer.clone(),
 5344                        cx.clone(),
 5345                    )
 5346                }))
 5347                .await;
 5348
 5349                Ok(Some(
 5350                    actions
 5351                        .into_iter()
 5352                        .collect::<Result<Vec<Vec<_>>>>()?
 5353                        .into_iter()
 5354                        .flatten()
 5355                        .dedup()
 5356                        .collect(),
 5357                ))
 5358            })
 5359        } else {
 5360            let definitions_task = self.request_multiple_lsp_locally(
 5361                buffer,
 5362                Some(position),
 5363                GetDefinitions { position },
 5364                cx,
 5365            );
 5366            cx.background_spawn(async move {
 5367                Ok(Some(
 5368                    definitions_task
 5369                        .await
 5370                        .into_iter()
 5371                        .flat_map(|(_, definitions)| definitions)
 5372                        .dedup()
 5373                        .collect(),
 5374                ))
 5375            })
 5376        }
 5377    }
 5378
 5379    pub fn declarations(
 5380        &mut self,
 5381        buffer: &Entity<Buffer>,
 5382        position: PointUtf16,
 5383        cx: &mut Context<Self>,
 5384    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5385        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5386            let request = GetDeclarations { position };
 5387            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5388                return Task::ready(Ok(None));
 5389            }
 5390            let request_task = upstream_client.request_lsp(
 5391                project_id,
 5392                None,
 5393                LSP_REQUEST_TIMEOUT,
 5394                cx.background_executor().clone(),
 5395                request.to_proto(project_id, buffer.read(cx)),
 5396            );
 5397            let buffer = buffer.clone();
 5398            cx.spawn(async move |weak_project, cx| {
 5399                let Some(project) = weak_project.upgrade() else {
 5400                    return Ok(None);
 5401                };
 5402                let Some(responses) = request_task.await? else {
 5403                    return Ok(None);
 5404                };
 5405                let actions = join_all(responses.payload.into_iter().map(|response| {
 5406                    GetDeclarations { position }.response_from_proto(
 5407                        response.response,
 5408                        project.clone(),
 5409                        buffer.clone(),
 5410                        cx.clone(),
 5411                    )
 5412                }))
 5413                .await;
 5414
 5415                Ok(Some(
 5416                    actions
 5417                        .into_iter()
 5418                        .collect::<Result<Vec<Vec<_>>>>()?
 5419                        .into_iter()
 5420                        .flatten()
 5421                        .dedup()
 5422                        .collect(),
 5423                ))
 5424            })
 5425        } else {
 5426            let declarations_task = self.request_multiple_lsp_locally(
 5427                buffer,
 5428                Some(position),
 5429                GetDeclarations { position },
 5430                cx,
 5431            );
 5432            cx.background_spawn(async move {
 5433                Ok(Some(
 5434                    declarations_task
 5435                        .await
 5436                        .into_iter()
 5437                        .flat_map(|(_, declarations)| declarations)
 5438                        .dedup()
 5439                        .collect(),
 5440                ))
 5441            })
 5442        }
 5443    }
 5444
 5445    pub fn type_definitions(
 5446        &mut self,
 5447        buffer: &Entity<Buffer>,
 5448        position: PointUtf16,
 5449        cx: &mut Context<Self>,
 5450    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5451        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5452            let request = GetTypeDefinitions { position };
 5453            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5454                return Task::ready(Ok(None));
 5455            }
 5456            let request_task = upstream_client.request_lsp(
 5457                project_id,
 5458                None,
 5459                LSP_REQUEST_TIMEOUT,
 5460                cx.background_executor().clone(),
 5461                request.to_proto(project_id, buffer.read(cx)),
 5462            );
 5463            let buffer = buffer.clone();
 5464            cx.spawn(async move |weak_project, cx| {
 5465                let Some(project) = weak_project.upgrade() else {
 5466                    return Ok(None);
 5467                };
 5468                let Some(responses) = request_task.await? else {
 5469                    return Ok(None);
 5470                };
 5471                let actions = join_all(responses.payload.into_iter().map(|response| {
 5472                    GetTypeDefinitions { position }.response_from_proto(
 5473                        response.response,
 5474                        project.clone(),
 5475                        buffer.clone(),
 5476                        cx.clone(),
 5477                    )
 5478                }))
 5479                .await;
 5480
 5481                Ok(Some(
 5482                    actions
 5483                        .into_iter()
 5484                        .collect::<Result<Vec<Vec<_>>>>()?
 5485                        .into_iter()
 5486                        .flatten()
 5487                        .dedup()
 5488                        .collect(),
 5489                ))
 5490            })
 5491        } else {
 5492            let type_definitions_task = self.request_multiple_lsp_locally(
 5493                buffer,
 5494                Some(position),
 5495                GetTypeDefinitions { position },
 5496                cx,
 5497            );
 5498            cx.background_spawn(async move {
 5499                Ok(Some(
 5500                    type_definitions_task
 5501                        .await
 5502                        .into_iter()
 5503                        .flat_map(|(_, type_definitions)| type_definitions)
 5504                        .dedup()
 5505                        .collect(),
 5506                ))
 5507            })
 5508        }
 5509    }
 5510
 5511    pub fn implementations(
 5512        &mut self,
 5513        buffer: &Entity<Buffer>,
 5514        position: PointUtf16,
 5515        cx: &mut Context<Self>,
 5516    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5517        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5518            let request = GetImplementations { position };
 5519            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5520                return Task::ready(Ok(None));
 5521            }
 5522            let request_task = upstream_client.request_lsp(
 5523                project_id,
 5524                None,
 5525                LSP_REQUEST_TIMEOUT,
 5526                cx.background_executor().clone(),
 5527                request.to_proto(project_id, buffer.read(cx)),
 5528            );
 5529            let buffer = buffer.clone();
 5530            cx.spawn(async move |weak_project, cx| {
 5531                let Some(project) = weak_project.upgrade() else {
 5532                    return Ok(None);
 5533                };
 5534                let Some(responses) = request_task.await? else {
 5535                    return Ok(None);
 5536                };
 5537                let actions = join_all(responses.payload.into_iter().map(|response| {
 5538                    GetImplementations { position }.response_from_proto(
 5539                        response.response,
 5540                        project.clone(),
 5541                        buffer.clone(),
 5542                        cx.clone(),
 5543                    )
 5544                }))
 5545                .await;
 5546
 5547                Ok(Some(
 5548                    actions
 5549                        .into_iter()
 5550                        .collect::<Result<Vec<Vec<_>>>>()?
 5551                        .into_iter()
 5552                        .flatten()
 5553                        .dedup()
 5554                        .collect(),
 5555                ))
 5556            })
 5557        } else {
 5558            let implementations_task = self.request_multiple_lsp_locally(
 5559                buffer,
 5560                Some(position),
 5561                GetImplementations { position },
 5562                cx,
 5563            );
 5564            cx.background_spawn(async move {
 5565                Ok(Some(
 5566                    implementations_task
 5567                        .await
 5568                        .into_iter()
 5569                        .flat_map(|(_, implementations)| implementations)
 5570                        .dedup()
 5571                        .collect(),
 5572                ))
 5573            })
 5574        }
 5575    }
 5576
 5577    pub fn references(
 5578        &mut self,
 5579        buffer: &Entity<Buffer>,
 5580        position: PointUtf16,
 5581        cx: &mut Context<Self>,
 5582    ) -> Task<Result<Option<Vec<Location>>>> {
 5583        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5584            let request = GetReferences { position };
 5585            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5586                return Task::ready(Ok(None));
 5587            }
 5588
 5589            let request_task = upstream_client.request_lsp(
 5590                project_id,
 5591                None,
 5592                LSP_REQUEST_TIMEOUT,
 5593                cx.background_executor().clone(),
 5594                request.to_proto(project_id, buffer.read(cx)),
 5595            );
 5596            let buffer = buffer.clone();
 5597            cx.spawn(async move |weak_project, cx| {
 5598                let Some(project) = weak_project.upgrade() else {
 5599                    return Ok(None);
 5600                };
 5601                let Some(responses) = request_task.await? else {
 5602                    return Ok(None);
 5603                };
 5604
 5605                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5606                    GetReferences { position }.response_from_proto(
 5607                        lsp_response.response,
 5608                        project.clone(),
 5609                        buffer.clone(),
 5610                        cx.clone(),
 5611                    )
 5612                }))
 5613                .await
 5614                .into_iter()
 5615                .collect::<Result<Vec<Vec<_>>>>()?
 5616                .into_iter()
 5617                .flatten()
 5618                .dedup()
 5619                .collect();
 5620                Ok(Some(locations))
 5621            })
 5622        } else {
 5623            let references_task = self.request_multiple_lsp_locally(
 5624                buffer,
 5625                Some(position),
 5626                GetReferences { position },
 5627                cx,
 5628            );
 5629            cx.background_spawn(async move {
 5630                Ok(Some(
 5631                    references_task
 5632                        .await
 5633                        .into_iter()
 5634                        .flat_map(|(_, references)| references)
 5635                        .dedup()
 5636                        .collect(),
 5637                ))
 5638            })
 5639        }
 5640    }
 5641
 5642    pub fn code_actions(
 5643        &mut self,
 5644        buffer: &Entity<Buffer>,
 5645        range: Range<Anchor>,
 5646        kinds: Option<Vec<CodeActionKind>>,
 5647        cx: &mut Context<Self>,
 5648    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5649        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5650            let request = GetCodeActions {
 5651                range: range.clone(),
 5652                kinds: kinds.clone(),
 5653            };
 5654            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5655                return Task::ready(Ok(None));
 5656            }
 5657            let request_task = upstream_client.request_lsp(
 5658                project_id,
 5659                None,
 5660                LSP_REQUEST_TIMEOUT,
 5661                cx.background_executor().clone(),
 5662                request.to_proto(project_id, buffer.read(cx)),
 5663            );
 5664            let buffer = buffer.clone();
 5665            cx.spawn(async move |weak_project, cx| {
 5666                let Some(project) = weak_project.upgrade() else {
 5667                    return Ok(None);
 5668                };
 5669                let Some(responses) = request_task.await? else {
 5670                    return Ok(None);
 5671                };
 5672                let actions = join_all(responses.payload.into_iter().map(|response| {
 5673                    GetCodeActions {
 5674                        range: range.clone(),
 5675                        kinds: kinds.clone(),
 5676                    }
 5677                    .response_from_proto(
 5678                        response.response,
 5679                        project.clone(),
 5680                        buffer.clone(),
 5681                        cx.clone(),
 5682                    )
 5683                }))
 5684                .await;
 5685
 5686                Ok(Some(
 5687                    actions
 5688                        .into_iter()
 5689                        .collect::<Result<Vec<Vec<_>>>>()?
 5690                        .into_iter()
 5691                        .flatten()
 5692                        .collect(),
 5693                ))
 5694            })
 5695        } else {
 5696            let all_actions_task = self.request_multiple_lsp_locally(
 5697                buffer,
 5698                Some(range.start),
 5699                GetCodeActions { range, kinds },
 5700                cx,
 5701            );
 5702            cx.background_spawn(async move {
 5703                Ok(Some(
 5704                    all_actions_task
 5705                        .await
 5706                        .into_iter()
 5707                        .flat_map(|(_, actions)| actions)
 5708                        .collect(),
 5709                ))
 5710            })
 5711        }
 5712    }
 5713
 5714    pub fn code_lens_actions(
 5715        &mut self,
 5716        buffer: &Entity<Buffer>,
 5717        cx: &mut Context<Self>,
 5718    ) -> CodeLensTask {
 5719        let version_queried_for = buffer.read(cx).version();
 5720        let buffer_id = buffer.read(cx).remote_id();
 5721        let existing_servers = self.as_local().map(|local| {
 5722            local
 5723                .buffers_opened_in_servers
 5724                .get(&buffer_id)
 5725                .cloned()
 5726                .unwrap_or_default()
 5727        });
 5728
 5729        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 5730            if let Some(cached_lens) = &lsp_data.code_lens {
 5731                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 5732                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 5733                        existing_servers != cached_lens.lens.keys().copied().collect()
 5734                    });
 5735                    if !has_different_servers {
 5736                        return Task::ready(Ok(Some(
 5737                            cached_lens.lens.values().flatten().cloned().collect(),
 5738                        )))
 5739                        .shared();
 5740                    }
 5741                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 5742                    if !version_queried_for.changed_since(updating_for) {
 5743                        return running_update.clone();
 5744                    }
 5745                }
 5746            }
 5747        }
 5748
 5749        let lens_lsp_data = self
 5750            .latest_lsp_data(buffer, cx)
 5751            .code_lens
 5752            .get_or_insert_default();
 5753        let buffer = buffer.clone();
 5754        let query_version_queried_for = version_queried_for.clone();
 5755        let new_task = cx
 5756            .spawn(async move |lsp_store, cx| {
 5757                cx.background_executor()
 5758                    .timer(Duration::from_millis(30))
 5759                    .await;
 5760                let fetched_lens = lsp_store
 5761                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 5762                    .map_err(Arc::new)?
 5763                    .await
 5764                    .context("fetching code lens")
 5765                    .map_err(Arc::new);
 5766                let fetched_lens = match fetched_lens {
 5767                    Ok(fetched_lens) => fetched_lens,
 5768                    Err(e) => {
 5769                        lsp_store
 5770                            .update(cx, |lsp_store, _| {
 5771                                if let Some(lens_lsp_data) = lsp_store
 5772                                    .lsp_data
 5773                                    .get_mut(&buffer_id)
 5774                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 5775                                {
 5776                                    lens_lsp_data.update = None;
 5777                                }
 5778                            })
 5779                            .ok();
 5780                        return Err(e);
 5781                    }
 5782                };
 5783
 5784                lsp_store
 5785                    .update(cx, |lsp_store, _| {
 5786                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 5787                        let code_lens = lsp_data.code_lens.as_mut()?;
 5788                        if let Some(fetched_lens) = fetched_lens {
 5789                            if lsp_data.buffer_version == query_version_queried_for {
 5790                                code_lens.lens.extend(fetched_lens);
 5791                            } else if !lsp_data
 5792                                .buffer_version
 5793                                .changed_since(&query_version_queried_for)
 5794                            {
 5795                                lsp_data.buffer_version = query_version_queried_for;
 5796                                code_lens.lens = fetched_lens;
 5797                            }
 5798                        }
 5799                        code_lens.update = None;
 5800                        Some(code_lens.lens.values().flatten().cloned().collect())
 5801                    })
 5802                    .map_err(Arc::new)
 5803            })
 5804            .shared();
 5805        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 5806        new_task
 5807    }
 5808
 5809    fn fetch_code_lens(
 5810        &mut self,
 5811        buffer: &Entity<Buffer>,
 5812        cx: &mut Context<Self>,
 5813    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 5814        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5815            let request = GetCodeLens;
 5816            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5817                return Task::ready(Ok(None));
 5818            }
 5819            let request_task = upstream_client.request_lsp(
 5820                project_id,
 5821                None,
 5822                LSP_REQUEST_TIMEOUT,
 5823                cx.background_executor().clone(),
 5824                request.to_proto(project_id, buffer.read(cx)),
 5825            );
 5826            let buffer = buffer.clone();
 5827            cx.spawn(async move |weak_lsp_store, cx| {
 5828                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5829                    return Ok(None);
 5830                };
 5831                let Some(responses) = request_task.await? else {
 5832                    return Ok(None);
 5833                };
 5834
 5835                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 5836                    let lsp_store = lsp_store.clone();
 5837                    let buffer = buffer.clone();
 5838                    let cx = cx.clone();
 5839                    async move {
 5840                        (
 5841                            LanguageServerId::from_proto(response.server_id),
 5842                            GetCodeLens
 5843                                .response_from_proto(response.response, lsp_store, buffer, cx)
 5844                                .await,
 5845                        )
 5846                    }
 5847                }))
 5848                .await;
 5849
 5850                let mut has_errors = false;
 5851                let code_lens_actions = code_lens_actions
 5852                    .into_iter()
 5853                    .filter_map(|(server_id, code_lens)| match code_lens {
 5854                        Ok(code_lens) => Some((server_id, code_lens)),
 5855                        Err(e) => {
 5856                            has_errors = true;
 5857                            log::error!("{e:#}");
 5858                            None
 5859                        }
 5860                    })
 5861                    .collect::<HashMap<_, _>>();
 5862                anyhow::ensure!(
 5863                    !has_errors || !code_lens_actions.is_empty(),
 5864                    "Failed to fetch code lens"
 5865                );
 5866                Ok(Some(code_lens_actions))
 5867            })
 5868        } else {
 5869            let code_lens_actions_task =
 5870                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 5871            cx.background_spawn(async move {
 5872                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 5873            })
 5874        }
 5875    }
 5876
 5877    #[inline(never)]
 5878    pub fn completions(
 5879        &self,
 5880        buffer: &Entity<Buffer>,
 5881        position: PointUtf16,
 5882        context: CompletionContext,
 5883        cx: &mut Context<Self>,
 5884    ) -> Task<Result<Vec<CompletionResponse>>> {
 5885        let language_registry = self.languages.clone();
 5886
 5887        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5888            let request = GetCompletions { position, context };
 5889            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5890                return Task::ready(Ok(Vec::new()));
 5891            }
 5892            let task = self.send_lsp_proto_request(
 5893                buffer.clone(),
 5894                upstream_client,
 5895                project_id,
 5896                request,
 5897                cx,
 5898            );
 5899            let language = buffer.read(cx).language().cloned();
 5900
 5901            // In the future, we should provide project guests with the names of LSP adapters,
 5902            // so that they can use the correct LSP adapter when computing labels. For now,
 5903            // guests just use the first LSP adapter associated with the buffer's language.
 5904            let lsp_adapter = language.as_ref().and_then(|language| {
 5905                language_registry
 5906                    .lsp_adapters(&language.name())
 5907                    .first()
 5908                    .cloned()
 5909            });
 5910
 5911            cx.foreground_executor().spawn(async move {
 5912                let completion_response = task.await?;
 5913                let completions = populate_labels_for_completions(
 5914                    completion_response.completions,
 5915                    language,
 5916                    lsp_adapter,
 5917                )
 5918                .await;
 5919                Ok(vec![CompletionResponse {
 5920                    completions,
 5921                    display_options: CompletionDisplayOptions::default(),
 5922                    is_incomplete: completion_response.is_incomplete,
 5923                }])
 5924            })
 5925        } else if let Some(local) = self.as_local() {
 5926            let snapshot = buffer.read(cx).snapshot();
 5927            let offset = position.to_offset(&snapshot);
 5928            let scope = snapshot.language_scope_at(offset);
 5929            let language = snapshot.language().cloned();
 5930            let completion_settings = language_settings(
 5931                language.as_ref().map(|language| language.name()),
 5932                buffer.read(cx).file(),
 5933                cx,
 5934            )
 5935            .completions
 5936            .clone();
 5937            if !completion_settings.lsp {
 5938                return Task::ready(Ok(Vec::new()));
 5939            }
 5940
 5941            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 5942                local
 5943                    .language_servers_for_buffer(buffer, cx)
 5944                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 5945                    .filter(|(adapter, _)| {
 5946                        scope
 5947                            .as_ref()
 5948                            .map(|scope| scope.language_allowed(&adapter.name))
 5949                            .unwrap_or(true)
 5950                    })
 5951                    .map(|(_, server)| server.server_id())
 5952                    .collect()
 5953            });
 5954
 5955            let buffer = buffer.clone();
 5956            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 5957            let lsp_timeout = if lsp_timeout > 0 {
 5958                Some(Duration::from_millis(lsp_timeout))
 5959            } else {
 5960                None
 5961            };
 5962            cx.spawn(async move |this,  cx| {
 5963                let mut tasks = Vec::with_capacity(server_ids.len());
 5964                this.update(cx, |lsp_store, cx| {
 5965                    for server_id in server_ids {
 5966                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 5967                        let lsp_timeout = lsp_timeout
 5968                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 5969                        let mut timeout = cx.background_spawn(async move {
 5970                            match lsp_timeout {
 5971                                Some(lsp_timeout) => {
 5972                                    lsp_timeout.await;
 5973                                    true
 5974                                },
 5975                                None => false,
 5976                            }
 5977                        }).fuse();
 5978                        let mut lsp_request = lsp_store.request_lsp(
 5979                            buffer.clone(),
 5980                            LanguageServerToQuery::Other(server_id),
 5981                            GetCompletions {
 5982                                position,
 5983                                context: context.clone(),
 5984                            },
 5985                            cx,
 5986                        ).fuse();
 5987                        let new_task = cx.background_spawn(async move {
 5988                            select_biased! {
 5989                                response = lsp_request => anyhow::Ok(Some(response?)),
 5990                                timeout_happened = timeout => {
 5991                                    if timeout_happened {
 5992                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 5993                                        Ok(None)
 5994                                    } else {
 5995                                        let completions = lsp_request.await?;
 5996                                        Ok(Some(completions))
 5997                                    }
 5998                                },
 5999                            }
 6000                        });
 6001                        tasks.push((lsp_adapter, new_task));
 6002                    }
 6003                })?;
 6004
 6005                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6006                    let completion_response = task.await.ok()??;
 6007                    let completions = populate_labels_for_completions(
 6008                            completion_response.completions,
 6009                            language.clone(),
 6010                            lsp_adapter,
 6011                        )
 6012                        .await;
 6013                    Some(CompletionResponse {
 6014                        completions,
 6015                        display_options: CompletionDisplayOptions::default(),
 6016                        is_incomplete: completion_response.is_incomplete,
 6017                    })
 6018                });
 6019
 6020                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6021
 6022                Ok(responses.into_iter().flatten().collect())
 6023            })
 6024        } else {
 6025            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6026        }
 6027    }
 6028
 6029    pub fn resolve_completions(
 6030        &self,
 6031        buffer: Entity<Buffer>,
 6032        completion_indices: Vec<usize>,
 6033        completions: Rc<RefCell<Box<[Completion]>>>,
 6034        cx: &mut Context<Self>,
 6035    ) -> Task<Result<bool>> {
 6036        let client = self.upstream_client();
 6037        let buffer_id = buffer.read(cx).remote_id();
 6038        let buffer_snapshot = buffer.read(cx).snapshot();
 6039
 6040        if !self.check_if_capable_for_proto_request(
 6041            &buffer,
 6042            GetCompletions::can_resolve_completions,
 6043            cx,
 6044        ) {
 6045            return Task::ready(Ok(false));
 6046        }
 6047        cx.spawn(async move |lsp_store, cx| {
 6048            let mut did_resolve = false;
 6049            if let Some((client, project_id)) = client {
 6050                for completion_index in completion_indices {
 6051                    let server_id = {
 6052                        let completion = &completions.borrow()[completion_index];
 6053                        completion.source.server_id()
 6054                    };
 6055                    if let Some(server_id) = server_id {
 6056                        if Self::resolve_completion_remote(
 6057                            project_id,
 6058                            server_id,
 6059                            buffer_id,
 6060                            completions.clone(),
 6061                            completion_index,
 6062                            client.clone(),
 6063                        )
 6064                        .await
 6065                        .log_err()
 6066                        .is_some()
 6067                        {
 6068                            did_resolve = true;
 6069                        }
 6070                    } else {
 6071                        resolve_word_completion(
 6072                            &buffer_snapshot,
 6073                            &mut completions.borrow_mut()[completion_index],
 6074                        );
 6075                    }
 6076                }
 6077            } else {
 6078                for completion_index in completion_indices {
 6079                    let server_id = {
 6080                        let completion = &completions.borrow()[completion_index];
 6081                        completion.source.server_id()
 6082                    };
 6083                    if let Some(server_id) = server_id {
 6084                        let server_and_adapter = lsp_store
 6085                            .read_with(cx, |lsp_store, _| {
 6086                                let server = lsp_store.language_server_for_id(server_id)?;
 6087                                let adapter =
 6088                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6089                                Some((server, adapter))
 6090                            })
 6091                            .ok()
 6092                            .flatten();
 6093                        let Some((server, adapter)) = server_and_adapter else {
 6094                            continue;
 6095                        };
 6096
 6097                        let resolved = Self::resolve_completion_local(
 6098                            server,
 6099                            completions.clone(),
 6100                            completion_index,
 6101                        )
 6102                        .await
 6103                        .log_err()
 6104                        .is_some();
 6105                        if resolved {
 6106                            Self::regenerate_completion_labels(
 6107                                adapter,
 6108                                &buffer_snapshot,
 6109                                completions.clone(),
 6110                                completion_index,
 6111                            )
 6112                            .await
 6113                            .log_err();
 6114                            did_resolve = true;
 6115                        }
 6116                    } else {
 6117                        resolve_word_completion(
 6118                            &buffer_snapshot,
 6119                            &mut completions.borrow_mut()[completion_index],
 6120                        );
 6121                    }
 6122                }
 6123            }
 6124
 6125            Ok(did_resolve)
 6126        })
 6127    }
 6128
 6129    async fn resolve_completion_local(
 6130        server: Arc<lsp::LanguageServer>,
 6131        completions: Rc<RefCell<Box<[Completion]>>>,
 6132        completion_index: usize,
 6133    ) -> Result<()> {
 6134        let server_id = server.server_id();
 6135        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6136            return Ok(());
 6137        }
 6138
 6139        let request = {
 6140            let completion = &completions.borrow()[completion_index];
 6141            match &completion.source {
 6142                CompletionSource::Lsp {
 6143                    lsp_completion,
 6144                    resolved,
 6145                    server_id: completion_server_id,
 6146                    ..
 6147                } => {
 6148                    if *resolved {
 6149                        return Ok(());
 6150                    }
 6151                    anyhow::ensure!(
 6152                        server_id == *completion_server_id,
 6153                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6154                    );
 6155                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6156                }
 6157                CompletionSource::BufferWord { .. }
 6158                | CompletionSource::Dap { .. }
 6159                | CompletionSource::Custom => {
 6160                    return Ok(());
 6161                }
 6162            }
 6163        };
 6164        let resolved_completion = request
 6165            .await
 6166            .into_response()
 6167            .context("resolve completion")?;
 6168
 6169        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6170        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6171
 6172        let mut completions = completions.borrow_mut();
 6173        let completion = &mut completions[completion_index];
 6174        if let CompletionSource::Lsp {
 6175            lsp_completion,
 6176            resolved,
 6177            server_id: completion_server_id,
 6178            ..
 6179        } = &mut completion.source
 6180        {
 6181            if *resolved {
 6182                return Ok(());
 6183            }
 6184            anyhow::ensure!(
 6185                server_id == *completion_server_id,
 6186                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6187            );
 6188            *lsp_completion = Box::new(resolved_completion);
 6189            *resolved = true;
 6190        }
 6191        Ok(())
 6192    }
 6193
 6194    async fn regenerate_completion_labels(
 6195        adapter: Arc<CachedLspAdapter>,
 6196        snapshot: &BufferSnapshot,
 6197        completions: Rc<RefCell<Box<[Completion]>>>,
 6198        completion_index: usize,
 6199    ) -> Result<()> {
 6200        let completion_item = completions.borrow()[completion_index]
 6201            .source
 6202            .lsp_completion(true)
 6203            .map(Cow::into_owned);
 6204        if let Some(lsp_documentation) = completion_item
 6205            .as_ref()
 6206            .and_then(|completion_item| completion_item.documentation.clone())
 6207        {
 6208            let mut completions = completions.borrow_mut();
 6209            let completion = &mut completions[completion_index];
 6210            completion.documentation = Some(lsp_documentation.into());
 6211        } else {
 6212            let mut completions = completions.borrow_mut();
 6213            let completion = &mut completions[completion_index];
 6214            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6215        }
 6216
 6217        let mut new_label = match completion_item {
 6218            Some(completion_item) => {
 6219                // NB: Zed does not have `details` inside the completion resolve capabilities, but certain language servers violate the spec and do not return `details` immediately, e.g. https://github.com/yioneko/vtsls/issues/213
 6220                // So we have to update the label here anyway...
 6221                let language = snapshot.language();
 6222                match language {
 6223                    Some(language) => {
 6224                        adapter
 6225                            .labels_for_completions(
 6226                                std::slice::from_ref(&completion_item),
 6227                                language,
 6228                            )
 6229                            .await?
 6230                    }
 6231                    None => Vec::new(),
 6232                }
 6233                .pop()
 6234                .flatten()
 6235                .unwrap_or_else(|| {
 6236                    CodeLabel::fallback_for_completion(
 6237                        &completion_item,
 6238                        language.map(|language| language.as_ref()),
 6239                    )
 6240                })
 6241            }
 6242            None => CodeLabel::plain(
 6243                completions.borrow()[completion_index].new_text.clone(),
 6244                None,
 6245            ),
 6246        };
 6247        ensure_uniform_list_compatible_label(&mut new_label);
 6248
 6249        let mut completions = completions.borrow_mut();
 6250        let completion = &mut completions[completion_index];
 6251        if completion.label.filter_text() == new_label.filter_text() {
 6252            completion.label = new_label;
 6253        } else {
 6254            log::error!(
 6255                "Resolved completion changed display label from {} to {}. \
 6256                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6257                completion.label.text(),
 6258                new_label.text(),
 6259                completion.label.filter_text(),
 6260                new_label.filter_text()
 6261            );
 6262        }
 6263
 6264        Ok(())
 6265    }
 6266
 6267    async fn resolve_completion_remote(
 6268        project_id: u64,
 6269        server_id: LanguageServerId,
 6270        buffer_id: BufferId,
 6271        completions: Rc<RefCell<Box<[Completion]>>>,
 6272        completion_index: usize,
 6273        client: AnyProtoClient,
 6274    ) -> Result<()> {
 6275        let lsp_completion = {
 6276            let completion = &completions.borrow()[completion_index];
 6277            match &completion.source {
 6278                CompletionSource::Lsp {
 6279                    lsp_completion,
 6280                    resolved,
 6281                    server_id: completion_server_id,
 6282                    ..
 6283                } => {
 6284                    anyhow::ensure!(
 6285                        server_id == *completion_server_id,
 6286                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6287                    );
 6288                    if *resolved {
 6289                        return Ok(());
 6290                    }
 6291                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6292                }
 6293                CompletionSource::Custom
 6294                | CompletionSource::Dap { .. }
 6295                | CompletionSource::BufferWord { .. } => {
 6296                    return Ok(());
 6297                }
 6298            }
 6299        };
 6300        let request = proto::ResolveCompletionDocumentation {
 6301            project_id,
 6302            language_server_id: server_id.0 as u64,
 6303            lsp_completion,
 6304            buffer_id: buffer_id.into(),
 6305        };
 6306
 6307        let response = client
 6308            .request(request)
 6309            .await
 6310            .context("completion documentation resolve proto request")?;
 6311        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6312
 6313        let documentation = if response.documentation.is_empty() {
 6314            CompletionDocumentation::Undocumented
 6315        } else if response.documentation_is_markdown {
 6316            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6317        } else if response.documentation.lines().count() <= 1 {
 6318            CompletionDocumentation::SingleLine(response.documentation.into())
 6319        } else {
 6320            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6321        };
 6322
 6323        let mut completions = completions.borrow_mut();
 6324        let completion = &mut completions[completion_index];
 6325        completion.documentation = Some(documentation);
 6326        if let CompletionSource::Lsp {
 6327            insert_range,
 6328            lsp_completion,
 6329            resolved,
 6330            server_id: completion_server_id,
 6331            lsp_defaults: _,
 6332        } = &mut completion.source
 6333        {
 6334            let completion_insert_range = response
 6335                .old_insert_start
 6336                .and_then(deserialize_anchor)
 6337                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6338            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6339
 6340            if *resolved {
 6341                return Ok(());
 6342            }
 6343            anyhow::ensure!(
 6344                server_id == *completion_server_id,
 6345                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6346            );
 6347            *lsp_completion = Box::new(resolved_lsp_completion);
 6348            *resolved = true;
 6349        }
 6350
 6351        let replace_range = response
 6352            .old_replace_start
 6353            .and_then(deserialize_anchor)
 6354            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6355        if let Some((old_replace_start, old_replace_end)) = replace_range
 6356            && !response.new_text.is_empty()
 6357        {
 6358            completion.new_text = response.new_text;
 6359            completion.replace_range = old_replace_start..old_replace_end;
 6360        }
 6361
 6362        Ok(())
 6363    }
 6364
 6365    pub fn apply_additional_edits_for_completion(
 6366        &self,
 6367        buffer_handle: Entity<Buffer>,
 6368        completions: Rc<RefCell<Box<[Completion]>>>,
 6369        completion_index: usize,
 6370        push_to_history: bool,
 6371        cx: &mut Context<Self>,
 6372    ) -> Task<Result<Option<Transaction>>> {
 6373        if let Some((client, project_id)) = self.upstream_client() {
 6374            let buffer = buffer_handle.read(cx);
 6375            let buffer_id = buffer.remote_id();
 6376            cx.spawn(async move |_, cx| {
 6377                let request = {
 6378                    let completion = completions.borrow()[completion_index].clone();
 6379                    proto::ApplyCompletionAdditionalEdits {
 6380                        project_id,
 6381                        buffer_id: buffer_id.into(),
 6382                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6383                            replace_range: completion.replace_range,
 6384                            new_text: completion.new_text,
 6385                            source: completion.source,
 6386                        })),
 6387                    }
 6388                };
 6389
 6390                if let Some(transaction) = client.request(request).await?.transaction {
 6391                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6392                    buffer_handle
 6393                        .update(cx, |buffer, _| {
 6394                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6395                        })?
 6396                        .await?;
 6397                    if push_to_history {
 6398                        buffer_handle.update(cx, |buffer, _| {
 6399                            buffer.push_transaction(transaction.clone(), Instant::now());
 6400                            buffer.finalize_last_transaction();
 6401                        })?;
 6402                    }
 6403                    Ok(Some(transaction))
 6404                } else {
 6405                    Ok(None)
 6406                }
 6407            })
 6408        } else {
 6409            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6410                let completion = &completions.borrow()[completion_index];
 6411                let server_id = completion.source.server_id()?;
 6412                Some(
 6413                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6414                        .1
 6415                        .clone(),
 6416                )
 6417            }) else {
 6418                return Task::ready(Ok(None));
 6419            };
 6420
 6421            cx.spawn(async move |this, cx| {
 6422                Self::resolve_completion_local(
 6423                    server.clone(),
 6424                    completions.clone(),
 6425                    completion_index,
 6426                )
 6427                .await
 6428                .context("resolving completion")?;
 6429                let completion = completions.borrow()[completion_index].clone();
 6430                let additional_text_edits = completion
 6431                    .source
 6432                    .lsp_completion(true)
 6433                    .as_ref()
 6434                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6435                if let Some(edits) = additional_text_edits {
 6436                    let edits = this
 6437                        .update(cx, |this, cx| {
 6438                            this.as_local_mut().unwrap().edits_from_lsp(
 6439                                &buffer_handle,
 6440                                edits,
 6441                                server.server_id(),
 6442                                None,
 6443                                cx,
 6444                            )
 6445                        })?
 6446                        .await?;
 6447
 6448                    buffer_handle.update(cx, |buffer, cx| {
 6449                        buffer.finalize_last_transaction();
 6450                        buffer.start_transaction();
 6451
 6452                        for (range, text) in edits {
 6453                            let primary = &completion.replace_range;
 6454
 6455                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6456                            // and the primary completion is just an insertion (empty range), then this is likely
 6457                            // an auto-import scenario and should not be considered overlapping
 6458                            // https://github.com/zed-industries/zed/issues/26136
 6459                            let is_file_start_auto_import = {
 6460                                let snapshot = buffer.snapshot();
 6461                                let primary_start_point = primary.start.to_point(&snapshot);
 6462                                let range_start_point = range.start.to_point(&snapshot);
 6463
 6464                                let result = primary_start_point.row == 0
 6465                                    && primary_start_point.column == 0
 6466                                    && range_start_point.row == 0
 6467                                    && range_start_point.column == 0;
 6468
 6469                                result
 6470                            };
 6471
 6472                            let has_overlap = if is_file_start_auto_import {
 6473                                false
 6474                            } else {
 6475                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6476                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6477                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6478                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6479                                let result = start_within || end_within;
 6480                                result
 6481                            };
 6482
 6483                            //Skip additional edits which overlap with the primary completion edit
 6484                            //https://github.com/zed-industries/zed/pull/1871
 6485                            if !has_overlap {
 6486                                buffer.edit([(range, text)], None, cx);
 6487                            }
 6488                        }
 6489
 6490                        let transaction = if buffer.end_transaction(cx).is_some() {
 6491                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6492                            if !push_to_history {
 6493                                buffer.forget_transaction(transaction.id);
 6494                            }
 6495                            Some(transaction)
 6496                        } else {
 6497                            None
 6498                        };
 6499                        Ok(transaction)
 6500                    })?
 6501                } else {
 6502                    Ok(None)
 6503                }
 6504            })
 6505        }
 6506    }
 6507
 6508    pub fn pull_diagnostics(
 6509        &mut self,
 6510        buffer: Entity<Buffer>,
 6511        cx: &mut Context<Self>,
 6512    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6513        let buffer_id = buffer.read(cx).remote_id();
 6514
 6515        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6516            let mut suitable_capabilities = None;
 6517            // Are we capable for proto request?
 6518            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6519                &buffer,
 6520                |capabilities| {
 6521                    if let Some(caps) = &capabilities.diagnostic_provider {
 6522                        suitable_capabilities = Some(caps.clone());
 6523                        true
 6524                    } else {
 6525                        false
 6526                    }
 6527                },
 6528                cx,
 6529            );
 6530            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6531            let Some(dynamic_caps) = suitable_capabilities else {
 6532                return Task::ready(Ok(None));
 6533            };
 6534            assert!(any_server_has_diagnostics_provider);
 6535
 6536            let request = GetDocumentDiagnostics {
 6537                previous_result_id: None,
 6538                dynamic_caps,
 6539            };
 6540            let request_task = client.request_lsp(
 6541                upstream_project_id,
 6542                None,
 6543                LSP_REQUEST_TIMEOUT,
 6544                cx.background_executor().clone(),
 6545                request.to_proto(upstream_project_id, buffer.read(cx)),
 6546            );
 6547            cx.background_spawn(async move {
 6548                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6549                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6550                // Do not attempt to further process the dummy responses here.
 6551                let _response = request_task.await?;
 6552                Ok(None)
 6553            })
 6554        } else {
 6555            let servers = buffer.update(cx, |buffer, cx| {
 6556                self.language_servers_for_local_buffer(buffer, cx)
 6557                    .map(|(_, server)| server.clone())
 6558                    .collect::<Vec<_>>()
 6559            });
 6560
 6561            let pull_diagnostics = servers
 6562                .into_iter()
 6563                .flat_map(|server| {
 6564                    let result = maybe!({
 6565                        let local = self.as_local()?;
 6566                        let server_id = server.server_id();
 6567                        let providers_with_identifiers = local
 6568                            .language_server_dynamic_registrations
 6569                            .get(&server_id)
 6570                            .into_iter()
 6571                            .flat_map(|registrations| registrations.diagnostics.values().cloned())
 6572                            .collect::<Vec<_>>();
 6573                        Some(
 6574                            providers_with_identifiers
 6575                                .into_iter()
 6576                                .map(|dynamic_caps| {
 6577                                    let result_id = self.result_id(server_id, buffer_id, cx);
 6578                                    self.request_lsp(
 6579                                        buffer.clone(),
 6580                                        LanguageServerToQuery::Other(server_id),
 6581                                        GetDocumentDiagnostics {
 6582                                            previous_result_id: result_id,
 6583                                            dynamic_caps,
 6584                                        },
 6585                                        cx,
 6586                                    )
 6587                                })
 6588                                .collect::<Vec<_>>(),
 6589                        )
 6590                    });
 6591
 6592                    result.unwrap_or_default()
 6593                })
 6594                .collect::<Vec<_>>();
 6595
 6596            cx.background_spawn(async move {
 6597                let mut responses = Vec::new();
 6598                for diagnostics in join_all(pull_diagnostics).await {
 6599                    responses.extend(diagnostics?);
 6600                }
 6601                Ok(Some(responses))
 6602            })
 6603        }
 6604    }
 6605
 6606    pub fn applicable_inlay_chunks(
 6607        &mut self,
 6608        buffer: &Entity<Buffer>,
 6609        ranges: &[Range<text::Anchor>],
 6610        cx: &mut Context<Self>,
 6611    ) -> Vec<Range<BufferRow>> {
 6612        self.latest_lsp_data(buffer, cx)
 6613            .inlay_hints
 6614            .applicable_chunks(ranges)
 6615            .map(|chunk| chunk.start..chunk.end)
 6616            .collect()
 6617    }
 6618
 6619    pub fn invalidate_inlay_hints<'a>(
 6620        &'a mut self,
 6621        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6622    ) {
 6623        for buffer_id in for_buffers {
 6624            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6625                lsp_data.inlay_hints.clear();
 6626            }
 6627        }
 6628    }
 6629
 6630    pub fn inlay_hints(
 6631        &mut self,
 6632        invalidate: InvalidationStrategy,
 6633        buffer: Entity<Buffer>,
 6634        ranges: Vec<Range<text::Anchor>>,
 6635        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6636        cx: &mut Context<Self>,
 6637    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6638        let buffer_snapshot = buffer.read(cx).snapshot();
 6639        let next_hint_id = self.next_hint_id.clone();
 6640        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6641        let mut lsp_refresh_requested = false;
 6642        let for_server = if let InvalidationStrategy::RefreshRequested(server_id) = invalidate {
 6643            lsp_data.inlay_hints.invalidate_for_server(server_id);
 6644            lsp_refresh_requested = true;
 6645            Some(server_id)
 6646        } else {
 6647            None
 6648        };
 6649        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6650        let known_chunks = known_chunks
 6651            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6652            .map(|(_, known_chunks)| known_chunks)
 6653            .unwrap_or_default();
 6654
 6655        let mut hint_fetch_tasks = Vec::new();
 6656        let mut cached_inlay_hints = None;
 6657        let mut ranges_to_query = None;
 6658        let applicable_chunks = existing_inlay_hints
 6659            .applicable_chunks(ranges.as_slice())
 6660            .filter(|chunk| !known_chunks.contains(&(chunk.start..chunk.end)))
 6661            .collect::<Vec<_>>();
 6662        if applicable_chunks.is_empty() {
 6663            return HashMap::default();
 6664        }
 6665
 6666        let last_chunk_number = existing_inlay_hints.buffer_chunks_len() - 1;
 6667
 6668        for row_chunk in applicable_chunks {
 6669            match (
 6670                existing_inlay_hints
 6671                    .cached_hints(&row_chunk)
 6672                    .filter(|_| !lsp_refresh_requested)
 6673                    .cloned(),
 6674                existing_inlay_hints
 6675                    .fetched_hints(&row_chunk)
 6676                    .as_ref()
 6677                    .filter(|_| !lsp_refresh_requested)
 6678                    .cloned(),
 6679            ) {
 6680                (None, None) => {
 6681                    let end = if last_chunk_number == row_chunk.id {
 6682                        Point::new(row_chunk.end, buffer_snapshot.line_len(row_chunk.end))
 6683                    } else {
 6684                        Point::new(row_chunk.end, 0)
 6685                    };
 6686                    ranges_to_query.get_or_insert_with(Vec::new).push((
 6687                        row_chunk,
 6688                        buffer_snapshot.anchor_before(Point::new(row_chunk.start, 0))
 6689                            ..buffer_snapshot.anchor_after(end),
 6690                    ));
 6691                }
 6692                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 6693                (Some(cached_hints), None) => {
 6694                    for (server_id, cached_hints) in cached_hints {
 6695                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6696                            cached_inlay_hints
 6697                                .get_or_insert_with(HashMap::default)
 6698                                .entry(row_chunk.start..row_chunk.end)
 6699                                .or_insert_with(HashMap::default)
 6700                                .entry(server_id)
 6701                                .or_insert_with(Vec::new)
 6702                                .extend(cached_hints);
 6703                        }
 6704                    }
 6705                }
 6706                (Some(cached_hints), Some(fetched_hints)) => {
 6707                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 6708                    for (server_id, cached_hints) in cached_hints {
 6709                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6710                            cached_inlay_hints
 6711                                .get_or_insert_with(HashMap::default)
 6712                                .entry(row_chunk.start..row_chunk.end)
 6713                                .or_insert_with(HashMap::default)
 6714                                .entry(server_id)
 6715                                .or_insert_with(Vec::new)
 6716                                .extend(cached_hints);
 6717                        }
 6718                    }
 6719                }
 6720            }
 6721        }
 6722
 6723        if hint_fetch_tasks.is_empty()
 6724            && ranges_to_query
 6725                .as_ref()
 6726                .is_none_or(|ranges| ranges.is_empty())
 6727            && let Some(cached_inlay_hints) = cached_inlay_hints
 6728        {
 6729            cached_inlay_hints
 6730                .into_iter()
 6731                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 6732                .collect()
 6733        } else {
 6734            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 6735                let next_hint_id = next_hint_id.clone();
 6736                let buffer = buffer.clone();
 6737                let new_inlay_hints = cx
 6738                    .spawn(async move |lsp_store, cx| {
 6739                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 6740                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 6741                        })?;
 6742                        new_fetch_task
 6743                            .await
 6744                            .and_then(|new_hints_by_server| {
 6745                                lsp_store.update(cx, |lsp_store, cx| {
 6746                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 6747                                    let update_cache = !lsp_data
 6748                                        .buffer_version
 6749                                        .changed_since(&buffer.read(cx).version());
 6750                                    if new_hints_by_server.is_empty() {
 6751                                        if update_cache {
 6752                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 6753                                        }
 6754                                        HashMap::default()
 6755                                    } else {
 6756                                        new_hints_by_server
 6757                                            .into_iter()
 6758                                            .map(|(server_id, new_hints)| {
 6759                                                let new_hints = new_hints
 6760                                                    .into_iter()
 6761                                                    .map(|new_hint| {
 6762                                                        (
 6763                                                            InlayId::Hint(next_hint_id.fetch_add(
 6764                                                                1,
 6765                                                                atomic::Ordering::AcqRel,
 6766                                                            )),
 6767                                                            new_hint,
 6768                                                        )
 6769                                                    })
 6770                                                    .collect::<Vec<_>>();
 6771                                                if update_cache {
 6772                                                    lsp_data.inlay_hints.insert_new_hints(
 6773                                                        chunk,
 6774                                                        server_id,
 6775                                                        new_hints.clone(),
 6776                                                    );
 6777                                                }
 6778                                                (server_id, new_hints)
 6779                                            })
 6780                                            .collect()
 6781                                    }
 6782                                })
 6783                            })
 6784                            .map_err(Arc::new)
 6785                    })
 6786                    .shared();
 6787
 6788                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 6789                *fetch_task = Some(new_inlay_hints.clone());
 6790                hint_fetch_tasks.push((chunk, new_inlay_hints));
 6791            }
 6792
 6793            cached_inlay_hints
 6794                .unwrap_or_default()
 6795                .into_iter()
 6796                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 6797                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 6798                    (
 6799                        chunk.start..chunk.end,
 6800                        cx.spawn(async move |_, _| {
 6801                            hints_fetch.await.map_err(|e| {
 6802                                if e.error_code() != ErrorCode::Internal {
 6803                                    anyhow!(e.error_code())
 6804                                } else {
 6805                                    anyhow!("{e:#}")
 6806                                }
 6807                            })
 6808                        }),
 6809                    )
 6810                }))
 6811                .collect()
 6812        }
 6813    }
 6814
 6815    fn fetch_inlay_hints(
 6816        &mut self,
 6817        for_server: Option<LanguageServerId>,
 6818        buffer: &Entity<Buffer>,
 6819        range: Range<Anchor>,
 6820        cx: &mut Context<Self>,
 6821    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 6822        let request = InlayHints {
 6823            range: range.clone(),
 6824        };
 6825        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6826            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6827                return Task::ready(Ok(HashMap::default()));
 6828            }
 6829            let request_task = upstream_client.request_lsp(
 6830                project_id,
 6831                for_server.map(|id| id.to_proto()),
 6832                LSP_REQUEST_TIMEOUT,
 6833                cx.background_executor().clone(),
 6834                request.to_proto(project_id, buffer.read(cx)),
 6835            );
 6836            let buffer = buffer.clone();
 6837            cx.spawn(async move |weak_lsp_store, cx| {
 6838                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6839                    return Ok(HashMap::default());
 6840                };
 6841                let Some(responses) = request_task.await? else {
 6842                    return Ok(HashMap::default());
 6843                };
 6844
 6845                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 6846                    let lsp_store = lsp_store.clone();
 6847                    let buffer = buffer.clone();
 6848                    let cx = cx.clone();
 6849                    let request = request.clone();
 6850                    async move {
 6851                        (
 6852                            LanguageServerId::from_proto(response.server_id),
 6853                            request
 6854                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6855                                .await,
 6856                        )
 6857                    }
 6858                }))
 6859                .await;
 6860
 6861                let mut has_errors = false;
 6862                let inlay_hints = inlay_hints
 6863                    .into_iter()
 6864                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 6865                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 6866                        Err(e) => {
 6867                            has_errors = true;
 6868                            log::error!("{e:#}");
 6869                            None
 6870                        }
 6871                    })
 6872                    .collect::<HashMap<_, _>>();
 6873                anyhow::ensure!(
 6874                    !has_errors || !inlay_hints.is_empty(),
 6875                    "Failed to fetch inlay hints"
 6876                );
 6877                Ok(inlay_hints)
 6878            })
 6879        } else {
 6880            let inlay_hints_task = match for_server {
 6881                Some(server_id) => {
 6882                    let server_task = self.request_lsp(
 6883                        buffer.clone(),
 6884                        LanguageServerToQuery::Other(server_id),
 6885                        request,
 6886                        cx,
 6887                    );
 6888                    cx.background_spawn(async move {
 6889                        let mut responses = Vec::new();
 6890                        match server_task.await {
 6891                            Ok(response) => responses.push((server_id, response)),
 6892                            Err(e) => log::error!(
 6893                                "Error handling response for inlay hints request: {e:#}"
 6894                            ),
 6895                        }
 6896                        responses
 6897                    })
 6898                }
 6899                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 6900            };
 6901            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 6902            cx.background_spawn(async move {
 6903                Ok(inlay_hints_task
 6904                    .await
 6905                    .into_iter()
 6906                    .map(|(server_id, mut new_hints)| {
 6907                        new_hints.retain(|hint| {
 6908                            hint.position.is_valid(&buffer_snapshot)
 6909                                && range.start.is_valid(&buffer_snapshot)
 6910                                && range.end.is_valid(&buffer_snapshot)
 6911                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 6912                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 6913                        });
 6914                        (server_id, new_hints)
 6915                    })
 6916                    .collect())
 6917            })
 6918        }
 6919    }
 6920
 6921    pub fn pull_diagnostics_for_buffer(
 6922        &mut self,
 6923        buffer: Entity<Buffer>,
 6924        cx: &mut Context<Self>,
 6925    ) -> Task<anyhow::Result<()>> {
 6926        let diagnostics = self.pull_diagnostics(buffer, cx);
 6927        cx.spawn(async move |lsp_store, cx| {
 6928            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 6929                return Ok(());
 6930            };
 6931            lsp_store.update(cx, |lsp_store, cx| {
 6932                if lsp_store.as_local().is_none() {
 6933                    return;
 6934                }
 6935
 6936                let mut unchanged_buffers = HashSet::default();
 6937                let mut changed_buffers = HashSet::default();
 6938                let server_diagnostics_updates = diagnostics
 6939                    .into_iter()
 6940                    .filter_map(|diagnostics_set| match diagnostics_set {
 6941                        LspPullDiagnostics::Response {
 6942                            server_id,
 6943                            uri,
 6944                            diagnostics,
 6945                        } => Some((server_id, uri, diagnostics)),
 6946                        LspPullDiagnostics::Default => None,
 6947                    })
 6948                    .fold(
 6949                        HashMap::default(),
 6950                        |mut acc, (server_id, uri, diagnostics)| {
 6951                            let (result_id, diagnostics) = match diagnostics {
 6952                                PulledDiagnostics::Unchanged { result_id } => {
 6953                                    unchanged_buffers.insert(uri.clone());
 6954                                    (Some(result_id), Vec::new())
 6955                                }
 6956                                PulledDiagnostics::Changed {
 6957                                    result_id,
 6958                                    diagnostics,
 6959                                } => {
 6960                                    changed_buffers.insert(uri.clone());
 6961                                    (result_id, diagnostics)
 6962                                }
 6963                            };
 6964                            let disk_based_sources = Cow::Owned(
 6965                                lsp_store
 6966                                    .language_server_adapter_for_id(server_id)
 6967                                    .as_ref()
 6968                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 6969                                    .unwrap_or(&[])
 6970                                    .to_vec(),
 6971                            );
 6972                            acc.entry(server_id).or_insert_with(Vec::new).push(
 6973                                DocumentDiagnosticsUpdate {
 6974                                    server_id,
 6975                                    diagnostics: lsp::PublishDiagnosticsParams {
 6976                                        uri,
 6977                                        diagnostics,
 6978                                        version: None,
 6979                                    },
 6980                                    result_id,
 6981                                    disk_based_sources,
 6982                                },
 6983                            );
 6984                            acc
 6985                        },
 6986                    );
 6987
 6988                for diagnostic_updates in server_diagnostics_updates.into_values() {
 6989                    lsp_store
 6990                        .merge_lsp_diagnostics(
 6991                            DiagnosticSourceKind::Pulled,
 6992                            diagnostic_updates,
 6993                            |buffer, old_diagnostic, cx| {
 6994                                File::from_dyn(buffer.file())
 6995                                    .and_then(|file| {
 6996                                        let abs_path = file.as_local()?.abs_path(cx);
 6997                                        lsp::Uri::from_file_path(abs_path).ok()
 6998                                    })
 6999                                    .is_none_or(|buffer_uri| {
 7000                                        unchanged_buffers.contains(&buffer_uri)
 7001                                            || match old_diagnostic.source_kind {
 7002                                                DiagnosticSourceKind::Pulled => {
 7003                                                    !changed_buffers.contains(&buffer_uri)
 7004                                                }
 7005                                                DiagnosticSourceKind::Other
 7006                                                | DiagnosticSourceKind::Pushed => true,
 7007                                            }
 7008                                    })
 7009                            },
 7010                            cx,
 7011                        )
 7012                        .log_err();
 7013                }
 7014            })
 7015        })
 7016    }
 7017
 7018    pub fn document_colors(
 7019        &mut self,
 7020        known_cache_version: Option<usize>,
 7021        buffer: Entity<Buffer>,
 7022        cx: &mut Context<Self>,
 7023    ) -> Option<DocumentColorTask> {
 7024        let version_queried_for = buffer.read(cx).version();
 7025        let buffer_id = buffer.read(cx).remote_id();
 7026
 7027        let current_language_servers = self.as_local().map(|local| {
 7028            local
 7029                .buffers_opened_in_servers
 7030                .get(&buffer_id)
 7031                .cloned()
 7032                .unwrap_or_default()
 7033        });
 7034
 7035        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7036            if let Some(cached_colors) = &lsp_data.document_colors {
 7037                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7038                    let has_different_servers =
 7039                        current_language_servers.is_some_and(|current_language_servers| {
 7040                            current_language_servers
 7041                                != cached_colors.colors.keys().copied().collect()
 7042                        });
 7043                    if !has_different_servers {
 7044                        let cache_version = cached_colors.cache_version;
 7045                        if Some(cache_version) == known_cache_version {
 7046                            return None;
 7047                        } else {
 7048                            return Some(
 7049                                Task::ready(Ok(DocumentColors {
 7050                                    colors: cached_colors
 7051                                        .colors
 7052                                        .values()
 7053                                        .flatten()
 7054                                        .cloned()
 7055                                        .collect(),
 7056                                    cache_version: Some(cache_version),
 7057                                }))
 7058                                .shared(),
 7059                            );
 7060                        }
 7061                    }
 7062                }
 7063            }
 7064        }
 7065
 7066        let color_lsp_data = self
 7067            .latest_lsp_data(&buffer, cx)
 7068            .document_colors
 7069            .get_or_insert_default();
 7070        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7071            && !version_queried_for.changed_since(updating_for)
 7072        {
 7073            return Some(running_update.clone());
 7074        }
 7075        let buffer_version_queried_for = version_queried_for.clone();
 7076        let new_task = cx
 7077            .spawn(async move |lsp_store, cx| {
 7078                cx.background_executor()
 7079                    .timer(Duration::from_millis(30))
 7080                    .await;
 7081                let fetched_colors = lsp_store
 7082                    .update(cx, |lsp_store, cx| {
 7083                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7084                    })?
 7085                    .await
 7086                    .context("fetching document colors")
 7087                    .map_err(Arc::new);
 7088                let fetched_colors = match fetched_colors {
 7089                    Ok(fetched_colors) => {
 7090                        if Some(true)
 7091                            == buffer
 7092                                .update(cx, |buffer, _| {
 7093                                    buffer.version() != buffer_version_queried_for
 7094                                })
 7095                                .ok()
 7096                        {
 7097                            return Ok(DocumentColors::default());
 7098                        }
 7099                        fetched_colors
 7100                    }
 7101                    Err(e) => {
 7102                        lsp_store
 7103                            .update(cx, |lsp_store, _| {
 7104                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7105                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7106                                        document_colors.colors_update = None;
 7107                                    }
 7108                                }
 7109                            })
 7110                            .ok();
 7111                        return Err(e);
 7112                    }
 7113                };
 7114
 7115                lsp_store
 7116                    .update(cx, |lsp_store, cx| {
 7117                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7118                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7119
 7120                        if let Some(fetched_colors) = fetched_colors {
 7121                            if lsp_data.buffer_version == buffer_version_queried_for {
 7122                                lsp_colors.colors.extend(fetched_colors);
 7123                                lsp_colors.cache_version += 1;
 7124                            } else if !lsp_data
 7125                                .buffer_version
 7126                                .changed_since(&buffer_version_queried_for)
 7127                            {
 7128                                lsp_data.buffer_version = buffer_version_queried_for;
 7129                                lsp_colors.colors = fetched_colors;
 7130                                lsp_colors.cache_version += 1;
 7131                            }
 7132                        }
 7133                        lsp_colors.colors_update = None;
 7134                        let colors = lsp_colors
 7135                            .colors
 7136                            .values()
 7137                            .flatten()
 7138                            .cloned()
 7139                            .collect::<HashSet<_>>();
 7140                        DocumentColors {
 7141                            colors,
 7142                            cache_version: Some(lsp_colors.cache_version),
 7143                        }
 7144                    })
 7145                    .map_err(Arc::new)
 7146            })
 7147            .shared();
 7148        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7149        Some(new_task)
 7150    }
 7151
 7152    fn fetch_document_colors_for_buffer(
 7153        &mut self,
 7154        buffer: &Entity<Buffer>,
 7155        cx: &mut Context<Self>,
 7156    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7157        if let Some((client, project_id)) = self.upstream_client() {
 7158            let request = GetDocumentColor {};
 7159            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7160                return Task::ready(Ok(None));
 7161            }
 7162
 7163            let request_task = client.request_lsp(
 7164                project_id,
 7165                None,
 7166                LSP_REQUEST_TIMEOUT,
 7167                cx.background_executor().clone(),
 7168                request.to_proto(project_id, buffer.read(cx)),
 7169            );
 7170            let buffer = buffer.clone();
 7171            cx.spawn(async move |lsp_store, cx| {
 7172                let Some(project) = lsp_store.upgrade() else {
 7173                    return Ok(None);
 7174                };
 7175                let colors = join_all(
 7176                    request_task
 7177                        .await
 7178                        .log_err()
 7179                        .flatten()
 7180                        .map(|response| response.payload)
 7181                        .unwrap_or_default()
 7182                        .into_iter()
 7183                        .map(|color_response| {
 7184                            let response = request.response_from_proto(
 7185                                color_response.response,
 7186                                project.clone(),
 7187                                buffer.clone(),
 7188                                cx.clone(),
 7189                            );
 7190                            async move {
 7191                                (
 7192                                    LanguageServerId::from_proto(color_response.server_id),
 7193                                    response.await.log_err().unwrap_or_default(),
 7194                                )
 7195                            }
 7196                        }),
 7197                )
 7198                .await
 7199                .into_iter()
 7200                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7201                    acc.entry(server_id)
 7202                        .or_insert_with(HashSet::default)
 7203                        .extend(colors);
 7204                    acc
 7205                });
 7206                Ok(Some(colors))
 7207            })
 7208        } else {
 7209            let document_colors_task =
 7210                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7211            cx.background_spawn(async move {
 7212                Ok(Some(
 7213                    document_colors_task
 7214                        .await
 7215                        .into_iter()
 7216                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7217                            acc.entry(server_id)
 7218                                .or_insert_with(HashSet::default)
 7219                                .extend(colors);
 7220                            acc
 7221                        })
 7222                        .into_iter()
 7223                        .collect(),
 7224                ))
 7225            })
 7226        }
 7227    }
 7228
 7229    pub fn signature_help<T: ToPointUtf16>(
 7230        &mut self,
 7231        buffer: &Entity<Buffer>,
 7232        position: T,
 7233        cx: &mut Context<Self>,
 7234    ) -> Task<Option<Vec<SignatureHelp>>> {
 7235        let position = position.to_point_utf16(buffer.read(cx));
 7236
 7237        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7238            let request = GetSignatureHelp { position };
 7239            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7240                return Task::ready(None);
 7241            }
 7242            let request_task = client.request_lsp(
 7243                upstream_project_id,
 7244                None,
 7245                LSP_REQUEST_TIMEOUT,
 7246                cx.background_executor().clone(),
 7247                request.to_proto(upstream_project_id, buffer.read(cx)),
 7248            );
 7249            let buffer = buffer.clone();
 7250            cx.spawn(async move |weak_project, cx| {
 7251                let project = weak_project.upgrade()?;
 7252                let signatures = join_all(
 7253                    request_task
 7254                        .await
 7255                        .log_err()
 7256                        .flatten()
 7257                        .map(|response| response.payload)
 7258                        .unwrap_or_default()
 7259                        .into_iter()
 7260                        .map(|response| {
 7261                            let response = GetSignatureHelp { position }.response_from_proto(
 7262                                response.response,
 7263                                project.clone(),
 7264                                buffer.clone(),
 7265                                cx.clone(),
 7266                            );
 7267                            async move { response.await.log_err().flatten() }
 7268                        }),
 7269                )
 7270                .await
 7271                .into_iter()
 7272                .flatten()
 7273                .collect();
 7274                Some(signatures)
 7275            })
 7276        } else {
 7277            let all_actions_task = self.request_multiple_lsp_locally(
 7278                buffer,
 7279                Some(position),
 7280                GetSignatureHelp { position },
 7281                cx,
 7282            );
 7283            cx.background_spawn(async move {
 7284                Some(
 7285                    all_actions_task
 7286                        .await
 7287                        .into_iter()
 7288                        .flat_map(|(_, actions)| actions)
 7289                        .collect::<Vec<_>>(),
 7290                )
 7291            })
 7292        }
 7293    }
 7294
 7295    pub fn hover(
 7296        &mut self,
 7297        buffer: &Entity<Buffer>,
 7298        position: PointUtf16,
 7299        cx: &mut Context<Self>,
 7300    ) -> Task<Option<Vec<Hover>>> {
 7301        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7302            let request = GetHover { position };
 7303            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7304                return Task::ready(None);
 7305            }
 7306            let request_task = client.request_lsp(
 7307                upstream_project_id,
 7308                None,
 7309                LSP_REQUEST_TIMEOUT,
 7310                cx.background_executor().clone(),
 7311                request.to_proto(upstream_project_id, buffer.read(cx)),
 7312            );
 7313            let buffer = buffer.clone();
 7314            cx.spawn(async move |weak_project, cx| {
 7315                let project = weak_project.upgrade()?;
 7316                let hovers = join_all(
 7317                    request_task
 7318                        .await
 7319                        .log_err()
 7320                        .flatten()
 7321                        .map(|response| response.payload)
 7322                        .unwrap_or_default()
 7323                        .into_iter()
 7324                        .map(|response| {
 7325                            let response = GetHover { position }.response_from_proto(
 7326                                response.response,
 7327                                project.clone(),
 7328                                buffer.clone(),
 7329                                cx.clone(),
 7330                            );
 7331                            async move {
 7332                                response
 7333                                    .await
 7334                                    .log_err()
 7335                                    .flatten()
 7336                                    .and_then(remove_empty_hover_blocks)
 7337                            }
 7338                        }),
 7339                )
 7340                .await
 7341                .into_iter()
 7342                .flatten()
 7343                .collect();
 7344                Some(hovers)
 7345            })
 7346        } else {
 7347            let all_actions_task = self.request_multiple_lsp_locally(
 7348                buffer,
 7349                Some(position),
 7350                GetHover { position },
 7351                cx,
 7352            );
 7353            cx.background_spawn(async move {
 7354                Some(
 7355                    all_actions_task
 7356                        .await
 7357                        .into_iter()
 7358                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7359                        .collect::<Vec<Hover>>(),
 7360                )
 7361            })
 7362        }
 7363    }
 7364
 7365    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7366        let language_registry = self.languages.clone();
 7367
 7368        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7369            let request = upstream_client.request(proto::GetProjectSymbols {
 7370                project_id: *project_id,
 7371                query: query.to_string(),
 7372            });
 7373            cx.foreground_executor().spawn(async move {
 7374                let response = request.await?;
 7375                let mut symbols = Vec::new();
 7376                let core_symbols = response
 7377                    .symbols
 7378                    .into_iter()
 7379                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7380                    .collect::<Vec<_>>();
 7381                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7382                    .await;
 7383                Ok(symbols)
 7384            })
 7385        } else if let Some(local) = self.as_local() {
 7386            struct WorkspaceSymbolsResult {
 7387                server_id: LanguageServerId,
 7388                lsp_adapter: Arc<CachedLspAdapter>,
 7389                worktree: WeakEntity<Worktree>,
 7390                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7391            }
 7392
 7393            let mut requests = Vec::new();
 7394            let mut requested_servers = BTreeSet::new();
 7395            for (seed, state) in local.language_server_ids.iter() {
 7396                let Some(worktree_handle) = self
 7397                    .worktree_store
 7398                    .read(cx)
 7399                    .worktree_for_id(seed.worktree_id, cx)
 7400                else {
 7401                    continue;
 7402                };
 7403                let worktree = worktree_handle.read(cx);
 7404                if !worktree.is_visible() {
 7405                    continue;
 7406                }
 7407
 7408                if !requested_servers.insert(state.id) {
 7409                    continue;
 7410                }
 7411
 7412                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7413                    Some(LanguageServerState::Running {
 7414                        adapter, server, ..
 7415                    }) => (adapter.clone(), server),
 7416
 7417                    _ => continue,
 7418                };
 7419                let supports_workspace_symbol_request =
 7420                    match server.capabilities().workspace_symbol_provider {
 7421                        Some(OneOf::Left(supported)) => supported,
 7422                        Some(OneOf::Right(_)) => true,
 7423                        None => false,
 7424                    };
 7425                if !supports_workspace_symbol_request {
 7426                    continue;
 7427                }
 7428                let worktree_handle = worktree_handle.clone();
 7429                let server_id = server.server_id();
 7430                requests.push(
 7431                        server
 7432                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7433                                lsp::WorkspaceSymbolParams {
 7434                                    query: query.to_string(),
 7435                                    ..Default::default()
 7436                                },
 7437                            )
 7438                            .map(move |response| {
 7439                                let lsp_symbols = response.into_response()
 7440                                    .context("workspace symbols request")
 7441                                    .log_err()
 7442                                    .flatten()
 7443                                    .map(|symbol_response| match symbol_response {
 7444                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7445                                            flat_responses.into_iter().map(|lsp_symbol| {
 7446                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7447                                            }).collect::<Vec<_>>()
 7448                                        }
 7449                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7450                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7451                                                let location = match lsp_symbol.location {
 7452                                                    OneOf::Left(location) => location,
 7453                                                    OneOf::Right(_) => {
 7454                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7455                                                        return None
 7456                                                    }
 7457                                                };
 7458                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7459                                            }).collect::<Vec<_>>()
 7460                                        }
 7461                                    }).unwrap_or_default();
 7462
 7463                                WorkspaceSymbolsResult {
 7464                                    server_id,
 7465                                    lsp_adapter,
 7466                                    worktree: worktree_handle.downgrade(),
 7467                                    lsp_symbols,
 7468                                }
 7469                            }),
 7470                    );
 7471            }
 7472
 7473            cx.spawn(async move |this, cx| {
 7474                let responses = futures::future::join_all(requests).await;
 7475                let this = match this.upgrade() {
 7476                    Some(this) => this,
 7477                    None => return Ok(Vec::new()),
 7478                };
 7479
 7480                let mut symbols = Vec::new();
 7481                for result in responses {
 7482                    let core_symbols = this.update(cx, |this, cx| {
 7483                        result
 7484                            .lsp_symbols
 7485                            .into_iter()
 7486                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7487                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7488                                let source_worktree = result.worktree.upgrade()?;
 7489                                let source_worktree_id = source_worktree.read(cx).id();
 7490
 7491                                let path = if let Some((tree, rel_path)) =
 7492                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7493                                {
 7494                                    let worktree_id = tree.read(cx).id();
 7495                                    SymbolLocation::InProject(ProjectPath {
 7496                                        worktree_id,
 7497                                        path: rel_path,
 7498                                    })
 7499                                } else {
 7500                                    SymbolLocation::OutsideProject {
 7501                                        signature: this.symbol_signature(&abs_path),
 7502                                        abs_path: abs_path.into(),
 7503                                    }
 7504                                };
 7505
 7506                                Some(CoreSymbol {
 7507                                    source_language_server_id: result.server_id,
 7508                                    language_server_name: result.lsp_adapter.name.clone(),
 7509                                    source_worktree_id,
 7510                                    path,
 7511                                    kind: symbol_kind,
 7512                                    name: symbol_name,
 7513                                    range: range_from_lsp(symbol_location.range),
 7514                                })
 7515                            })
 7516                            .collect()
 7517                    })?;
 7518
 7519                    populate_labels_for_symbols(
 7520                        core_symbols,
 7521                        &language_registry,
 7522                        Some(result.lsp_adapter),
 7523                        &mut symbols,
 7524                    )
 7525                    .await;
 7526                }
 7527
 7528                Ok(symbols)
 7529            })
 7530        } else {
 7531            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7532        }
 7533    }
 7534
 7535    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7536        let mut summary = DiagnosticSummary::default();
 7537        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7538            summary.error_count += path_summary.error_count;
 7539            summary.warning_count += path_summary.warning_count;
 7540        }
 7541        summary
 7542    }
 7543
 7544    /// Returns the diagnostic summary for a specific project path.
 7545    pub fn diagnostic_summary_for_path(
 7546        &self,
 7547        project_path: &ProjectPath,
 7548        _: &App,
 7549    ) -> DiagnosticSummary {
 7550        if let Some(summaries) = self
 7551            .diagnostic_summaries
 7552            .get(&project_path.worktree_id)
 7553            .and_then(|map| map.get(&project_path.path))
 7554        {
 7555            let (error_count, warning_count) = summaries.iter().fold(
 7556                (0, 0),
 7557                |(error_count, warning_count), (_language_server_id, summary)| {
 7558                    (
 7559                        error_count + summary.error_count,
 7560                        warning_count + summary.warning_count,
 7561                    )
 7562                },
 7563            );
 7564
 7565            DiagnosticSummary {
 7566                error_count,
 7567                warning_count,
 7568            }
 7569        } else {
 7570            DiagnosticSummary::default()
 7571        }
 7572    }
 7573
 7574    pub fn diagnostic_summaries<'a>(
 7575        &'a self,
 7576        include_ignored: bool,
 7577        cx: &'a App,
 7578    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7579        self.worktree_store
 7580            .read(cx)
 7581            .visible_worktrees(cx)
 7582            .filter_map(|worktree| {
 7583                let worktree = worktree.read(cx);
 7584                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7585            })
 7586            .flat_map(move |(worktree, summaries)| {
 7587                let worktree_id = worktree.id();
 7588                summaries
 7589                    .iter()
 7590                    .filter(move |(path, _)| {
 7591                        include_ignored
 7592                            || worktree
 7593                                .entry_for_path(path.as_ref())
 7594                                .is_some_and(|entry| !entry.is_ignored)
 7595                    })
 7596                    .flat_map(move |(path, summaries)| {
 7597                        summaries.iter().map(move |(server_id, summary)| {
 7598                            (
 7599                                ProjectPath {
 7600                                    worktree_id,
 7601                                    path: path.clone(),
 7602                                },
 7603                                *server_id,
 7604                                *summary,
 7605                            )
 7606                        })
 7607                    })
 7608            })
 7609    }
 7610
 7611    pub fn on_buffer_edited(
 7612        &mut self,
 7613        buffer: Entity<Buffer>,
 7614        cx: &mut Context<Self>,
 7615    ) -> Option<()> {
 7616        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7617            Some(
 7618                self.as_local()?
 7619                    .language_servers_for_buffer(buffer, cx)
 7620                    .map(|i| i.1.clone())
 7621                    .collect(),
 7622            )
 7623        })?;
 7624
 7625        let buffer = buffer.read(cx);
 7626        let file = File::from_dyn(buffer.file())?;
 7627        let abs_path = file.as_local()?.abs_path(cx);
 7628        let uri = lsp::Uri::from_file_path(abs_path).unwrap();
 7629        let next_snapshot = buffer.text_snapshot();
 7630        for language_server in language_servers {
 7631            let language_server = language_server.clone();
 7632
 7633            let buffer_snapshots = self
 7634                .as_local_mut()
 7635                .unwrap()
 7636                .buffer_snapshots
 7637                .get_mut(&buffer.remote_id())
 7638                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7639            let previous_snapshot = buffer_snapshots.last()?;
 7640
 7641            let build_incremental_change = || {
 7642                buffer
 7643                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7644                        previous_snapshot.snapshot.version(),
 7645                    )
 7646                    .map(|edit| {
 7647                        let edit_start = edit.new.start.0;
 7648                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7649                        let new_text = next_snapshot
 7650                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7651                            .collect();
 7652                        lsp::TextDocumentContentChangeEvent {
 7653                            range: Some(lsp::Range::new(
 7654                                point_to_lsp(edit_start),
 7655                                point_to_lsp(edit_end),
 7656                            )),
 7657                            range_length: None,
 7658                            text: new_text,
 7659                        }
 7660                    })
 7661                    .collect()
 7662            };
 7663
 7664            let document_sync_kind = language_server
 7665                .capabilities()
 7666                .text_document_sync
 7667                .as_ref()
 7668                .and_then(|sync| match sync {
 7669                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7670                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7671                });
 7672
 7673            let content_changes: Vec<_> = match document_sync_kind {
 7674                Some(lsp::TextDocumentSyncKind::FULL) => {
 7675                    vec![lsp::TextDocumentContentChangeEvent {
 7676                        range: None,
 7677                        range_length: None,
 7678                        text: next_snapshot.text(),
 7679                    }]
 7680                }
 7681                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7682                _ => {
 7683                    #[cfg(any(test, feature = "test-support"))]
 7684                    {
 7685                        build_incremental_change()
 7686                    }
 7687
 7688                    #[cfg(not(any(test, feature = "test-support")))]
 7689                    {
 7690                        continue;
 7691                    }
 7692                }
 7693            };
 7694
 7695            let next_version = previous_snapshot.version + 1;
 7696            buffer_snapshots.push(LspBufferSnapshot {
 7697                version: next_version,
 7698                snapshot: next_snapshot.clone(),
 7699            });
 7700
 7701            language_server
 7702                .notify::<lsp::notification::DidChangeTextDocument>(
 7703                    lsp::DidChangeTextDocumentParams {
 7704                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7705                            uri.clone(),
 7706                            next_version,
 7707                        ),
 7708                        content_changes,
 7709                    },
 7710                )
 7711                .ok();
 7712            self.pull_workspace_diagnostics(language_server.server_id());
 7713        }
 7714
 7715        None
 7716    }
 7717
 7718    pub fn on_buffer_saved(
 7719        &mut self,
 7720        buffer: Entity<Buffer>,
 7721        cx: &mut Context<Self>,
 7722    ) -> Option<()> {
 7723        let file = File::from_dyn(buffer.read(cx).file())?;
 7724        let worktree_id = file.worktree_id(cx);
 7725        let abs_path = file.as_local()?.abs_path(cx);
 7726        let text_document = lsp::TextDocumentIdentifier {
 7727            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7728        };
 7729        let local = self.as_local()?;
 7730
 7731        for server in local.language_servers_for_worktree(worktree_id) {
 7732            if let Some(include_text) = include_text(server.as_ref()) {
 7733                let text = if include_text {
 7734                    Some(buffer.read(cx).text())
 7735                } else {
 7736                    None
 7737                };
 7738                server
 7739                    .notify::<lsp::notification::DidSaveTextDocument>(
 7740                        lsp::DidSaveTextDocumentParams {
 7741                            text_document: text_document.clone(),
 7742                            text,
 7743                        },
 7744                    )
 7745                    .ok();
 7746            }
 7747        }
 7748
 7749        let language_servers = buffer.update(cx, |buffer, cx| {
 7750            local.language_server_ids_for_buffer(buffer, cx)
 7751        });
 7752        for language_server_id in language_servers {
 7753            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7754        }
 7755
 7756        None
 7757    }
 7758
 7759    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 7760        maybe!(async move {
 7761            let mut refreshed_servers = HashSet::default();
 7762            let servers = lsp_store
 7763                .update(cx, |lsp_store, cx| {
 7764                    let local = lsp_store.as_local()?;
 7765
 7766                    let servers = local
 7767                        .language_server_ids
 7768                        .iter()
 7769                        .filter_map(|(seed, state)| {
 7770                            let worktree = lsp_store
 7771                                .worktree_store
 7772                                .read(cx)
 7773                                .worktree_for_id(seed.worktree_id, cx);
 7774                            let delegate: Arc<dyn LspAdapterDelegate> =
 7775                                worktree.map(|worktree| {
 7776                                    LocalLspAdapterDelegate::new(
 7777                                        local.languages.clone(),
 7778                                        &local.environment,
 7779                                        cx.weak_entity(),
 7780                                        &worktree,
 7781                                        local.http_client.clone(),
 7782                                        local.fs.clone(),
 7783                                        cx,
 7784                                    )
 7785                                })?;
 7786                            let server_id = state.id;
 7787
 7788                            let states = local.language_servers.get(&server_id)?;
 7789
 7790                            match states {
 7791                                LanguageServerState::Starting { .. } => None,
 7792                                LanguageServerState::Running {
 7793                                    adapter, server, ..
 7794                                } => {
 7795                                    let adapter = adapter.clone();
 7796                                    let server = server.clone();
 7797                                    refreshed_servers.insert(server.name());
 7798                                    let toolchain = seed.toolchain.clone();
 7799                                    Some(cx.spawn(async move |_, cx| {
 7800                                        let settings =
 7801                                            LocalLspStore::workspace_configuration_for_adapter(
 7802                                                adapter.adapter.clone(),
 7803                                                &delegate,
 7804                                                toolchain,
 7805                                                cx,
 7806                                            )
 7807                                            .await
 7808                                            .ok()?;
 7809                                        server
 7810                                            .notify::<lsp::notification::DidChangeConfiguration>(
 7811                                                lsp::DidChangeConfigurationParams { settings },
 7812                                            )
 7813                                            .ok()?;
 7814                                        Some(())
 7815                                    }))
 7816                                }
 7817                            }
 7818                        })
 7819                        .collect::<Vec<_>>();
 7820
 7821                    Some(servers)
 7822                })
 7823                .ok()
 7824                .flatten()?;
 7825
 7826            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 7827            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 7828            // to stop and unregister its language server wrapper.
 7829            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 7830            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 7831            let _: Vec<Option<()>> = join_all(servers).await;
 7832
 7833            Some(())
 7834        })
 7835        .await;
 7836    }
 7837
 7838    fn maintain_workspace_config(
 7839        external_refresh_requests: watch::Receiver<()>,
 7840        cx: &mut Context<Self>,
 7841    ) -> Task<Result<()>> {
 7842        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 7843        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 7844
 7845        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 7846            *settings_changed_tx.borrow_mut() = ();
 7847        });
 7848
 7849        let mut joint_future =
 7850            futures::stream::select(settings_changed_rx, external_refresh_requests);
 7851        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 7852        // - 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).
 7853        // - 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.
 7854        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 7855        // - 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,
 7856        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 7857        cx.spawn(async move |this, cx| {
 7858            while let Some(()) = joint_future.next().await {
 7859                this.update(cx, |this, cx| {
 7860                    this.refresh_server_tree(cx);
 7861                })
 7862                .ok();
 7863
 7864                Self::refresh_workspace_configurations(&this, cx).await;
 7865            }
 7866
 7867            drop(settings_observation);
 7868            anyhow::Ok(())
 7869        })
 7870    }
 7871
 7872    pub fn language_servers_for_local_buffer<'a>(
 7873        &'a self,
 7874        buffer: &Buffer,
 7875        cx: &mut App,
 7876    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7877        let local = self.as_local();
 7878        let language_server_ids = local
 7879            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 7880            .unwrap_or_default();
 7881
 7882        language_server_ids
 7883            .into_iter()
 7884            .filter_map(
 7885                move |server_id| match local?.language_servers.get(&server_id)? {
 7886                    LanguageServerState::Running {
 7887                        adapter, server, ..
 7888                    } => Some((adapter, server)),
 7889                    _ => None,
 7890                },
 7891            )
 7892    }
 7893
 7894    pub fn language_server_for_local_buffer<'a>(
 7895        &'a self,
 7896        buffer: &'a Buffer,
 7897        server_id: LanguageServerId,
 7898        cx: &'a mut App,
 7899    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7900        self.as_local()?
 7901            .language_servers_for_buffer(buffer, cx)
 7902            .find(|(_, s)| s.server_id() == server_id)
 7903    }
 7904
 7905    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 7906        self.diagnostic_summaries.remove(&id_to_remove);
 7907        if let Some(local) = self.as_local_mut() {
 7908            let to_remove = local.remove_worktree(id_to_remove, cx);
 7909            for server in to_remove {
 7910                self.language_server_statuses.remove(&server);
 7911            }
 7912        }
 7913    }
 7914
 7915    pub fn shared(
 7916        &mut self,
 7917        project_id: u64,
 7918        downstream_client: AnyProtoClient,
 7919        _: &mut Context<Self>,
 7920    ) {
 7921        self.downstream_client = Some((downstream_client.clone(), project_id));
 7922
 7923        for (server_id, status) in &self.language_server_statuses {
 7924            if let Some(server) = self.language_server_for_id(*server_id) {
 7925                downstream_client
 7926                    .send(proto::StartLanguageServer {
 7927                        project_id,
 7928                        server: Some(proto::LanguageServer {
 7929                            id: server_id.to_proto(),
 7930                            name: status.name.to_string(),
 7931                            worktree_id: status.worktree.map(|id| id.to_proto()),
 7932                        }),
 7933                        capabilities: serde_json::to_string(&server.capabilities())
 7934                            .expect("serializing server LSP capabilities"),
 7935                    })
 7936                    .log_err();
 7937            }
 7938        }
 7939    }
 7940
 7941    pub fn disconnected_from_host(&mut self) {
 7942        self.downstream_client.take();
 7943    }
 7944
 7945    pub fn disconnected_from_ssh_remote(&mut self) {
 7946        if let LspStoreMode::Remote(RemoteLspStore {
 7947            upstream_client, ..
 7948        }) = &mut self.mode
 7949        {
 7950            upstream_client.take();
 7951        }
 7952    }
 7953
 7954    pub(crate) fn set_language_server_statuses_from_proto(
 7955        &mut self,
 7956        project: WeakEntity<Project>,
 7957        language_servers: Vec<proto::LanguageServer>,
 7958        server_capabilities: Vec<String>,
 7959        cx: &mut Context<Self>,
 7960    ) {
 7961        let lsp_logs = cx
 7962            .try_global::<GlobalLogStore>()
 7963            .map(|lsp_store| lsp_store.0.clone());
 7964
 7965        self.language_server_statuses = language_servers
 7966            .into_iter()
 7967            .zip(server_capabilities)
 7968            .map(|(server, server_capabilities)| {
 7969                let server_id = LanguageServerId(server.id as usize);
 7970                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 7971                    self.lsp_server_capabilities
 7972                        .insert(server_id, server_capabilities);
 7973                }
 7974
 7975                let name = LanguageServerName::from_proto(server.name);
 7976                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 7977
 7978                if let Some(lsp_logs) = &lsp_logs {
 7979                    lsp_logs.update(cx, |lsp_logs, cx| {
 7980                        lsp_logs.add_language_server(
 7981                            // Only remote clients get their language servers set from proto
 7982                            LanguageServerKind::Remote {
 7983                                project: project.clone(),
 7984                            },
 7985                            server_id,
 7986                            Some(name.clone()),
 7987                            worktree,
 7988                            None,
 7989                            cx,
 7990                        );
 7991                    });
 7992                }
 7993
 7994                (
 7995                    server_id,
 7996                    LanguageServerStatus {
 7997                        name,
 7998                        pending_work: Default::default(),
 7999                        has_pending_diagnostic_updates: false,
 8000                        progress_tokens: Default::default(),
 8001                        worktree,
 8002                    },
 8003                )
 8004            })
 8005            .collect();
 8006    }
 8007
 8008    #[cfg(test)]
 8009    pub fn update_diagnostic_entries(
 8010        &mut self,
 8011        server_id: LanguageServerId,
 8012        abs_path: PathBuf,
 8013        result_id: Option<String>,
 8014        version: Option<i32>,
 8015        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8016        cx: &mut Context<Self>,
 8017    ) -> anyhow::Result<()> {
 8018        self.merge_diagnostic_entries(
 8019            vec![DocumentDiagnosticsUpdate {
 8020                diagnostics: DocumentDiagnostics {
 8021                    diagnostics,
 8022                    document_abs_path: abs_path,
 8023                    version,
 8024                },
 8025                result_id,
 8026                server_id,
 8027                disk_based_sources: Cow::Borrowed(&[]),
 8028            }],
 8029            |_, _, _| false,
 8030            cx,
 8031        )?;
 8032        Ok(())
 8033    }
 8034
 8035    pub fn merge_diagnostic_entries<'a>(
 8036        &mut self,
 8037        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8038        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
 8039        cx: &mut Context<Self>,
 8040    ) -> anyhow::Result<()> {
 8041        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8042        let mut updated_diagnostics_paths = HashMap::default();
 8043        for mut update in diagnostic_updates {
 8044            let abs_path = &update.diagnostics.document_abs_path;
 8045            let server_id = update.server_id;
 8046            let Some((worktree, relative_path)) =
 8047                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8048            else {
 8049                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8050                return Ok(());
 8051            };
 8052
 8053            let worktree_id = worktree.read(cx).id();
 8054            let project_path = ProjectPath {
 8055                worktree_id,
 8056                path: relative_path,
 8057            };
 8058
 8059            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8060                let snapshot = buffer_handle.read(cx).snapshot();
 8061                let buffer = buffer_handle.read(cx);
 8062                let reused_diagnostics = buffer
 8063                    .buffer_diagnostics(Some(server_id))
 8064                    .iter()
 8065                    .filter(|v| merge(buffer, &v.diagnostic, cx))
 8066                    .map(|v| {
 8067                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8068                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8069                        DiagnosticEntry {
 8070                            range: start..end,
 8071                            diagnostic: v.diagnostic.clone(),
 8072                        }
 8073                    })
 8074                    .collect::<Vec<_>>();
 8075
 8076                self.as_local_mut()
 8077                    .context("cannot merge diagnostics on a remote LspStore")?
 8078                    .update_buffer_diagnostics(
 8079                        &buffer_handle,
 8080                        server_id,
 8081                        update.result_id,
 8082                        update.diagnostics.version,
 8083                        update.diagnostics.diagnostics.clone(),
 8084                        reused_diagnostics.clone(),
 8085                        cx,
 8086                    )?;
 8087
 8088                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8089            }
 8090
 8091            let updated = worktree.update(cx, |worktree, cx| {
 8092                self.update_worktree_diagnostics(
 8093                    worktree.id(),
 8094                    server_id,
 8095                    project_path.path.clone(),
 8096                    update.diagnostics.diagnostics,
 8097                    cx,
 8098                )
 8099            })?;
 8100            match updated {
 8101                ControlFlow::Continue(new_summary) => {
 8102                    if let Some((project_id, new_summary)) = new_summary {
 8103                        match &mut diagnostics_summary {
 8104                            Some(diagnostics_summary) => {
 8105                                diagnostics_summary
 8106                                    .more_summaries
 8107                                    .push(proto::DiagnosticSummary {
 8108                                        path: project_path.path.as_ref().to_proto(),
 8109                                        language_server_id: server_id.0 as u64,
 8110                                        error_count: new_summary.error_count,
 8111                                        warning_count: new_summary.warning_count,
 8112                                    })
 8113                            }
 8114                            None => {
 8115                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8116                                    project_id,
 8117                                    worktree_id: worktree_id.to_proto(),
 8118                                    summary: Some(proto::DiagnosticSummary {
 8119                                        path: project_path.path.as_ref().to_proto(),
 8120                                        language_server_id: server_id.0 as u64,
 8121                                        error_count: new_summary.error_count,
 8122                                        warning_count: new_summary.warning_count,
 8123                                    }),
 8124                                    more_summaries: Vec::new(),
 8125                                })
 8126                            }
 8127                        }
 8128                    }
 8129                    updated_diagnostics_paths
 8130                        .entry(server_id)
 8131                        .or_insert_with(Vec::new)
 8132                        .push(project_path);
 8133                }
 8134                ControlFlow::Break(()) => {}
 8135            }
 8136        }
 8137
 8138        if let Some((diagnostics_summary, (downstream_client, _))) =
 8139            diagnostics_summary.zip(self.downstream_client.as_ref())
 8140        {
 8141            downstream_client.send(diagnostics_summary).log_err();
 8142        }
 8143        for (server_id, paths) in updated_diagnostics_paths {
 8144            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8145        }
 8146        Ok(())
 8147    }
 8148
 8149    fn update_worktree_diagnostics(
 8150        &mut self,
 8151        worktree_id: WorktreeId,
 8152        server_id: LanguageServerId,
 8153        path_in_worktree: Arc<RelPath>,
 8154        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8155        _: &mut Context<Worktree>,
 8156    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8157        let local = match &mut self.mode {
 8158            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8159            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8160        };
 8161
 8162        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8163        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8164        let summaries_by_server_id = summaries_for_tree
 8165            .entry(path_in_worktree.clone())
 8166            .or_default();
 8167
 8168        let old_summary = summaries_by_server_id
 8169            .remove(&server_id)
 8170            .unwrap_or_default();
 8171
 8172        let new_summary = DiagnosticSummary::new(&diagnostics);
 8173        if new_summary.is_empty() {
 8174            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8175            {
 8176                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8177                    diagnostics_by_server_id.remove(ix);
 8178                }
 8179                if diagnostics_by_server_id.is_empty() {
 8180                    diagnostics_for_tree.remove(&path_in_worktree);
 8181                }
 8182            }
 8183        } else {
 8184            summaries_by_server_id.insert(server_id, new_summary);
 8185            let diagnostics_by_server_id = diagnostics_for_tree
 8186                .entry(path_in_worktree.clone())
 8187                .or_default();
 8188            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8189                Ok(ix) => {
 8190                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8191                }
 8192                Err(ix) => {
 8193                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8194                }
 8195            }
 8196        }
 8197
 8198        if !old_summary.is_empty() || !new_summary.is_empty() {
 8199            if let Some((_, project_id)) = &self.downstream_client {
 8200                Ok(ControlFlow::Continue(Some((
 8201                    *project_id,
 8202                    proto::DiagnosticSummary {
 8203                        path: path_in_worktree.to_proto(),
 8204                        language_server_id: server_id.0 as u64,
 8205                        error_count: new_summary.error_count as u32,
 8206                        warning_count: new_summary.warning_count as u32,
 8207                    },
 8208                ))))
 8209            } else {
 8210                Ok(ControlFlow::Continue(None))
 8211            }
 8212        } else {
 8213            Ok(ControlFlow::Break(()))
 8214        }
 8215    }
 8216
 8217    pub fn open_buffer_for_symbol(
 8218        &mut self,
 8219        symbol: &Symbol,
 8220        cx: &mut Context<Self>,
 8221    ) -> Task<Result<Entity<Buffer>>> {
 8222        if let Some((client, project_id)) = self.upstream_client() {
 8223            let request = client.request(proto::OpenBufferForSymbol {
 8224                project_id,
 8225                symbol: Some(Self::serialize_symbol(symbol)),
 8226            });
 8227            cx.spawn(async move |this, cx| {
 8228                let response = request.await?;
 8229                let buffer_id = BufferId::new(response.buffer_id)?;
 8230                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8231                    .await
 8232            })
 8233        } else if let Some(local) = self.as_local() {
 8234            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8235                seed.worktree_id == symbol.source_worktree_id
 8236                    && state.id == symbol.source_language_server_id
 8237                    && symbol.language_server_name == seed.name
 8238            });
 8239            if !is_valid {
 8240                return Task::ready(Err(anyhow!(
 8241                    "language server for worktree and language not found"
 8242                )));
 8243            };
 8244
 8245            let symbol_abs_path = match &symbol.path {
 8246                SymbolLocation::InProject(project_path) => self
 8247                    .worktree_store
 8248                    .read(cx)
 8249                    .absolutize(&project_path, cx)
 8250                    .context("no such worktree"),
 8251                SymbolLocation::OutsideProject {
 8252                    abs_path,
 8253                    signature: _,
 8254                } => Ok(abs_path.to_path_buf()),
 8255            };
 8256            let symbol_abs_path = match symbol_abs_path {
 8257                Ok(abs_path) => abs_path,
 8258                Err(err) => return Task::ready(Err(err)),
 8259            };
 8260            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8261                uri
 8262            } else {
 8263                return Task::ready(Err(anyhow!("invalid symbol path")));
 8264            };
 8265
 8266            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8267        } else {
 8268            Task::ready(Err(anyhow!("no upstream client or local store")))
 8269        }
 8270    }
 8271
 8272    pub(crate) fn open_local_buffer_via_lsp(
 8273        &mut self,
 8274        abs_path: lsp::Uri,
 8275        language_server_id: LanguageServerId,
 8276        cx: &mut Context<Self>,
 8277    ) -> Task<Result<Entity<Buffer>>> {
 8278        cx.spawn(async move |lsp_store, cx| {
 8279            // Escape percent-encoded string.
 8280            let current_scheme = abs_path.scheme().to_owned();
 8281            // Uri is immutable, so we can't modify the scheme
 8282
 8283            let abs_path = abs_path
 8284                .to_file_path()
 8285                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8286            let p = abs_path.clone();
 8287            let yarn_worktree = lsp_store
 8288                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8289                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8290                        cx.spawn(async move |this, cx| {
 8291                            let t = this
 8292                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8293                                .ok()?;
 8294                            t.await
 8295                        })
 8296                    }),
 8297                    None => Task::ready(None),
 8298                })?
 8299                .await;
 8300            let (worktree_root_target, known_relative_path) =
 8301                if let Some((zip_root, relative_path)) = yarn_worktree {
 8302                    (zip_root, Some(relative_path))
 8303                } else {
 8304                    (Arc::<Path>::from(abs_path.as_path()), None)
 8305                };
 8306            let (worktree, relative_path) = if let Some(result) =
 8307                lsp_store.update(cx, |lsp_store, cx| {
 8308                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8309                        worktree_store.find_worktree(&worktree_root_target, cx)
 8310                    })
 8311                })? {
 8312                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8313                (result.0, relative_path)
 8314            } else {
 8315                let worktree = lsp_store
 8316                    .update(cx, |lsp_store, cx| {
 8317                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8318                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8319                        })
 8320                    })?
 8321                    .await?;
 8322                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8323                    lsp_store
 8324                        .update(cx, |lsp_store, cx| {
 8325                            if let Some(local) = lsp_store.as_local_mut() {
 8326                                local.register_language_server_for_invisible_worktree(
 8327                                    &worktree,
 8328                                    language_server_id,
 8329                                    cx,
 8330                                )
 8331                            }
 8332                        })
 8333                        .ok();
 8334                }
 8335                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8336                let relative_path = if let Some(known_path) = known_relative_path {
 8337                    known_path
 8338                } else {
 8339                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8340                        .into_arc()
 8341                };
 8342                (worktree, relative_path)
 8343            };
 8344            let project_path = ProjectPath {
 8345                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8346                path: relative_path,
 8347            };
 8348            lsp_store
 8349                .update(cx, |lsp_store, cx| {
 8350                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8351                        buffer_store.open_buffer(project_path, cx)
 8352                    })
 8353                })?
 8354                .await
 8355        })
 8356    }
 8357
 8358    fn request_multiple_lsp_locally<P, R>(
 8359        &mut self,
 8360        buffer: &Entity<Buffer>,
 8361        position: Option<P>,
 8362        request: R,
 8363        cx: &mut Context<Self>,
 8364    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8365    where
 8366        P: ToOffset,
 8367        R: LspCommand + Clone,
 8368        <R::LspRequest as lsp::request::Request>::Result: Send,
 8369        <R::LspRequest as lsp::request::Request>::Params: Send,
 8370    {
 8371        let Some(local) = self.as_local() else {
 8372            return Task::ready(Vec::new());
 8373        };
 8374
 8375        let snapshot = buffer.read(cx).snapshot();
 8376        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8377
 8378        let server_ids = buffer.update(cx, |buffer, cx| {
 8379            local
 8380                .language_servers_for_buffer(buffer, cx)
 8381                .filter(|(adapter, _)| {
 8382                    scope
 8383                        .as_ref()
 8384                        .map(|scope| scope.language_allowed(&adapter.name))
 8385                        .unwrap_or(true)
 8386                })
 8387                .map(|(_, server)| server.server_id())
 8388                .filter(|server_id| {
 8389                    self.as_local().is_none_or(|local| {
 8390                        local
 8391                            .buffers_opened_in_servers
 8392                            .get(&snapshot.remote_id())
 8393                            .is_some_and(|servers| servers.contains(server_id))
 8394                    })
 8395                })
 8396                .collect::<Vec<_>>()
 8397        });
 8398
 8399        let mut response_results = server_ids
 8400            .into_iter()
 8401            .map(|server_id| {
 8402                let task = self.request_lsp(
 8403                    buffer.clone(),
 8404                    LanguageServerToQuery::Other(server_id),
 8405                    request.clone(),
 8406                    cx,
 8407                );
 8408                async move { (server_id, task.await) }
 8409            })
 8410            .collect::<FuturesUnordered<_>>();
 8411
 8412        cx.background_spawn(async move {
 8413            let mut responses = Vec::with_capacity(response_results.len());
 8414            while let Some((server_id, response_result)) = response_results.next().await {
 8415                match response_result {
 8416                    Ok(response) => responses.push((server_id, response)),
 8417                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8418                }
 8419            }
 8420            responses
 8421        })
 8422    }
 8423
 8424    async fn handle_lsp_command<T: LspCommand>(
 8425        this: Entity<Self>,
 8426        envelope: TypedEnvelope<T::ProtoRequest>,
 8427        mut cx: AsyncApp,
 8428    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8429    where
 8430        <T::LspRequest as lsp::request::Request>::Params: Send,
 8431        <T::LspRequest as lsp::request::Request>::Result: Send,
 8432    {
 8433        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8434        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8435        let buffer_handle = this.update(&mut cx, |this, cx| {
 8436            this.buffer_store.read(cx).get_existing(buffer_id)
 8437        })??;
 8438        let request = T::from_proto(
 8439            envelope.payload,
 8440            this.clone(),
 8441            buffer_handle.clone(),
 8442            cx.clone(),
 8443        )
 8444        .await?;
 8445        let response = this
 8446            .update(&mut cx, |this, cx| {
 8447                this.request_lsp(
 8448                    buffer_handle.clone(),
 8449                    LanguageServerToQuery::FirstCapable,
 8450                    request,
 8451                    cx,
 8452                )
 8453            })?
 8454            .await?;
 8455        this.update(&mut cx, |this, cx| {
 8456            Ok(T::response_to_proto(
 8457                response,
 8458                this,
 8459                sender_id,
 8460                &buffer_handle.read(cx).version(),
 8461                cx,
 8462            ))
 8463        })?
 8464    }
 8465
 8466    async fn handle_lsp_query(
 8467        lsp_store: Entity<Self>,
 8468        envelope: TypedEnvelope<proto::LspQuery>,
 8469        mut cx: AsyncApp,
 8470    ) -> Result<proto::Ack> {
 8471        use proto::lsp_query::Request;
 8472        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8473        let lsp_query = envelope.payload;
 8474        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8475        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8476        match lsp_query.request.context("invalid LSP query request")? {
 8477            Request::GetReferences(get_references) => {
 8478                let position = get_references.position.clone().and_then(deserialize_anchor);
 8479                Self::query_lsp_locally::<GetReferences>(
 8480                    lsp_store,
 8481                    server_id,
 8482                    sender_id,
 8483                    lsp_request_id,
 8484                    get_references,
 8485                    position,
 8486                    &mut cx,
 8487                )
 8488                .await?;
 8489            }
 8490            Request::GetDocumentColor(get_document_color) => {
 8491                Self::query_lsp_locally::<GetDocumentColor>(
 8492                    lsp_store,
 8493                    server_id,
 8494                    sender_id,
 8495                    lsp_request_id,
 8496                    get_document_color,
 8497                    None,
 8498                    &mut cx,
 8499                )
 8500                .await?;
 8501            }
 8502            Request::GetHover(get_hover) => {
 8503                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8504                Self::query_lsp_locally::<GetHover>(
 8505                    lsp_store,
 8506                    server_id,
 8507                    sender_id,
 8508                    lsp_request_id,
 8509                    get_hover,
 8510                    position,
 8511                    &mut cx,
 8512                )
 8513                .await?;
 8514            }
 8515            Request::GetCodeActions(get_code_actions) => {
 8516                Self::query_lsp_locally::<GetCodeActions>(
 8517                    lsp_store,
 8518                    server_id,
 8519                    sender_id,
 8520                    lsp_request_id,
 8521                    get_code_actions,
 8522                    None,
 8523                    &mut cx,
 8524                )
 8525                .await?;
 8526            }
 8527            Request::GetSignatureHelp(get_signature_help) => {
 8528                let position = get_signature_help
 8529                    .position
 8530                    .clone()
 8531                    .and_then(deserialize_anchor);
 8532                Self::query_lsp_locally::<GetSignatureHelp>(
 8533                    lsp_store,
 8534                    server_id,
 8535                    sender_id,
 8536                    lsp_request_id,
 8537                    get_signature_help,
 8538                    position,
 8539                    &mut cx,
 8540                )
 8541                .await?;
 8542            }
 8543            Request::GetCodeLens(get_code_lens) => {
 8544                Self::query_lsp_locally::<GetCodeLens>(
 8545                    lsp_store,
 8546                    server_id,
 8547                    sender_id,
 8548                    lsp_request_id,
 8549                    get_code_lens,
 8550                    None,
 8551                    &mut cx,
 8552                )
 8553                .await?;
 8554            }
 8555            Request::GetDefinition(get_definition) => {
 8556                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8557                Self::query_lsp_locally::<GetDefinitions>(
 8558                    lsp_store,
 8559                    server_id,
 8560                    sender_id,
 8561                    lsp_request_id,
 8562                    get_definition,
 8563                    position,
 8564                    &mut cx,
 8565                )
 8566                .await?;
 8567            }
 8568            Request::GetDeclaration(get_declaration) => {
 8569                let position = get_declaration
 8570                    .position
 8571                    .clone()
 8572                    .and_then(deserialize_anchor);
 8573                Self::query_lsp_locally::<GetDeclarations>(
 8574                    lsp_store,
 8575                    server_id,
 8576                    sender_id,
 8577                    lsp_request_id,
 8578                    get_declaration,
 8579                    position,
 8580                    &mut cx,
 8581                )
 8582                .await?;
 8583            }
 8584            Request::GetTypeDefinition(get_type_definition) => {
 8585                let position = get_type_definition
 8586                    .position
 8587                    .clone()
 8588                    .and_then(deserialize_anchor);
 8589                Self::query_lsp_locally::<GetTypeDefinitions>(
 8590                    lsp_store,
 8591                    server_id,
 8592                    sender_id,
 8593                    lsp_request_id,
 8594                    get_type_definition,
 8595                    position,
 8596                    &mut cx,
 8597                )
 8598                .await?;
 8599            }
 8600            Request::GetImplementation(get_implementation) => {
 8601                let position = get_implementation
 8602                    .position
 8603                    .clone()
 8604                    .and_then(deserialize_anchor);
 8605                Self::query_lsp_locally::<GetImplementations>(
 8606                    lsp_store,
 8607                    server_id,
 8608                    sender_id,
 8609                    lsp_request_id,
 8610                    get_implementation,
 8611                    position,
 8612                    &mut cx,
 8613                )
 8614                .await?;
 8615            }
 8616            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 8617                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 8618                let version = deserialize_version(get_document_diagnostics.buffer_version());
 8619                let buffer = lsp_store.update(&mut cx, |this, cx| {
 8620                    this.buffer_store.read(cx).get_existing(buffer_id)
 8621                })??;
 8622                buffer
 8623                    .update(&mut cx, |buffer, _| {
 8624                        buffer.wait_for_version(version.clone())
 8625                    })?
 8626                    .await?;
 8627                lsp_store.update(&mut cx, |lsp_store, cx| {
 8628                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 8629                    let key = LspKey {
 8630                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 8631                        server_queried: server_id,
 8632                    };
 8633                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 8634                    ) {
 8635                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 8636                            lsp_requests.clear();
 8637                        };
 8638                    }
 8639
 8640                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 8641                    existing_queries.insert(
 8642                        lsp_request_id,
 8643                        cx.spawn(async move |lsp_store, cx| {
 8644                            let diagnostics_pull = lsp_store
 8645                                .update(cx, |lsp_store, cx| {
 8646                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8647                                })
 8648                                .ok();
 8649                            if let Some(diagnostics_pull) = diagnostics_pull {
 8650                                match diagnostics_pull.await {
 8651                                    Ok(()) => {}
 8652                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 8653                                };
 8654                            }
 8655                        }),
 8656                    );
 8657                })?;
 8658            }
 8659            Request::InlayHints(inlay_hints) => {
 8660                let query_start = inlay_hints
 8661                    .start
 8662                    .clone()
 8663                    .and_then(deserialize_anchor)
 8664                    .context("invalid inlay hints range start")?;
 8665                let query_end = inlay_hints
 8666                    .end
 8667                    .clone()
 8668                    .and_then(deserialize_anchor)
 8669                    .context("invalid inlay hints range end")?;
 8670                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 8671                    &lsp_store,
 8672                    server_id,
 8673                    lsp_request_id,
 8674                    &inlay_hints,
 8675                    query_start..query_end,
 8676                    &mut cx,
 8677                )
 8678                .await
 8679                .context("preparing inlay hints request")?;
 8680                Self::query_lsp_locally::<InlayHints>(
 8681                    lsp_store,
 8682                    server_id,
 8683                    sender_id,
 8684                    lsp_request_id,
 8685                    inlay_hints,
 8686                    None,
 8687                    &mut cx,
 8688                )
 8689                .await
 8690                .context("querying for inlay hints")?
 8691            }
 8692        }
 8693        Ok(proto::Ack {})
 8694    }
 8695
 8696    async fn handle_lsp_query_response(
 8697        lsp_store: Entity<Self>,
 8698        envelope: TypedEnvelope<proto::LspQueryResponse>,
 8699        cx: AsyncApp,
 8700    ) -> Result<()> {
 8701        lsp_store.read_with(&cx, |lsp_store, _| {
 8702            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 8703                upstream_client.handle_lsp_response(envelope.clone());
 8704            }
 8705        })?;
 8706        Ok(())
 8707    }
 8708
 8709    async fn handle_apply_code_action(
 8710        this: Entity<Self>,
 8711        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 8712        mut cx: AsyncApp,
 8713    ) -> Result<proto::ApplyCodeActionResponse> {
 8714        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8715        let action =
 8716            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 8717        let apply_code_action = this.update(&mut cx, |this, cx| {
 8718            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8719            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 8720            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 8721        })??;
 8722
 8723        let project_transaction = apply_code_action.await?;
 8724        let project_transaction = this.update(&mut cx, |this, cx| {
 8725            this.buffer_store.update(cx, |buffer_store, cx| {
 8726                buffer_store.serialize_project_transaction_for_peer(
 8727                    project_transaction,
 8728                    sender_id,
 8729                    cx,
 8730                )
 8731            })
 8732        })?;
 8733        Ok(proto::ApplyCodeActionResponse {
 8734            transaction: Some(project_transaction),
 8735        })
 8736    }
 8737
 8738    async fn handle_register_buffer_with_language_servers(
 8739        this: Entity<Self>,
 8740        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 8741        mut cx: AsyncApp,
 8742    ) -> Result<proto::Ack> {
 8743        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8744        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 8745        this.update(&mut cx, |this, cx| {
 8746            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 8747                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 8748                    project_id: upstream_project_id,
 8749                    buffer_id: buffer_id.to_proto(),
 8750                    only_servers: envelope.payload.only_servers,
 8751                });
 8752            }
 8753
 8754            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 8755                anyhow::bail!("buffer is not open");
 8756            };
 8757
 8758            let handle = this.register_buffer_with_language_servers(
 8759                &buffer,
 8760                envelope
 8761                    .payload
 8762                    .only_servers
 8763                    .into_iter()
 8764                    .filter_map(|selector| {
 8765                        Some(match selector.selector? {
 8766                            proto::language_server_selector::Selector::ServerId(server_id) => {
 8767                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 8768                            }
 8769                            proto::language_server_selector::Selector::Name(name) => {
 8770                                LanguageServerSelector::Name(LanguageServerName(
 8771                                    SharedString::from(name),
 8772                                ))
 8773                            }
 8774                        })
 8775                    })
 8776                    .collect(),
 8777                false,
 8778                cx,
 8779            );
 8780            this.buffer_store().update(cx, |buffer_store, _| {
 8781                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 8782            });
 8783
 8784            Ok(())
 8785        })??;
 8786        Ok(proto::Ack {})
 8787    }
 8788
 8789    async fn handle_rename_project_entry(
 8790        this: Entity<Self>,
 8791        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 8792        mut cx: AsyncApp,
 8793    ) -> Result<proto::ProjectEntryResponse> {
 8794        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 8795        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 8796        let new_path =
 8797            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 8798
 8799        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 8800            .update(&mut cx, |this, cx| {
 8801                let (worktree, entry) = this
 8802                    .worktree_store
 8803                    .read(cx)
 8804                    .worktree_and_entry_for_id(entry_id, cx)?;
 8805                let new_worktree = this
 8806                    .worktree_store
 8807                    .read(cx)
 8808                    .worktree_for_id(new_worktree_id, cx)?;
 8809                Some((
 8810                    this.worktree_store.clone(),
 8811                    worktree,
 8812                    new_worktree,
 8813                    entry.clone(),
 8814                ))
 8815            })?
 8816            .context("worktree not found")?;
 8817        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 8818            (worktree.absolutize(&old_entry.path), worktree.id())
 8819        })?;
 8820        let new_abs_path =
 8821            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 8822
 8823        let _transaction = Self::will_rename_entry(
 8824            this.downgrade(),
 8825            old_worktree_id,
 8826            &old_abs_path,
 8827            &new_abs_path,
 8828            old_entry.is_dir(),
 8829            cx.clone(),
 8830        )
 8831        .await;
 8832        let response = WorktreeStore::handle_rename_project_entry(
 8833            worktree_store,
 8834            envelope.payload,
 8835            cx.clone(),
 8836        )
 8837        .await;
 8838        this.read_with(&cx, |this, _| {
 8839            this.did_rename_entry(
 8840                old_worktree_id,
 8841                &old_abs_path,
 8842                &new_abs_path,
 8843                old_entry.is_dir(),
 8844            );
 8845        })
 8846        .ok();
 8847        response
 8848    }
 8849
 8850    async fn handle_update_diagnostic_summary(
 8851        this: Entity<Self>,
 8852        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 8853        mut cx: AsyncApp,
 8854    ) -> Result<()> {
 8855        this.update(&mut cx, |lsp_store, cx| {
 8856            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 8857            let mut updated_diagnostics_paths = HashMap::default();
 8858            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8859            for message_summary in envelope
 8860                .payload
 8861                .summary
 8862                .into_iter()
 8863                .chain(envelope.payload.more_summaries)
 8864            {
 8865                let project_path = ProjectPath {
 8866                    worktree_id,
 8867                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 8868                };
 8869                let path = project_path.path.clone();
 8870                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 8871                let summary = DiagnosticSummary {
 8872                    error_count: message_summary.error_count as usize,
 8873                    warning_count: message_summary.warning_count as usize,
 8874                };
 8875
 8876                if summary.is_empty() {
 8877                    if let Some(worktree_summaries) =
 8878                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 8879                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 8880                    {
 8881                        summaries.remove(&server_id);
 8882                        if summaries.is_empty() {
 8883                            worktree_summaries.remove(&path);
 8884                        }
 8885                    }
 8886                } else {
 8887                    lsp_store
 8888                        .diagnostic_summaries
 8889                        .entry(worktree_id)
 8890                        .or_default()
 8891                        .entry(path)
 8892                        .or_default()
 8893                        .insert(server_id, summary);
 8894                }
 8895
 8896                if let Some((_, project_id)) = &lsp_store.downstream_client {
 8897                    match &mut diagnostics_summary {
 8898                        Some(diagnostics_summary) => {
 8899                            diagnostics_summary
 8900                                .more_summaries
 8901                                .push(proto::DiagnosticSummary {
 8902                                    path: project_path.path.as_ref().to_proto(),
 8903                                    language_server_id: server_id.0 as u64,
 8904                                    error_count: summary.error_count as u32,
 8905                                    warning_count: summary.warning_count as u32,
 8906                                })
 8907                        }
 8908                        None => {
 8909                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8910                                project_id: *project_id,
 8911                                worktree_id: worktree_id.to_proto(),
 8912                                summary: Some(proto::DiagnosticSummary {
 8913                                    path: project_path.path.as_ref().to_proto(),
 8914                                    language_server_id: server_id.0 as u64,
 8915                                    error_count: summary.error_count as u32,
 8916                                    warning_count: summary.warning_count as u32,
 8917                                }),
 8918                                more_summaries: Vec::new(),
 8919                            })
 8920                        }
 8921                    }
 8922                }
 8923                updated_diagnostics_paths
 8924                    .entry(server_id)
 8925                    .or_insert_with(Vec::new)
 8926                    .push(project_path);
 8927            }
 8928
 8929            if let Some((diagnostics_summary, (downstream_client, _))) =
 8930                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 8931            {
 8932                downstream_client.send(diagnostics_summary).log_err();
 8933            }
 8934            for (server_id, paths) in updated_diagnostics_paths {
 8935                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8936            }
 8937            Ok(())
 8938        })?
 8939    }
 8940
 8941    async fn handle_start_language_server(
 8942        lsp_store: Entity<Self>,
 8943        envelope: TypedEnvelope<proto::StartLanguageServer>,
 8944        mut cx: AsyncApp,
 8945    ) -> Result<()> {
 8946        let server = envelope.payload.server.context("invalid server")?;
 8947        let server_capabilities =
 8948            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 8949                .with_context(|| {
 8950                    format!(
 8951                        "incorrect server capabilities {}",
 8952                        envelope.payload.capabilities
 8953                    )
 8954                })?;
 8955        lsp_store.update(&mut cx, |lsp_store, cx| {
 8956            let server_id = LanguageServerId(server.id as usize);
 8957            let server_name = LanguageServerName::from_proto(server.name.clone());
 8958            lsp_store
 8959                .lsp_server_capabilities
 8960                .insert(server_id, server_capabilities);
 8961            lsp_store.language_server_statuses.insert(
 8962                server_id,
 8963                LanguageServerStatus {
 8964                    name: server_name.clone(),
 8965                    pending_work: Default::default(),
 8966                    has_pending_diagnostic_updates: false,
 8967                    progress_tokens: Default::default(),
 8968                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 8969                },
 8970            );
 8971            cx.emit(LspStoreEvent::LanguageServerAdded(
 8972                server_id,
 8973                server_name,
 8974                server.worktree_id.map(WorktreeId::from_proto),
 8975            ));
 8976            cx.notify();
 8977        })?;
 8978        Ok(())
 8979    }
 8980
 8981    async fn handle_update_language_server(
 8982        lsp_store: Entity<Self>,
 8983        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 8984        mut cx: AsyncApp,
 8985    ) -> Result<()> {
 8986        lsp_store.update(&mut cx, |lsp_store, cx| {
 8987            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8988
 8989            match envelope.payload.variant.context("invalid variant")? {
 8990                proto::update_language_server::Variant::WorkStart(payload) => {
 8991                    lsp_store.on_lsp_work_start(
 8992                        language_server_id,
 8993                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 8994                            .context("invalid progress token value")?,
 8995                        LanguageServerProgress {
 8996                            title: payload.title,
 8997                            is_disk_based_diagnostics_progress: false,
 8998                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 8999                            message: payload.message,
 9000                            percentage: payload.percentage.map(|p| p as usize),
 9001                            last_update_at: cx.background_executor().now(),
 9002                        },
 9003                        cx,
 9004                    );
 9005                }
 9006                proto::update_language_server::Variant::WorkProgress(payload) => {
 9007                    lsp_store.on_lsp_work_progress(
 9008                        language_server_id,
 9009                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9010                            .context("invalid progress token value")?,
 9011                        LanguageServerProgress {
 9012                            title: None,
 9013                            is_disk_based_diagnostics_progress: false,
 9014                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9015                            message: payload.message,
 9016                            percentage: payload.percentage.map(|p| p as usize),
 9017                            last_update_at: cx.background_executor().now(),
 9018                        },
 9019                        cx,
 9020                    );
 9021                }
 9022
 9023                proto::update_language_server::Variant::WorkEnd(payload) => {
 9024                    lsp_store.on_lsp_work_end(
 9025                        language_server_id,
 9026                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9027                            .context("invalid progress token value")?,
 9028                        cx,
 9029                    );
 9030                }
 9031
 9032                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9033                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9034                }
 9035
 9036                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9037                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9038                }
 9039
 9040                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9041                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9042                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9043                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9044                        language_server_id,
 9045                        name: envelope
 9046                            .payload
 9047                            .server_name
 9048                            .map(SharedString::new)
 9049                            .map(LanguageServerName),
 9050                        message: non_lsp,
 9051                    });
 9052                }
 9053            }
 9054
 9055            Ok(())
 9056        })?
 9057    }
 9058
 9059    async fn handle_language_server_log(
 9060        this: Entity<Self>,
 9061        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9062        mut cx: AsyncApp,
 9063    ) -> Result<()> {
 9064        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9065        let log_type = envelope
 9066            .payload
 9067            .log_type
 9068            .map(LanguageServerLogType::from_proto)
 9069            .context("invalid language server log type")?;
 9070
 9071        let message = envelope.payload.message;
 9072
 9073        this.update(&mut cx, |_, cx| {
 9074            cx.emit(LspStoreEvent::LanguageServerLog(
 9075                language_server_id,
 9076                log_type,
 9077                message,
 9078            ));
 9079        })
 9080    }
 9081
 9082    async fn handle_lsp_ext_cancel_flycheck(
 9083        lsp_store: Entity<Self>,
 9084        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9085        cx: AsyncApp,
 9086    ) -> Result<proto::Ack> {
 9087        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9088        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9089            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9090                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9091            } else {
 9092                None
 9093            }
 9094        })?;
 9095        if let Some(task) = task {
 9096            task.context("handling lsp ext cancel flycheck")?;
 9097        }
 9098
 9099        Ok(proto::Ack {})
 9100    }
 9101
 9102    async fn handle_lsp_ext_run_flycheck(
 9103        lsp_store: Entity<Self>,
 9104        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9105        mut cx: AsyncApp,
 9106    ) -> Result<proto::Ack> {
 9107        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9108        lsp_store.update(&mut cx, |lsp_store, cx| {
 9109            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9110                let text_document = if envelope.payload.current_file_only {
 9111                    let buffer_id = envelope
 9112                        .payload
 9113                        .buffer_id
 9114                        .map(|id| BufferId::new(id))
 9115                        .transpose()?;
 9116                    buffer_id
 9117                        .and_then(|buffer_id| {
 9118                            lsp_store
 9119                                .buffer_store()
 9120                                .read(cx)
 9121                                .get(buffer_id)
 9122                                .and_then(|buffer| {
 9123                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9124                                })
 9125                                .map(|path| make_text_document_identifier(&path))
 9126                        })
 9127                        .transpose()?
 9128                } else {
 9129                    None
 9130                };
 9131                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9132                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9133                )?;
 9134            }
 9135            anyhow::Ok(())
 9136        })??;
 9137
 9138        Ok(proto::Ack {})
 9139    }
 9140
 9141    async fn handle_lsp_ext_clear_flycheck(
 9142        lsp_store: Entity<Self>,
 9143        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9144        cx: AsyncApp,
 9145    ) -> Result<proto::Ack> {
 9146        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9147        lsp_store
 9148            .read_with(&cx, |lsp_store, _| {
 9149                if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9150                    Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9151                } else {
 9152                    None
 9153                }
 9154            })
 9155            .context("handling lsp ext clear flycheck")?;
 9156
 9157        Ok(proto::Ack {})
 9158    }
 9159
 9160    pub fn disk_based_diagnostics_started(
 9161        &mut self,
 9162        language_server_id: LanguageServerId,
 9163        cx: &mut Context<Self>,
 9164    ) {
 9165        if let Some(language_server_status) =
 9166            self.language_server_statuses.get_mut(&language_server_id)
 9167        {
 9168            language_server_status.has_pending_diagnostic_updates = true;
 9169        }
 9170
 9171        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9172        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9173            language_server_id,
 9174            name: self
 9175                .language_server_adapter_for_id(language_server_id)
 9176                .map(|adapter| adapter.name()),
 9177            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9178                Default::default(),
 9179            ),
 9180        })
 9181    }
 9182
 9183    pub fn disk_based_diagnostics_finished(
 9184        &mut self,
 9185        language_server_id: LanguageServerId,
 9186        cx: &mut Context<Self>,
 9187    ) {
 9188        if let Some(language_server_status) =
 9189            self.language_server_statuses.get_mut(&language_server_id)
 9190        {
 9191            language_server_status.has_pending_diagnostic_updates = false;
 9192        }
 9193
 9194        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9195        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9196            language_server_id,
 9197            name: self
 9198                .language_server_adapter_for_id(language_server_id)
 9199                .map(|adapter| adapter.name()),
 9200            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9201                Default::default(),
 9202            ),
 9203        })
 9204    }
 9205
 9206    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9207    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9208    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9209    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9210    // the language server might take some time to publish diagnostics.
 9211    fn simulate_disk_based_diagnostics_events_if_needed(
 9212        &mut self,
 9213        language_server_id: LanguageServerId,
 9214        cx: &mut Context<Self>,
 9215    ) {
 9216        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9217
 9218        let Some(LanguageServerState::Running {
 9219            simulate_disk_based_diagnostics_completion,
 9220            adapter,
 9221            ..
 9222        }) = self
 9223            .as_local_mut()
 9224            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9225        else {
 9226            return;
 9227        };
 9228
 9229        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9230            return;
 9231        }
 9232
 9233        let prev_task =
 9234            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9235                cx.background_executor()
 9236                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9237                    .await;
 9238
 9239                this.update(cx, |this, cx| {
 9240                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9241
 9242                    if let Some(LanguageServerState::Running {
 9243                        simulate_disk_based_diagnostics_completion,
 9244                        ..
 9245                    }) = this.as_local_mut().and_then(|local_store| {
 9246                        local_store.language_servers.get_mut(&language_server_id)
 9247                    }) {
 9248                        *simulate_disk_based_diagnostics_completion = None;
 9249                    }
 9250                })
 9251                .ok();
 9252            }));
 9253
 9254        if prev_task.is_none() {
 9255            self.disk_based_diagnostics_started(language_server_id, cx);
 9256        }
 9257    }
 9258
 9259    pub fn language_server_statuses(
 9260        &self,
 9261    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9262        self.language_server_statuses
 9263            .iter()
 9264            .map(|(key, value)| (*key, value))
 9265    }
 9266
 9267    pub(super) fn did_rename_entry(
 9268        &self,
 9269        worktree_id: WorktreeId,
 9270        old_path: &Path,
 9271        new_path: &Path,
 9272        is_dir: bool,
 9273    ) {
 9274        maybe!({
 9275            let local_store = self.as_local()?;
 9276
 9277            let old_uri = lsp::Uri::from_file_path(old_path)
 9278                .ok()
 9279                .map(|uri| uri.to_string())?;
 9280            let new_uri = lsp::Uri::from_file_path(new_path)
 9281                .ok()
 9282                .map(|uri| uri.to_string())?;
 9283
 9284            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9285                let Some(filter) = local_store
 9286                    .language_server_paths_watched_for_rename
 9287                    .get(&language_server.server_id())
 9288                else {
 9289                    continue;
 9290                };
 9291
 9292                if filter.should_send_did_rename(&old_uri, is_dir) {
 9293                    language_server
 9294                        .notify::<DidRenameFiles>(RenameFilesParams {
 9295                            files: vec![FileRename {
 9296                                old_uri: old_uri.clone(),
 9297                                new_uri: new_uri.clone(),
 9298                            }],
 9299                        })
 9300                        .ok();
 9301                }
 9302            }
 9303            Some(())
 9304        });
 9305    }
 9306
 9307    pub(super) fn will_rename_entry(
 9308        this: WeakEntity<Self>,
 9309        worktree_id: WorktreeId,
 9310        old_path: &Path,
 9311        new_path: &Path,
 9312        is_dir: bool,
 9313        cx: AsyncApp,
 9314    ) -> Task<ProjectTransaction> {
 9315        let old_uri = lsp::Uri::from_file_path(old_path)
 9316            .ok()
 9317            .map(|uri| uri.to_string());
 9318        let new_uri = lsp::Uri::from_file_path(new_path)
 9319            .ok()
 9320            .map(|uri| uri.to_string());
 9321        cx.spawn(async move |cx| {
 9322            let mut tasks = vec![];
 9323            this.update(cx, |this, cx| {
 9324                let local_store = this.as_local()?;
 9325                let old_uri = old_uri?;
 9326                let new_uri = new_uri?;
 9327                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9328                    let Some(filter) = local_store
 9329                        .language_server_paths_watched_for_rename
 9330                        .get(&language_server.server_id())
 9331                    else {
 9332                        continue;
 9333                    };
 9334
 9335                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9336                        let apply_edit = cx.spawn({
 9337                            let old_uri = old_uri.clone();
 9338                            let new_uri = new_uri.clone();
 9339                            let language_server = language_server.clone();
 9340                            async move |this, cx| {
 9341                                let edit = language_server
 9342                                    .request::<WillRenameFiles>(RenameFilesParams {
 9343                                        files: vec![FileRename { old_uri, new_uri }],
 9344                                    })
 9345                                    .await
 9346                                    .into_response()
 9347                                    .context("will rename files")
 9348                                    .log_err()
 9349                                    .flatten()?;
 9350
 9351                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9352                                    this.upgrade()?,
 9353                                    edit,
 9354                                    false,
 9355                                    language_server.clone(),
 9356                                    cx,
 9357                                )
 9358                                .await
 9359                                .ok()?;
 9360                                Some(transaction)
 9361                            }
 9362                        });
 9363                        tasks.push(apply_edit);
 9364                    }
 9365                }
 9366                Some(())
 9367            })
 9368            .ok()
 9369            .flatten();
 9370            let mut merged_transaction = ProjectTransaction::default();
 9371            for task in tasks {
 9372                // Await on tasks sequentially so that the order of application of edits is deterministic
 9373                // (at least with regards to the order of registration of language servers)
 9374                if let Some(transaction) = task.await {
 9375                    for (buffer, buffer_transaction) in transaction.0 {
 9376                        merged_transaction.0.insert(buffer, buffer_transaction);
 9377                    }
 9378                }
 9379            }
 9380            merged_transaction
 9381        })
 9382    }
 9383
 9384    fn lsp_notify_abs_paths_changed(
 9385        &mut self,
 9386        server_id: LanguageServerId,
 9387        changes: Vec<PathEvent>,
 9388    ) {
 9389        maybe!({
 9390            let server = self.language_server_for_id(server_id)?;
 9391            let changes = changes
 9392                .into_iter()
 9393                .filter_map(|event| {
 9394                    let typ = match event.kind? {
 9395                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9396                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9397                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9398                    };
 9399                    Some(lsp::FileEvent {
 9400                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9401                        typ,
 9402                    })
 9403                })
 9404                .collect::<Vec<_>>();
 9405            if !changes.is_empty() {
 9406                server
 9407                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9408                        lsp::DidChangeWatchedFilesParams { changes },
 9409                    )
 9410                    .ok();
 9411            }
 9412            Some(())
 9413        });
 9414    }
 9415
 9416    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9417        self.as_local()?.language_server_for_id(id)
 9418    }
 9419
 9420    fn on_lsp_progress(
 9421        &mut self,
 9422        progress_params: lsp::ProgressParams,
 9423        language_server_id: LanguageServerId,
 9424        disk_based_diagnostics_progress_token: Option<String>,
 9425        cx: &mut Context<Self>,
 9426    ) {
 9427        match progress_params.value {
 9428            lsp::ProgressParamsValue::WorkDone(progress) => {
 9429                self.handle_work_done_progress(
 9430                    progress,
 9431                    language_server_id,
 9432                    disk_based_diagnostics_progress_token,
 9433                    ProgressToken::from_lsp(progress_params.token),
 9434                    cx,
 9435                );
 9436            }
 9437            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9438                let identifier = match progress_params.token {
 9439                    lsp::NumberOrString::Number(_) => None,
 9440                    lsp::NumberOrString::String(token) => token
 9441                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9442                        .map(|(_, id)| id.to_owned()),
 9443                };
 9444                if let Some(LanguageServerState::Running {
 9445                    workspace_diagnostics_refresh_tasks,
 9446                    ..
 9447                }) = self
 9448                    .as_local_mut()
 9449                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9450                    && let Some(workspace_diagnostics) =
 9451                        workspace_diagnostics_refresh_tasks.get_mut(&identifier)
 9452                {
 9453                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9454                    self.apply_workspace_diagnostic_report(language_server_id, report, cx)
 9455                }
 9456            }
 9457        }
 9458    }
 9459
 9460    fn handle_work_done_progress(
 9461        &mut self,
 9462        progress: lsp::WorkDoneProgress,
 9463        language_server_id: LanguageServerId,
 9464        disk_based_diagnostics_progress_token: Option<String>,
 9465        token: ProgressToken,
 9466        cx: &mut Context<Self>,
 9467    ) {
 9468        let language_server_status =
 9469            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9470                status
 9471            } else {
 9472                return;
 9473            };
 9474
 9475        if !language_server_status.progress_tokens.contains(&token) {
 9476            return;
 9477        }
 9478
 9479        let is_disk_based_diagnostics_progress =
 9480            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9481                (&disk_based_diagnostics_progress_token, &token)
 9482            {
 9483                token.starts_with(disk_based_token)
 9484            } else {
 9485                false
 9486            };
 9487
 9488        match progress {
 9489            lsp::WorkDoneProgress::Begin(report) => {
 9490                if is_disk_based_diagnostics_progress {
 9491                    self.disk_based_diagnostics_started(language_server_id, cx);
 9492                }
 9493                self.on_lsp_work_start(
 9494                    language_server_id,
 9495                    token.clone(),
 9496                    LanguageServerProgress {
 9497                        title: Some(report.title),
 9498                        is_disk_based_diagnostics_progress,
 9499                        is_cancellable: report.cancellable.unwrap_or(false),
 9500                        message: report.message.clone(),
 9501                        percentage: report.percentage.map(|p| p as usize),
 9502                        last_update_at: cx.background_executor().now(),
 9503                    },
 9504                    cx,
 9505                );
 9506            }
 9507            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9508                language_server_id,
 9509                token,
 9510                LanguageServerProgress {
 9511                    title: None,
 9512                    is_disk_based_diagnostics_progress,
 9513                    is_cancellable: report.cancellable.unwrap_or(false),
 9514                    message: report.message,
 9515                    percentage: report.percentage.map(|p| p as usize),
 9516                    last_update_at: cx.background_executor().now(),
 9517                },
 9518                cx,
 9519            ),
 9520            lsp::WorkDoneProgress::End(_) => {
 9521                language_server_status.progress_tokens.remove(&token);
 9522                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9523                if is_disk_based_diagnostics_progress {
 9524                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9525                }
 9526            }
 9527        }
 9528    }
 9529
 9530    fn on_lsp_work_start(
 9531        &mut self,
 9532        language_server_id: LanguageServerId,
 9533        token: ProgressToken,
 9534        progress: LanguageServerProgress,
 9535        cx: &mut Context<Self>,
 9536    ) {
 9537        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9538            status.pending_work.insert(token.clone(), progress.clone());
 9539            cx.notify();
 9540        }
 9541        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9542            language_server_id,
 9543            name: self
 9544                .language_server_adapter_for_id(language_server_id)
 9545                .map(|adapter| adapter.name()),
 9546            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9547                token: Some(token.to_proto()),
 9548                title: progress.title,
 9549                message: progress.message,
 9550                percentage: progress.percentage.map(|p| p as u32),
 9551                is_cancellable: Some(progress.is_cancellable),
 9552            }),
 9553        })
 9554    }
 9555
 9556    fn on_lsp_work_progress(
 9557        &mut self,
 9558        language_server_id: LanguageServerId,
 9559        token: ProgressToken,
 9560        progress: LanguageServerProgress,
 9561        cx: &mut Context<Self>,
 9562    ) {
 9563        let mut did_update = false;
 9564        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9565            match status.pending_work.entry(token.clone()) {
 9566                btree_map::Entry::Vacant(entry) => {
 9567                    entry.insert(progress.clone());
 9568                    did_update = true;
 9569                }
 9570                btree_map::Entry::Occupied(mut entry) => {
 9571                    let entry = entry.get_mut();
 9572                    if (progress.last_update_at - entry.last_update_at)
 9573                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9574                    {
 9575                        entry.last_update_at = progress.last_update_at;
 9576                        if progress.message.is_some() {
 9577                            entry.message = progress.message.clone();
 9578                        }
 9579                        if progress.percentage.is_some() {
 9580                            entry.percentage = progress.percentage;
 9581                        }
 9582                        if progress.is_cancellable != entry.is_cancellable {
 9583                            entry.is_cancellable = progress.is_cancellable;
 9584                        }
 9585                        did_update = true;
 9586                    }
 9587                }
 9588            }
 9589        }
 9590
 9591        if did_update {
 9592            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9593                language_server_id,
 9594                name: self
 9595                    .language_server_adapter_for_id(language_server_id)
 9596                    .map(|adapter| adapter.name()),
 9597                message: proto::update_language_server::Variant::WorkProgress(
 9598                    proto::LspWorkProgress {
 9599                        token: Some(token.to_proto()),
 9600                        message: progress.message,
 9601                        percentage: progress.percentage.map(|p| p as u32),
 9602                        is_cancellable: Some(progress.is_cancellable),
 9603                    },
 9604                ),
 9605            })
 9606        }
 9607    }
 9608
 9609    fn on_lsp_work_end(
 9610        &mut self,
 9611        language_server_id: LanguageServerId,
 9612        token: ProgressToken,
 9613        cx: &mut Context<Self>,
 9614    ) {
 9615        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9616            if let Some(work) = status.pending_work.remove(&token)
 9617                && !work.is_disk_based_diagnostics_progress
 9618            {
 9619                cx.emit(LspStoreEvent::RefreshInlayHints(language_server_id));
 9620            }
 9621            cx.notify();
 9622        }
 9623
 9624        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9625            language_server_id,
 9626            name: self
 9627                .language_server_adapter_for_id(language_server_id)
 9628                .map(|adapter| adapter.name()),
 9629            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
 9630                token: Some(token.to_proto()),
 9631            }),
 9632        })
 9633    }
 9634
 9635    pub async fn handle_resolve_completion_documentation(
 9636        this: Entity<Self>,
 9637        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
 9638        mut cx: AsyncApp,
 9639    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
 9640        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
 9641
 9642        let completion = this
 9643            .read_with(&cx, |this, cx| {
 9644                let id = LanguageServerId(envelope.payload.language_server_id as usize);
 9645                let server = this
 9646                    .language_server_for_id(id)
 9647                    .with_context(|| format!("No language server {id}"))?;
 9648
 9649                anyhow::Ok(cx.background_spawn(async move {
 9650                    let can_resolve = server
 9651                        .capabilities()
 9652                        .completion_provider
 9653                        .as_ref()
 9654                        .and_then(|options| options.resolve_provider)
 9655                        .unwrap_or(false);
 9656                    if can_resolve {
 9657                        server
 9658                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
 9659                            .await
 9660                            .into_response()
 9661                            .context("resolve completion item")
 9662                    } else {
 9663                        anyhow::Ok(lsp_completion)
 9664                    }
 9665                }))
 9666            })??
 9667            .await?;
 9668
 9669        let mut documentation_is_markdown = false;
 9670        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
 9671        let documentation = match completion.documentation {
 9672            Some(lsp::Documentation::String(text)) => text,
 9673
 9674            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
 9675                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
 9676                value
 9677            }
 9678
 9679            _ => String::new(),
 9680        };
 9681
 9682        // If we have a new buffer_id, that means we're talking to a new client
 9683        // and want to check for new text_edits in the completion too.
 9684        let mut old_replace_start = None;
 9685        let mut old_replace_end = None;
 9686        let mut old_insert_start = None;
 9687        let mut old_insert_end = None;
 9688        let mut new_text = String::default();
 9689        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
 9690            let buffer_snapshot = this.update(&mut cx, |this, cx| {
 9691                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9692                anyhow::Ok(buffer.read(cx).snapshot())
 9693            })??;
 9694
 9695            if let Some(text_edit) = completion.text_edit.as_ref() {
 9696                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
 9697
 9698                if let Some(mut edit) = edit {
 9699                    LineEnding::normalize(&mut edit.new_text);
 9700
 9701                    new_text = edit.new_text;
 9702                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
 9703                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
 9704                    if let Some(insert_range) = edit.insert_range {
 9705                        old_insert_start = Some(serialize_anchor(&insert_range.start));
 9706                        old_insert_end = Some(serialize_anchor(&insert_range.end));
 9707                    }
 9708                }
 9709            }
 9710        }
 9711
 9712        Ok(proto::ResolveCompletionDocumentationResponse {
 9713            documentation,
 9714            documentation_is_markdown,
 9715            old_replace_start,
 9716            old_replace_end,
 9717            new_text,
 9718            lsp_completion,
 9719            old_insert_start,
 9720            old_insert_end,
 9721        })
 9722    }
 9723
 9724    async fn handle_on_type_formatting(
 9725        this: Entity<Self>,
 9726        envelope: TypedEnvelope<proto::OnTypeFormatting>,
 9727        mut cx: AsyncApp,
 9728    ) -> Result<proto::OnTypeFormattingResponse> {
 9729        let on_type_formatting = this.update(&mut cx, |this, cx| {
 9730            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9731            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9732            let position = envelope
 9733                .payload
 9734                .position
 9735                .and_then(deserialize_anchor)
 9736                .context("invalid position")?;
 9737            anyhow::Ok(this.apply_on_type_formatting(
 9738                buffer,
 9739                position,
 9740                envelope.payload.trigger.clone(),
 9741                cx,
 9742            ))
 9743        })??;
 9744
 9745        let transaction = on_type_formatting
 9746            .await?
 9747            .as_ref()
 9748            .map(language::proto::serialize_transaction);
 9749        Ok(proto::OnTypeFormattingResponse { transaction })
 9750    }
 9751
 9752    async fn handle_refresh_inlay_hints(
 9753        lsp_store: Entity<Self>,
 9754        envelope: TypedEnvelope<proto::RefreshInlayHints>,
 9755        mut cx: AsyncApp,
 9756    ) -> Result<proto::Ack> {
 9757        lsp_store.update(&mut cx, |_, cx| {
 9758            cx.emit(LspStoreEvent::RefreshInlayHints(
 9759                LanguageServerId::from_proto(envelope.payload.server_id),
 9760            ));
 9761        })?;
 9762        Ok(proto::Ack {})
 9763    }
 9764
 9765    async fn handle_pull_workspace_diagnostics(
 9766        lsp_store: Entity<Self>,
 9767        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
 9768        mut cx: AsyncApp,
 9769    ) -> Result<proto::Ack> {
 9770        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
 9771        lsp_store.update(&mut cx, |lsp_store, _| {
 9772            lsp_store.pull_workspace_diagnostics(server_id);
 9773        })?;
 9774        Ok(proto::Ack {})
 9775    }
 9776
 9777    async fn handle_get_color_presentation(
 9778        lsp_store: Entity<Self>,
 9779        envelope: TypedEnvelope<proto::GetColorPresentation>,
 9780        mut cx: AsyncApp,
 9781    ) -> Result<proto::GetColorPresentationResponse> {
 9782        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9783        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9784            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9785        })??;
 9786
 9787        let color = envelope
 9788            .payload
 9789            .color
 9790            .context("invalid color resolve request")?;
 9791        let start = color
 9792            .lsp_range_start
 9793            .context("invalid color resolve request")?;
 9794        let end = color
 9795            .lsp_range_end
 9796            .context("invalid color resolve request")?;
 9797
 9798        let color = DocumentColor {
 9799            lsp_range: lsp::Range {
 9800                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
 9801                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
 9802            },
 9803            color: lsp::Color {
 9804                red: color.red,
 9805                green: color.green,
 9806                blue: color.blue,
 9807                alpha: color.alpha,
 9808            },
 9809            resolved: false,
 9810            color_presentations: Vec::new(),
 9811        };
 9812        let resolved_color = lsp_store
 9813            .update(&mut cx, |lsp_store, cx| {
 9814                lsp_store.resolve_color_presentation(
 9815                    color,
 9816                    buffer.clone(),
 9817                    LanguageServerId(envelope.payload.server_id as usize),
 9818                    cx,
 9819                )
 9820            })?
 9821            .await
 9822            .context("resolving color presentation")?;
 9823
 9824        Ok(proto::GetColorPresentationResponse {
 9825            presentations: resolved_color
 9826                .color_presentations
 9827                .into_iter()
 9828                .map(|presentation| proto::ColorPresentation {
 9829                    label: presentation.label.to_string(),
 9830                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
 9831                    additional_text_edits: presentation
 9832                        .additional_text_edits
 9833                        .into_iter()
 9834                        .map(serialize_lsp_edit)
 9835                        .collect(),
 9836                })
 9837                .collect(),
 9838        })
 9839    }
 9840
 9841    async fn handle_resolve_inlay_hint(
 9842        lsp_store: Entity<Self>,
 9843        envelope: TypedEnvelope<proto::ResolveInlayHint>,
 9844        mut cx: AsyncApp,
 9845    ) -> Result<proto::ResolveInlayHintResponse> {
 9846        let proto_hint = envelope
 9847            .payload
 9848            .hint
 9849            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
 9850        let hint = InlayHints::proto_to_project_hint(proto_hint)
 9851            .context("resolved proto inlay hint conversion")?;
 9852        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9853            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9854            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9855        })??;
 9856        let response_hint = lsp_store
 9857            .update(&mut cx, |lsp_store, cx| {
 9858                lsp_store.resolve_inlay_hint(
 9859                    hint,
 9860                    buffer,
 9861                    LanguageServerId(envelope.payload.language_server_id as usize),
 9862                    cx,
 9863                )
 9864            })?
 9865            .await
 9866            .context("inlay hints fetch")?;
 9867        Ok(proto::ResolveInlayHintResponse {
 9868            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
 9869        })
 9870    }
 9871
 9872    async fn handle_refresh_code_lens(
 9873        this: Entity<Self>,
 9874        _: TypedEnvelope<proto::RefreshCodeLens>,
 9875        mut cx: AsyncApp,
 9876    ) -> Result<proto::Ack> {
 9877        this.update(&mut cx, |_, cx| {
 9878            cx.emit(LspStoreEvent::RefreshCodeLens);
 9879        })?;
 9880        Ok(proto::Ack {})
 9881    }
 9882
 9883    async fn handle_open_buffer_for_symbol(
 9884        this: Entity<Self>,
 9885        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
 9886        mut cx: AsyncApp,
 9887    ) -> Result<proto::OpenBufferForSymbolResponse> {
 9888        let peer_id = envelope.original_sender_id().unwrap_or_default();
 9889        let symbol = envelope.payload.symbol.context("invalid symbol")?;
 9890        let symbol = Self::deserialize_symbol(symbol)?;
 9891        this.read_with(&cx, |this, _| {
 9892            if let SymbolLocation::OutsideProject {
 9893                abs_path,
 9894                signature,
 9895            } = &symbol.path
 9896            {
 9897                let new_signature = this.symbol_signature(&abs_path);
 9898                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
 9899            }
 9900            Ok(())
 9901        })??;
 9902        let buffer = this
 9903            .update(&mut cx, |this, cx| {
 9904                this.open_buffer_for_symbol(
 9905                    &Symbol {
 9906                        language_server_name: symbol.language_server_name,
 9907                        source_worktree_id: symbol.source_worktree_id,
 9908                        source_language_server_id: symbol.source_language_server_id,
 9909                        path: symbol.path,
 9910                        name: symbol.name,
 9911                        kind: symbol.kind,
 9912                        range: symbol.range,
 9913                        label: CodeLabel::default(),
 9914                    },
 9915                    cx,
 9916                )
 9917            })?
 9918            .await?;
 9919
 9920        this.update(&mut cx, |this, cx| {
 9921            let is_private = buffer
 9922                .read(cx)
 9923                .file()
 9924                .map(|f| f.is_private())
 9925                .unwrap_or_default();
 9926            if is_private {
 9927                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
 9928            } else {
 9929                this.buffer_store
 9930                    .update(cx, |buffer_store, cx| {
 9931                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
 9932                    })
 9933                    .detach_and_log_err(cx);
 9934                let buffer_id = buffer.read(cx).remote_id().to_proto();
 9935                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
 9936            }
 9937        })?
 9938    }
 9939
 9940    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
 9941        let mut hasher = Sha256::new();
 9942        hasher.update(abs_path.to_string_lossy().as_bytes());
 9943        hasher.update(self.nonce.to_be_bytes());
 9944        hasher.finalize().as_slice().try_into().unwrap()
 9945    }
 9946
 9947    pub async fn handle_get_project_symbols(
 9948        this: Entity<Self>,
 9949        envelope: TypedEnvelope<proto::GetProjectSymbols>,
 9950        mut cx: AsyncApp,
 9951    ) -> Result<proto::GetProjectSymbolsResponse> {
 9952        let symbols = this
 9953            .update(&mut cx, |this, cx| {
 9954                this.symbols(&envelope.payload.query, cx)
 9955            })?
 9956            .await?;
 9957
 9958        Ok(proto::GetProjectSymbolsResponse {
 9959            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
 9960        })
 9961    }
 9962
 9963    pub async fn handle_restart_language_servers(
 9964        this: Entity<Self>,
 9965        envelope: TypedEnvelope<proto::RestartLanguageServers>,
 9966        mut cx: AsyncApp,
 9967    ) -> Result<proto::Ack> {
 9968        this.update(&mut cx, |lsp_store, cx| {
 9969            let buffers =
 9970                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9971            lsp_store.restart_language_servers_for_buffers(
 9972                buffers,
 9973                envelope
 9974                    .payload
 9975                    .only_servers
 9976                    .into_iter()
 9977                    .filter_map(|selector| {
 9978                        Some(match selector.selector? {
 9979                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9980                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9981                            }
 9982                            proto::language_server_selector::Selector::Name(name) => {
 9983                                LanguageServerSelector::Name(LanguageServerName(
 9984                                    SharedString::from(name),
 9985                                ))
 9986                            }
 9987                        })
 9988                    })
 9989                    .collect(),
 9990                cx,
 9991            );
 9992        })?;
 9993
 9994        Ok(proto::Ack {})
 9995    }
 9996
 9997    pub async fn handle_stop_language_servers(
 9998        lsp_store: Entity<Self>,
 9999        envelope: TypedEnvelope<proto::StopLanguageServers>,
10000        mut cx: AsyncApp,
10001    ) -> Result<proto::Ack> {
10002        lsp_store.update(&mut cx, |lsp_store, cx| {
10003            if envelope.payload.all
10004                && envelope.payload.also_servers.is_empty()
10005                && envelope.payload.buffer_ids.is_empty()
10006            {
10007                lsp_store.stop_all_language_servers(cx);
10008            } else {
10009                let buffers =
10010                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10011                lsp_store
10012                    .stop_language_servers_for_buffers(
10013                        buffers,
10014                        envelope
10015                            .payload
10016                            .also_servers
10017                            .into_iter()
10018                            .filter_map(|selector| {
10019                                Some(match selector.selector? {
10020                                    proto::language_server_selector::Selector::ServerId(
10021                                        server_id,
10022                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10023                                        server_id,
10024                                    )),
10025                                    proto::language_server_selector::Selector::Name(name) => {
10026                                        LanguageServerSelector::Name(LanguageServerName(
10027                                            SharedString::from(name),
10028                                        ))
10029                                    }
10030                                })
10031                            })
10032                            .collect(),
10033                        cx,
10034                    )
10035                    .detach_and_log_err(cx);
10036            }
10037        })?;
10038
10039        Ok(proto::Ack {})
10040    }
10041
10042    pub async fn handle_cancel_language_server_work(
10043        lsp_store: Entity<Self>,
10044        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10045        mut cx: AsyncApp,
10046    ) -> Result<proto::Ack> {
10047        lsp_store.update(&mut cx, |lsp_store, cx| {
10048            if let Some(work) = envelope.payload.work {
10049                match work {
10050                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10051                        let buffers =
10052                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10053                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10054                    }
10055                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10056                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10057                        let token = work
10058                            .token
10059                            .map(|token| {
10060                                ProgressToken::from_proto(token)
10061                                    .context("invalid work progress token")
10062                            })
10063                            .transpose()?;
10064                        lsp_store.cancel_language_server_work(server_id, token, cx);
10065                    }
10066                }
10067            }
10068            anyhow::Ok(())
10069        })??;
10070
10071        Ok(proto::Ack {})
10072    }
10073
10074    fn buffer_ids_to_buffers(
10075        &mut self,
10076        buffer_ids: impl Iterator<Item = u64>,
10077        cx: &mut Context<Self>,
10078    ) -> Vec<Entity<Buffer>> {
10079        buffer_ids
10080            .into_iter()
10081            .flat_map(|buffer_id| {
10082                self.buffer_store
10083                    .read(cx)
10084                    .get(BufferId::new(buffer_id).log_err()?)
10085            })
10086            .collect::<Vec<_>>()
10087    }
10088
10089    async fn handle_apply_additional_edits_for_completion(
10090        this: Entity<Self>,
10091        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10092        mut cx: AsyncApp,
10093    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10094        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10095            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10096            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10097            let completion = Self::deserialize_completion(
10098                envelope.payload.completion.context("invalid completion")?,
10099            )?;
10100            anyhow::Ok((buffer, completion))
10101        })??;
10102
10103        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10104            this.apply_additional_edits_for_completion(
10105                buffer,
10106                Rc::new(RefCell::new(Box::new([Completion {
10107                    replace_range: completion.replace_range,
10108                    new_text: completion.new_text,
10109                    source: completion.source,
10110                    documentation: None,
10111                    label: CodeLabel::default(),
10112                    insert_text_mode: None,
10113                    icon_path: None,
10114                    confirm: None,
10115                }]))),
10116                0,
10117                false,
10118                cx,
10119            )
10120        })?;
10121
10122        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10123            transaction: apply_additional_edits
10124                .await?
10125                .as_ref()
10126                .map(language::proto::serialize_transaction),
10127        })
10128    }
10129
10130    pub fn last_formatting_failure(&self) -> Option<&str> {
10131        self.last_formatting_failure.as_deref()
10132    }
10133
10134    pub fn reset_last_formatting_failure(&mut self) {
10135        self.last_formatting_failure = None;
10136    }
10137
10138    pub fn environment_for_buffer(
10139        &self,
10140        buffer: &Entity<Buffer>,
10141        cx: &mut Context<Self>,
10142    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10143        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10144            environment.update(cx, |env, cx| {
10145                env.get_buffer_environment(buffer, &self.worktree_store, cx)
10146            })
10147        } else {
10148            Task::ready(None).shared()
10149        }
10150    }
10151
10152    pub fn format(
10153        &mut self,
10154        buffers: HashSet<Entity<Buffer>>,
10155        target: LspFormatTarget,
10156        push_to_history: bool,
10157        trigger: FormatTrigger,
10158        cx: &mut Context<Self>,
10159    ) -> Task<anyhow::Result<ProjectTransaction>> {
10160        let logger = zlog::scoped!("format");
10161        if self.as_local().is_some() {
10162            zlog::trace!(logger => "Formatting locally");
10163            let logger = zlog::scoped!(logger => "local");
10164            let buffers = buffers
10165                .into_iter()
10166                .map(|buffer_handle| {
10167                    let buffer = buffer_handle.read(cx);
10168                    let buffer_abs_path = File::from_dyn(buffer.file())
10169                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10170
10171                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10172                })
10173                .collect::<Vec<_>>();
10174
10175            cx.spawn(async move |lsp_store, cx| {
10176                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10177
10178                for (handle, abs_path, id) in buffers {
10179                    let env = lsp_store
10180                        .update(cx, |lsp_store, cx| {
10181                            lsp_store.environment_for_buffer(&handle, cx)
10182                        })?
10183                        .await;
10184
10185                    let ranges = match &target {
10186                        LspFormatTarget::Buffers => None,
10187                        LspFormatTarget::Ranges(ranges) => {
10188                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10189                        }
10190                    };
10191
10192                    formattable_buffers.push(FormattableBuffer {
10193                        handle,
10194                        abs_path,
10195                        env,
10196                        ranges,
10197                    });
10198                }
10199                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10200
10201                let format_timer = zlog::time!(logger => "Formatting buffers");
10202                let result = LocalLspStore::format_locally(
10203                    lsp_store.clone(),
10204                    formattable_buffers,
10205                    push_to_history,
10206                    trigger,
10207                    logger,
10208                    cx,
10209                )
10210                .await;
10211                format_timer.end();
10212
10213                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10214
10215                lsp_store.update(cx, |lsp_store, _| {
10216                    lsp_store.update_last_formatting_failure(&result);
10217                })?;
10218
10219                result
10220            })
10221        } else if let Some((client, project_id)) = self.upstream_client() {
10222            zlog::trace!(logger => "Formatting remotely");
10223            let logger = zlog::scoped!(logger => "remote");
10224            // Don't support formatting ranges via remote
10225            match target {
10226                LspFormatTarget::Buffers => {}
10227                LspFormatTarget::Ranges(_) => {
10228                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10229                    return Task::ready(Ok(ProjectTransaction::default()));
10230                }
10231            }
10232
10233            let buffer_store = self.buffer_store();
10234            cx.spawn(async move |lsp_store, cx| {
10235                zlog::trace!(logger => "Sending remote format request");
10236                let request_timer = zlog::time!(logger => "remote format request");
10237                let result = client
10238                    .request(proto::FormatBuffers {
10239                        project_id,
10240                        trigger: trigger as i32,
10241                        buffer_ids: buffers
10242                            .iter()
10243                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10244                            .collect::<Result<_>>()?,
10245                    })
10246                    .await
10247                    .and_then(|result| result.transaction.context("missing transaction"));
10248                request_timer.end();
10249
10250                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10251
10252                lsp_store.update(cx, |lsp_store, _| {
10253                    lsp_store.update_last_formatting_failure(&result);
10254                })?;
10255
10256                let transaction_response = result?;
10257                let _timer = zlog::time!(logger => "deserializing project transaction");
10258                buffer_store
10259                    .update(cx, |buffer_store, cx| {
10260                        buffer_store.deserialize_project_transaction(
10261                            transaction_response,
10262                            push_to_history,
10263                            cx,
10264                        )
10265                    })?
10266                    .await
10267            })
10268        } else {
10269            zlog::trace!(logger => "Not formatting");
10270            Task::ready(Ok(ProjectTransaction::default()))
10271        }
10272    }
10273
10274    async fn handle_format_buffers(
10275        this: Entity<Self>,
10276        envelope: TypedEnvelope<proto::FormatBuffers>,
10277        mut cx: AsyncApp,
10278    ) -> Result<proto::FormatBuffersResponse> {
10279        let sender_id = envelope.original_sender_id().unwrap_or_default();
10280        let format = this.update(&mut cx, |this, cx| {
10281            let mut buffers = HashSet::default();
10282            for buffer_id in &envelope.payload.buffer_ids {
10283                let buffer_id = BufferId::new(*buffer_id)?;
10284                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10285            }
10286            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10287            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10288        })??;
10289
10290        let project_transaction = format.await?;
10291        let project_transaction = this.update(&mut cx, |this, cx| {
10292            this.buffer_store.update(cx, |buffer_store, cx| {
10293                buffer_store.serialize_project_transaction_for_peer(
10294                    project_transaction,
10295                    sender_id,
10296                    cx,
10297                )
10298            })
10299        })?;
10300        Ok(proto::FormatBuffersResponse {
10301            transaction: Some(project_transaction),
10302        })
10303    }
10304
10305    async fn handle_apply_code_action_kind(
10306        this: Entity<Self>,
10307        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10308        mut cx: AsyncApp,
10309    ) -> Result<proto::ApplyCodeActionKindResponse> {
10310        let sender_id = envelope.original_sender_id().unwrap_or_default();
10311        let format = this.update(&mut cx, |this, cx| {
10312            let mut buffers = HashSet::default();
10313            for buffer_id in &envelope.payload.buffer_ids {
10314                let buffer_id = BufferId::new(*buffer_id)?;
10315                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10316            }
10317            let kind = match envelope.payload.kind.as_str() {
10318                "" => CodeActionKind::EMPTY,
10319                "quickfix" => CodeActionKind::QUICKFIX,
10320                "refactor" => CodeActionKind::REFACTOR,
10321                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10322                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10323                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10324                "source" => CodeActionKind::SOURCE,
10325                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10326                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10327                _ => anyhow::bail!(
10328                    "Invalid code action kind {}",
10329                    envelope.payload.kind.as_str()
10330                ),
10331            };
10332            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10333        })??;
10334
10335        let project_transaction = format.await?;
10336        let project_transaction = this.update(&mut cx, |this, cx| {
10337            this.buffer_store.update(cx, |buffer_store, cx| {
10338                buffer_store.serialize_project_transaction_for_peer(
10339                    project_transaction,
10340                    sender_id,
10341                    cx,
10342                )
10343            })
10344        })?;
10345        Ok(proto::ApplyCodeActionKindResponse {
10346            transaction: Some(project_transaction),
10347        })
10348    }
10349
10350    async fn shutdown_language_server(
10351        server_state: Option<LanguageServerState>,
10352        name: LanguageServerName,
10353        cx: &mut AsyncApp,
10354    ) {
10355        let server = match server_state {
10356            Some(LanguageServerState::Starting { startup, .. }) => {
10357                let mut timer = cx
10358                    .background_executor()
10359                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10360                    .fuse();
10361
10362                select! {
10363                    server = startup.fuse() => server,
10364                    () = timer => {
10365                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10366                        None
10367                    },
10368                }
10369            }
10370
10371            Some(LanguageServerState::Running { server, .. }) => Some(server),
10372
10373            None => None,
10374        };
10375
10376        if let Some(server) = server
10377            && let Some(shutdown) = server.shutdown()
10378        {
10379            shutdown.await;
10380        }
10381    }
10382
10383    // Returns a list of all of the worktrees which no longer have a language server and the root path
10384    // for the stopped server
10385    fn stop_local_language_server(
10386        &mut self,
10387        server_id: LanguageServerId,
10388        cx: &mut Context<Self>,
10389    ) -> Task<()> {
10390        let local = match &mut self.mode {
10391            LspStoreMode::Local(local) => local,
10392            _ => {
10393                return Task::ready(());
10394            }
10395        };
10396
10397        // Remove this server ID from all entries in the given worktree.
10398        local
10399            .language_server_ids
10400            .retain(|_, state| state.id != server_id);
10401        self.buffer_store.update(cx, |buffer_store, cx| {
10402            for buffer in buffer_store.buffers() {
10403                buffer.update(cx, |buffer, cx| {
10404                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10405                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10406                });
10407            }
10408        });
10409
10410        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10411            summaries.retain(|path, summaries_by_server_id| {
10412                if summaries_by_server_id.remove(&server_id).is_some() {
10413                    if let Some((client, project_id)) = self.downstream_client.clone() {
10414                        client
10415                            .send(proto::UpdateDiagnosticSummary {
10416                                project_id,
10417                                worktree_id: worktree_id.to_proto(),
10418                                summary: Some(proto::DiagnosticSummary {
10419                                    path: path.as_ref().to_proto(),
10420                                    language_server_id: server_id.0 as u64,
10421                                    error_count: 0,
10422                                    warning_count: 0,
10423                                }),
10424                                more_summaries: Vec::new(),
10425                            })
10426                            .log_err();
10427                    }
10428                    !summaries_by_server_id.is_empty()
10429                } else {
10430                    true
10431                }
10432            });
10433        }
10434
10435        let local = self.as_local_mut().unwrap();
10436        for diagnostics in local.diagnostics.values_mut() {
10437            diagnostics.retain(|_, diagnostics_by_server_id| {
10438                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10439                    diagnostics_by_server_id.remove(ix);
10440                    !diagnostics_by_server_id.is_empty()
10441                } else {
10442                    true
10443                }
10444            });
10445        }
10446        local.language_server_watched_paths.remove(&server_id);
10447
10448        let server_state = local.language_servers.remove(&server_id);
10449        self.cleanup_lsp_data(server_id);
10450        let name = self
10451            .language_server_statuses
10452            .remove(&server_id)
10453            .map(|status| status.name)
10454            .or_else(|| {
10455                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10456                    Some(adapter.name())
10457                } else {
10458                    None
10459                }
10460            });
10461
10462        if let Some(name) = name {
10463            log::info!("stopping language server {name}");
10464            self.languages
10465                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10466            cx.notify();
10467
10468            return cx.spawn(async move |lsp_store, cx| {
10469                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10470                lsp_store
10471                    .update(cx, |lsp_store, cx| {
10472                        lsp_store
10473                            .languages
10474                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10475                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10476                        cx.notify();
10477                    })
10478                    .ok();
10479            });
10480        }
10481
10482        if server_state.is_some() {
10483            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10484        }
10485        Task::ready(())
10486    }
10487
10488    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10489        if let Some((client, project_id)) = self.upstream_client() {
10490            let request = client.request(proto::StopLanguageServers {
10491                project_id,
10492                buffer_ids: Vec::new(),
10493                also_servers: Vec::new(),
10494                all: true,
10495            });
10496            cx.background_spawn(request).detach_and_log_err(cx);
10497        } else {
10498            let Some(local) = self.as_local_mut() else {
10499                return;
10500            };
10501            let language_servers_to_stop = local
10502                .language_server_ids
10503                .values()
10504                .map(|state| state.id)
10505                .collect();
10506            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10507            let tasks = language_servers_to_stop
10508                .into_iter()
10509                .map(|server| self.stop_local_language_server(server, cx))
10510                .collect::<Vec<_>>();
10511            cx.background_spawn(async move {
10512                futures::future::join_all(tasks).await;
10513            })
10514            .detach();
10515        }
10516    }
10517
10518    pub fn restart_language_servers_for_buffers(
10519        &mut self,
10520        buffers: Vec<Entity<Buffer>>,
10521        only_restart_servers: HashSet<LanguageServerSelector>,
10522        cx: &mut Context<Self>,
10523    ) {
10524        if let Some((client, project_id)) = self.upstream_client() {
10525            let request = client.request(proto::RestartLanguageServers {
10526                project_id,
10527                buffer_ids: buffers
10528                    .into_iter()
10529                    .map(|b| b.read(cx).remote_id().to_proto())
10530                    .collect(),
10531                only_servers: only_restart_servers
10532                    .into_iter()
10533                    .map(|selector| {
10534                        let selector = match selector {
10535                            LanguageServerSelector::Id(language_server_id) => {
10536                                proto::language_server_selector::Selector::ServerId(
10537                                    language_server_id.to_proto(),
10538                                )
10539                            }
10540                            LanguageServerSelector::Name(language_server_name) => {
10541                                proto::language_server_selector::Selector::Name(
10542                                    language_server_name.to_string(),
10543                                )
10544                            }
10545                        };
10546                        proto::LanguageServerSelector {
10547                            selector: Some(selector),
10548                        }
10549                    })
10550                    .collect(),
10551                all: false,
10552            });
10553            cx.background_spawn(request).detach_and_log_err(cx);
10554        } else {
10555            let stop_task = if only_restart_servers.is_empty() {
10556                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10557            } else {
10558                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10559            };
10560            cx.spawn(async move |lsp_store, cx| {
10561                stop_task.await;
10562                lsp_store
10563                    .update(cx, |lsp_store, cx| {
10564                        for buffer in buffers {
10565                            lsp_store.register_buffer_with_language_servers(
10566                                &buffer,
10567                                only_restart_servers.clone(),
10568                                true,
10569                                cx,
10570                            );
10571                        }
10572                    })
10573                    .ok()
10574            })
10575            .detach();
10576        }
10577    }
10578
10579    pub fn stop_language_servers_for_buffers(
10580        &mut self,
10581        buffers: Vec<Entity<Buffer>>,
10582        also_stop_servers: HashSet<LanguageServerSelector>,
10583        cx: &mut Context<Self>,
10584    ) -> Task<Result<()>> {
10585        if let Some((client, project_id)) = self.upstream_client() {
10586            let request = client.request(proto::StopLanguageServers {
10587                project_id,
10588                buffer_ids: buffers
10589                    .into_iter()
10590                    .map(|b| b.read(cx).remote_id().to_proto())
10591                    .collect(),
10592                also_servers: also_stop_servers
10593                    .into_iter()
10594                    .map(|selector| {
10595                        let selector = match selector {
10596                            LanguageServerSelector::Id(language_server_id) => {
10597                                proto::language_server_selector::Selector::ServerId(
10598                                    language_server_id.to_proto(),
10599                                )
10600                            }
10601                            LanguageServerSelector::Name(language_server_name) => {
10602                                proto::language_server_selector::Selector::Name(
10603                                    language_server_name.to_string(),
10604                                )
10605                            }
10606                        };
10607                        proto::LanguageServerSelector {
10608                            selector: Some(selector),
10609                        }
10610                    })
10611                    .collect(),
10612                all: false,
10613            });
10614            cx.background_spawn(async move {
10615                let _ = request.await?;
10616                Ok(())
10617            })
10618        } else {
10619            let task =
10620                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10621            cx.background_spawn(async move {
10622                task.await;
10623                Ok(())
10624            })
10625        }
10626    }
10627
10628    fn stop_local_language_servers_for_buffers(
10629        &mut self,
10630        buffers: &[Entity<Buffer>],
10631        also_stop_servers: HashSet<LanguageServerSelector>,
10632        cx: &mut Context<Self>,
10633    ) -> Task<()> {
10634        let Some(local) = self.as_local_mut() else {
10635            return Task::ready(());
10636        };
10637        let mut language_server_names_to_stop = BTreeSet::default();
10638        let mut language_servers_to_stop = also_stop_servers
10639            .into_iter()
10640            .flat_map(|selector| match selector {
10641                LanguageServerSelector::Id(id) => Some(id),
10642                LanguageServerSelector::Name(name) => {
10643                    language_server_names_to_stop.insert(name);
10644                    None
10645                }
10646            })
10647            .collect::<BTreeSet<_>>();
10648
10649        let mut covered_worktrees = HashSet::default();
10650        for buffer in buffers {
10651            buffer.update(cx, |buffer, cx| {
10652                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
10653                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
10654                    && covered_worktrees.insert(worktree_id)
10655                {
10656                    language_server_names_to_stop.retain(|name| {
10657                        let old_ids_count = language_servers_to_stop.len();
10658                        let all_language_servers_with_this_name = local
10659                            .language_server_ids
10660                            .iter()
10661                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
10662                        language_servers_to_stop.extend(all_language_servers_with_this_name);
10663                        old_ids_count == language_servers_to_stop.len()
10664                    });
10665                }
10666            });
10667        }
10668        for name in language_server_names_to_stop {
10669            language_servers_to_stop.extend(
10670                local
10671                    .language_server_ids
10672                    .iter()
10673                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
10674            );
10675        }
10676
10677        local.lsp_tree.remove_nodes(&language_servers_to_stop);
10678        let tasks = language_servers_to_stop
10679            .into_iter()
10680            .map(|server| self.stop_local_language_server(server, cx))
10681            .collect::<Vec<_>>();
10682
10683        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
10684    }
10685
10686    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
10687        let (worktree, relative_path) =
10688            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
10689
10690        let project_path = ProjectPath {
10691            worktree_id: worktree.read(cx).id(),
10692            path: relative_path,
10693        };
10694
10695        Some(
10696            self.buffer_store()
10697                .read(cx)
10698                .get_by_path(&project_path)?
10699                .read(cx),
10700        )
10701    }
10702
10703    #[cfg(any(test, feature = "test-support"))]
10704    pub fn update_diagnostics(
10705        &mut self,
10706        server_id: LanguageServerId,
10707        diagnostics: lsp::PublishDiagnosticsParams,
10708        result_id: Option<String>,
10709        source_kind: DiagnosticSourceKind,
10710        disk_based_sources: &[String],
10711        cx: &mut Context<Self>,
10712    ) -> Result<()> {
10713        self.merge_lsp_diagnostics(
10714            source_kind,
10715            vec![DocumentDiagnosticsUpdate {
10716                diagnostics,
10717                result_id,
10718                server_id,
10719                disk_based_sources: Cow::Borrowed(disk_based_sources),
10720            }],
10721            |_, _, _| false,
10722            cx,
10723        )
10724    }
10725
10726    pub fn merge_lsp_diagnostics(
10727        &mut self,
10728        source_kind: DiagnosticSourceKind,
10729        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
10730        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
10731        cx: &mut Context<Self>,
10732    ) -> Result<()> {
10733        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
10734        let updates = lsp_diagnostics
10735            .into_iter()
10736            .filter_map(|update| {
10737                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
10738                Some(DocumentDiagnosticsUpdate {
10739                    diagnostics: self.lsp_to_document_diagnostics(
10740                        abs_path,
10741                        source_kind,
10742                        update.server_id,
10743                        update.diagnostics,
10744                        &update.disk_based_sources,
10745                    ),
10746                    result_id: update.result_id,
10747                    server_id: update.server_id,
10748                    disk_based_sources: update.disk_based_sources,
10749                })
10750            })
10751            .collect();
10752        self.merge_diagnostic_entries(updates, merge, cx)?;
10753        Ok(())
10754    }
10755
10756    fn lsp_to_document_diagnostics(
10757        &mut self,
10758        document_abs_path: PathBuf,
10759        source_kind: DiagnosticSourceKind,
10760        server_id: LanguageServerId,
10761        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
10762        disk_based_sources: &[String],
10763    ) -> DocumentDiagnostics {
10764        let mut diagnostics = Vec::default();
10765        let mut primary_diagnostic_group_ids = HashMap::default();
10766        let mut sources_by_group_id = HashMap::default();
10767        let mut supporting_diagnostics = HashMap::default();
10768
10769        let adapter = self.language_server_adapter_for_id(server_id);
10770
10771        // Ensure that primary diagnostics are always the most severe
10772        lsp_diagnostics
10773            .diagnostics
10774            .sort_by_key(|item| item.severity);
10775
10776        for diagnostic in &lsp_diagnostics.diagnostics {
10777            let source = diagnostic.source.as_ref();
10778            let range = range_from_lsp(diagnostic.range);
10779            let is_supporting = diagnostic
10780                .related_information
10781                .as_ref()
10782                .is_some_and(|infos| {
10783                    infos.iter().any(|info| {
10784                        primary_diagnostic_group_ids.contains_key(&(
10785                            source,
10786                            diagnostic.code.clone(),
10787                            range_from_lsp(info.location.range),
10788                        ))
10789                    })
10790                });
10791
10792            let is_unnecessary = diagnostic
10793                .tags
10794                .as_ref()
10795                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
10796
10797            let underline = self
10798                .language_server_adapter_for_id(server_id)
10799                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
10800
10801            if is_supporting {
10802                supporting_diagnostics.insert(
10803                    (source, diagnostic.code.clone(), range),
10804                    (diagnostic.severity, is_unnecessary),
10805                );
10806            } else {
10807                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
10808                let is_disk_based =
10809                    source.is_some_and(|source| disk_based_sources.contains(source));
10810
10811                sources_by_group_id.insert(group_id, source);
10812                primary_diagnostic_group_ids
10813                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
10814
10815                diagnostics.push(DiagnosticEntry {
10816                    range,
10817                    diagnostic: Diagnostic {
10818                        source: diagnostic.source.clone(),
10819                        source_kind,
10820                        code: diagnostic.code.clone(),
10821                        code_description: diagnostic
10822                            .code_description
10823                            .as_ref()
10824                            .and_then(|d| d.href.clone()),
10825                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
10826                        markdown: adapter.as_ref().and_then(|adapter| {
10827                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
10828                        }),
10829                        message: diagnostic.message.trim().to_string(),
10830                        group_id,
10831                        is_primary: true,
10832                        is_disk_based,
10833                        is_unnecessary,
10834                        underline,
10835                        data: diagnostic.data.clone(),
10836                    },
10837                });
10838                if let Some(infos) = &diagnostic.related_information {
10839                    for info in infos {
10840                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
10841                            let range = range_from_lsp(info.location.range);
10842                            diagnostics.push(DiagnosticEntry {
10843                                range,
10844                                diagnostic: Diagnostic {
10845                                    source: diagnostic.source.clone(),
10846                                    source_kind,
10847                                    code: diagnostic.code.clone(),
10848                                    code_description: diagnostic
10849                                        .code_description
10850                                        .as_ref()
10851                                        .and_then(|d| d.href.clone()),
10852                                    severity: DiagnosticSeverity::INFORMATION,
10853                                    markdown: adapter.as_ref().and_then(|adapter| {
10854                                        adapter.diagnostic_message_to_markdown(&info.message)
10855                                    }),
10856                                    message: info.message.trim().to_string(),
10857                                    group_id,
10858                                    is_primary: false,
10859                                    is_disk_based,
10860                                    is_unnecessary: false,
10861                                    underline,
10862                                    data: diagnostic.data.clone(),
10863                                },
10864                            });
10865                        }
10866                    }
10867                }
10868            }
10869        }
10870
10871        for entry in &mut diagnostics {
10872            let diagnostic = &mut entry.diagnostic;
10873            if !diagnostic.is_primary {
10874                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
10875                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
10876                    source,
10877                    diagnostic.code.clone(),
10878                    entry.range.clone(),
10879                )) {
10880                    if let Some(severity) = severity {
10881                        diagnostic.severity = severity;
10882                    }
10883                    diagnostic.is_unnecessary = is_unnecessary;
10884                }
10885            }
10886        }
10887
10888        DocumentDiagnostics {
10889            diagnostics,
10890            document_abs_path,
10891            version: lsp_diagnostics.version,
10892        }
10893    }
10894
10895    fn insert_newly_running_language_server(
10896        &mut self,
10897        adapter: Arc<CachedLspAdapter>,
10898        language_server: Arc<LanguageServer>,
10899        server_id: LanguageServerId,
10900        key: LanguageServerSeed,
10901        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
10902        cx: &mut Context<Self>,
10903    ) {
10904        let Some(local) = self.as_local_mut() else {
10905            return;
10906        };
10907        // If the language server for this key doesn't match the server id, don't store the
10908        // server. Which will cause it to be dropped, killing the process
10909        if local
10910            .language_server_ids
10911            .get(&key)
10912            .map(|state| state.id != server_id)
10913            .unwrap_or(false)
10914        {
10915            return;
10916        }
10917
10918        // Update language_servers collection with Running variant of LanguageServerState
10919        // indicating that the server is up and running and ready
10920        let workspace_folders = workspace_folders.lock().clone();
10921        language_server.set_workspace_folders(workspace_folders);
10922
10923        let workspace_diagnostics_refresh_tasks = language_server
10924            .capabilities()
10925            .diagnostic_provider
10926            .and_then(|provider| {
10927                local
10928                    .language_server_dynamic_registrations
10929                    .entry(server_id)
10930                    .or_default()
10931                    .diagnostics
10932                    .entry(None)
10933                    .or_insert(provider.clone());
10934                let workspace_refresher =
10935                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
10936
10937                Some((None, workspace_refresher))
10938            })
10939            .into_iter()
10940            .collect();
10941        local.language_servers.insert(
10942            server_id,
10943            LanguageServerState::Running {
10944                workspace_diagnostics_refresh_tasks,
10945                adapter: adapter.clone(),
10946                server: language_server.clone(),
10947                simulate_disk_based_diagnostics_completion: None,
10948            },
10949        );
10950        local
10951            .languages
10952            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
10953        if let Some(file_ops_caps) = language_server
10954            .capabilities()
10955            .workspace
10956            .as_ref()
10957            .and_then(|ws| ws.file_operations.as_ref())
10958        {
10959            let did_rename_caps = file_ops_caps.did_rename.as_ref();
10960            let will_rename_caps = file_ops_caps.will_rename.as_ref();
10961            if did_rename_caps.or(will_rename_caps).is_some() {
10962                let watcher = RenamePathsWatchedForServer::default()
10963                    .with_did_rename_patterns(did_rename_caps)
10964                    .with_will_rename_patterns(will_rename_caps);
10965                local
10966                    .language_server_paths_watched_for_rename
10967                    .insert(server_id, watcher);
10968            }
10969        }
10970
10971        self.language_server_statuses.insert(
10972            server_id,
10973            LanguageServerStatus {
10974                name: language_server.name(),
10975                pending_work: Default::default(),
10976                has_pending_diagnostic_updates: false,
10977                progress_tokens: Default::default(),
10978                worktree: Some(key.worktree_id),
10979            },
10980        );
10981
10982        cx.emit(LspStoreEvent::LanguageServerAdded(
10983            server_id,
10984            language_server.name(),
10985            Some(key.worktree_id),
10986        ));
10987
10988        let server_capabilities = language_server.capabilities();
10989        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
10990            downstream_client
10991                .send(proto::StartLanguageServer {
10992                    project_id: *project_id,
10993                    server: Some(proto::LanguageServer {
10994                        id: server_id.to_proto(),
10995                        name: language_server.name().to_string(),
10996                        worktree_id: Some(key.worktree_id.to_proto()),
10997                    }),
10998                    capabilities: serde_json::to_string(&server_capabilities)
10999                        .expect("serializing server LSP capabilities"),
11000                })
11001                .log_err();
11002        }
11003        self.lsp_server_capabilities
11004            .insert(server_id, server_capabilities);
11005
11006        // Tell the language server about every open buffer in the worktree that matches the language.
11007        // Also check for buffers in worktrees that reused this server
11008        let mut worktrees_using_server = vec![key.worktree_id];
11009        if let Some(local) = self.as_local() {
11010            // Find all worktrees that have this server in their language server tree
11011            for (worktree_id, servers) in &local.lsp_tree.instances {
11012                if *worktree_id != key.worktree_id {
11013                    for server_map in servers.roots.values() {
11014                        if server_map
11015                            .values()
11016                            .any(|(node, _)| node.id() == Some(server_id))
11017                        {
11018                            worktrees_using_server.push(*worktree_id);
11019                        }
11020                    }
11021                }
11022            }
11023        }
11024
11025        let mut buffer_paths_registered = Vec::new();
11026        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11027            let mut lsp_adapters = HashMap::default();
11028            for buffer_handle in buffer_store.buffers() {
11029                let buffer = buffer_handle.read(cx);
11030                let file = match File::from_dyn(buffer.file()) {
11031                    Some(file) => file,
11032                    None => continue,
11033                };
11034                let language = match buffer.language() {
11035                    Some(language) => language,
11036                    None => continue,
11037                };
11038
11039                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11040                    || !lsp_adapters
11041                        .entry(language.name())
11042                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11043                        .iter()
11044                        .any(|a| a.name == key.name)
11045                {
11046                    continue;
11047                }
11048                // didOpen
11049                let file = match file.as_local() {
11050                    Some(file) => file,
11051                    None => continue,
11052                };
11053
11054                let local = self.as_local_mut().unwrap();
11055
11056                let buffer_id = buffer.remote_id();
11057                if local.registered_buffers.contains_key(&buffer_id) {
11058                    let versions = local
11059                        .buffer_snapshots
11060                        .entry(buffer_id)
11061                        .or_default()
11062                        .entry(server_id)
11063                        .and_modify(|_| {
11064                            assert!(
11065                            false,
11066                            "There should not be an existing snapshot for a newly inserted buffer"
11067                        )
11068                        })
11069                        .or_insert_with(|| {
11070                            vec![LspBufferSnapshot {
11071                                version: 0,
11072                                snapshot: buffer.text_snapshot(),
11073                            }]
11074                        });
11075
11076                    let snapshot = versions.last().unwrap();
11077                    let version = snapshot.version;
11078                    let initial_snapshot = &snapshot.snapshot;
11079                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11080                    language_server.register_buffer(
11081                        uri,
11082                        adapter.language_id(&language.name()),
11083                        version,
11084                        initial_snapshot.text(),
11085                    );
11086                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11087                    local
11088                        .buffers_opened_in_servers
11089                        .entry(buffer_id)
11090                        .or_default()
11091                        .insert(server_id);
11092                }
11093                buffer_handle.update(cx, |buffer, cx| {
11094                    buffer.set_completion_triggers(
11095                        server_id,
11096                        language_server
11097                            .capabilities()
11098                            .completion_provider
11099                            .as_ref()
11100                            .and_then(|provider| {
11101                                provider
11102                                    .trigger_characters
11103                                    .as_ref()
11104                                    .map(|characters| characters.iter().cloned().collect())
11105                            })
11106                            .unwrap_or_default(),
11107                        cx,
11108                    )
11109                });
11110            }
11111        });
11112
11113        for (buffer_id, abs_path) in buffer_paths_registered {
11114            cx.emit(LspStoreEvent::LanguageServerUpdate {
11115                language_server_id: server_id,
11116                name: Some(adapter.name()),
11117                message: proto::update_language_server::Variant::RegisteredForBuffer(
11118                    proto::RegisteredForBuffer {
11119                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11120                        buffer_id: buffer_id.to_proto(),
11121                    },
11122                ),
11123            });
11124        }
11125
11126        cx.notify();
11127    }
11128
11129    pub fn language_servers_running_disk_based_diagnostics(
11130        &self,
11131    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11132        self.language_server_statuses
11133            .iter()
11134            .filter_map(|(id, status)| {
11135                if status.has_pending_diagnostic_updates {
11136                    Some(*id)
11137                } else {
11138                    None
11139                }
11140            })
11141    }
11142
11143    pub(crate) fn cancel_language_server_work_for_buffers(
11144        &mut self,
11145        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11146        cx: &mut Context<Self>,
11147    ) {
11148        if let Some((client, project_id)) = self.upstream_client() {
11149            let request = client.request(proto::CancelLanguageServerWork {
11150                project_id,
11151                work: Some(proto::cancel_language_server_work::Work::Buffers(
11152                    proto::cancel_language_server_work::Buffers {
11153                        buffer_ids: buffers
11154                            .into_iter()
11155                            .map(|b| b.read(cx).remote_id().to_proto())
11156                            .collect(),
11157                    },
11158                )),
11159            });
11160            cx.background_spawn(request).detach_and_log_err(cx);
11161        } else if let Some(local) = self.as_local() {
11162            let servers = buffers
11163                .into_iter()
11164                .flat_map(|buffer| {
11165                    buffer.update(cx, |buffer, cx| {
11166                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11167                    })
11168                })
11169                .collect::<HashSet<_>>();
11170            for server_id in servers {
11171                self.cancel_language_server_work(server_id, None, cx);
11172            }
11173        }
11174    }
11175
11176    pub(crate) fn cancel_language_server_work(
11177        &mut self,
11178        server_id: LanguageServerId,
11179        token_to_cancel: Option<ProgressToken>,
11180        cx: &mut Context<Self>,
11181    ) {
11182        if let Some(local) = self.as_local() {
11183            let status = self.language_server_statuses.get(&server_id);
11184            let server = local.language_servers.get(&server_id);
11185            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11186            {
11187                for (token, progress) in &status.pending_work {
11188                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11189                        && token != token_to_cancel
11190                    {
11191                        continue;
11192                    }
11193                    if progress.is_cancellable {
11194                        server
11195                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11196                                WorkDoneProgressCancelParams {
11197                                    token: token.to_lsp(),
11198                                },
11199                            )
11200                            .ok();
11201                    }
11202                }
11203            }
11204        } else if let Some((client, project_id)) = self.upstream_client() {
11205            let request = client.request(proto::CancelLanguageServerWork {
11206                project_id,
11207                work: Some(
11208                    proto::cancel_language_server_work::Work::LanguageServerWork(
11209                        proto::cancel_language_server_work::LanguageServerWork {
11210                            language_server_id: server_id.to_proto(),
11211                            token: token_to_cancel.map(|token| token.to_proto()),
11212                        },
11213                    ),
11214                ),
11215            });
11216            cx.background_spawn(request).detach_and_log_err(cx);
11217        }
11218    }
11219
11220    fn register_supplementary_language_server(
11221        &mut self,
11222        id: LanguageServerId,
11223        name: LanguageServerName,
11224        server: Arc<LanguageServer>,
11225        cx: &mut Context<Self>,
11226    ) {
11227        if let Some(local) = self.as_local_mut() {
11228            local
11229                .supplementary_language_servers
11230                .insert(id, (name.clone(), server));
11231            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11232        }
11233    }
11234
11235    fn unregister_supplementary_language_server(
11236        &mut self,
11237        id: LanguageServerId,
11238        cx: &mut Context<Self>,
11239    ) {
11240        if let Some(local) = self.as_local_mut() {
11241            local.supplementary_language_servers.remove(&id);
11242            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11243        }
11244    }
11245
11246    pub(crate) fn supplementary_language_servers(
11247        &self,
11248    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11249        self.as_local().into_iter().flat_map(|local| {
11250            local
11251                .supplementary_language_servers
11252                .iter()
11253                .map(|(id, (name, _))| (*id, name.clone()))
11254        })
11255    }
11256
11257    pub fn language_server_adapter_for_id(
11258        &self,
11259        id: LanguageServerId,
11260    ) -> Option<Arc<CachedLspAdapter>> {
11261        self.as_local()
11262            .and_then(|local| local.language_servers.get(&id))
11263            .and_then(|language_server_state| match language_server_state {
11264                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11265                _ => None,
11266            })
11267    }
11268
11269    pub(super) fn update_local_worktree_language_servers(
11270        &mut self,
11271        worktree_handle: &Entity<Worktree>,
11272        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11273        cx: &mut Context<Self>,
11274    ) {
11275        if changes.is_empty() {
11276            return;
11277        }
11278
11279        let Some(local) = self.as_local() else { return };
11280
11281        local.prettier_store.update(cx, |prettier_store, cx| {
11282            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11283        });
11284
11285        let worktree_id = worktree_handle.read(cx).id();
11286        let mut language_server_ids = local
11287            .language_server_ids
11288            .iter()
11289            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11290            .collect::<Vec<_>>();
11291        language_server_ids.sort();
11292        language_server_ids.dedup();
11293
11294        // let abs_path = worktree_handle.read(cx).abs_path();
11295        for server_id in &language_server_ids {
11296            if let Some(LanguageServerState::Running { server, .. }) =
11297                local.language_servers.get(server_id)
11298                && let Some(watched_paths) = local
11299                    .language_server_watched_paths
11300                    .get(server_id)
11301                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11302            {
11303                let params = lsp::DidChangeWatchedFilesParams {
11304                    changes: changes
11305                        .iter()
11306                        .filter_map(|(path, _, change)| {
11307                            if !watched_paths.is_match(path.as_std_path()) {
11308                                return None;
11309                            }
11310                            let typ = match change {
11311                                PathChange::Loaded => return None,
11312                                PathChange::Added => lsp::FileChangeType::CREATED,
11313                                PathChange::Removed => lsp::FileChangeType::DELETED,
11314                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11315                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11316                            };
11317                            let uri = lsp::Uri::from_file_path(
11318                                worktree_handle.read(cx).absolutize(&path),
11319                            )
11320                            .ok()?;
11321                            Some(lsp::FileEvent { uri, typ })
11322                        })
11323                        .collect(),
11324                };
11325                if !params.changes.is_empty() {
11326                    server
11327                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11328                        .ok();
11329                }
11330            }
11331        }
11332        for (path, _, _) in changes {
11333            if let Some(file_name) = path.file_name()
11334                && local.watched_manifest_filenames.contains(file_name)
11335            {
11336                self.request_workspace_config_refresh();
11337                break;
11338            }
11339        }
11340    }
11341
11342    pub fn wait_for_remote_buffer(
11343        &mut self,
11344        id: BufferId,
11345        cx: &mut Context<Self>,
11346    ) -> Task<Result<Entity<Buffer>>> {
11347        self.buffer_store.update(cx, |buffer_store, cx| {
11348            buffer_store.wait_for_remote_buffer(id, cx)
11349        })
11350    }
11351
11352    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11353        let mut result = proto::Symbol {
11354            language_server_name: symbol.language_server_name.0.to_string(),
11355            source_worktree_id: symbol.source_worktree_id.to_proto(),
11356            language_server_id: symbol.source_language_server_id.to_proto(),
11357            name: symbol.name.clone(),
11358            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11359            start: Some(proto::PointUtf16 {
11360                row: symbol.range.start.0.row,
11361                column: symbol.range.start.0.column,
11362            }),
11363            end: Some(proto::PointUtf16 {
11364                row: symbol.range.end.0.row,
11365                column: symbol.range.end.0.column,
11366            }),
11367            worktree_id: Default::default(),
11368            path: Default::default(),
11369            signature: Default::default(),
11370        };
11371        match &symbol.path {
11372            SymbolLocation::InProject(path) => {
11373                result.worktree_id = path.worktree_id.to_proto();
11374                result.path = path.path.to_proto();
11375            }
11376            SymbolLocation::OutsideProject {
11377                abs_path,
11378                signature,
11379            } => {
11380                result.path = abs_path.to_string_lossy().into_owned();
11381                result.signature = signature.to_vec();
11382            }
11383        }
11384        result
11385    }
11386
11387    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11388        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11389        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11390        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11391
11392        let path = if serialized_symbol.signature.is_empty() {
11393            SymbolLocation::InProject(ProjectPath {
11394                worktree_id,
11395                path: RelPath::from_proto(&serialized_symbol.path)
11396                    .context("invalid symbol path")?,
11397            })
11398        } else {
11399            SymbolLocation::OutsideProject {
11400                abs_path: Path::new(&serialized_symbol.path).into(),
11401                signature: serialized_symbol
11402                    .signature
11403                    .try_into()
11404                    .map_err(|_| anyhow!("invalid signature"))?,
11405            }
11406        };
11407
11408        let start = serialized_symbol.start.context("invalid start")?;
11409        let end = serialized_symbol.end.context("invalid end")?;
11410        Ok(CoreSymbol {
11411            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11412            source_worktree_id,
11413            source_language_server_id: LanguageServerId::from_proto(
11414                serialized_symbol.language_server_id,
11415            ),
11416            path,
11417            name: serialized_symbol.name,
11418            range: Unclipped(PointUtf16::new(start.row, start.column))
11419                ..Unclipped(PointUtf16::new(end.row, end.column)),
11420            kind,
11421        })
11422    }
11423
11424    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11425        let mut serialized_completion = proto::Completion {
11426            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11427            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11428            new_text: completion.new_text.clone(),
11429            ..proto::Completion::default()
11430        };
11431        match &completion.source {
11432            CompletionSource::Lsp {
11433                insert_range,
11434                server_id,
11435                lsp_completion,
11436                lsp_defaults,
11437                resolved,
11438            } => {
11439                let (old_insert_start, old_insert_end) = insert_range
11440                    .as_ref()
11441                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11442                    .unzip();
11443
11444                serialized_completion.old_insert_start = old_insert_start;
11445                serialized_completion.old_insert_end = old_insert_end;
11446                serialized_completion.source = proto::completion::Source::Lsp as i32;
11447                serialized_completion.server_id = server_id.0 as u64;
11448                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11449                serialized_completion.lsp_defaults = lsp_defaults
11450                    .as_deref()
11451                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11452                serialized_completion.resolved = *resolved;
11453            }
11454            CompletionSource::BufferWord {
11455                word_range,
11456                resolved,
11457            } => {
11458                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11459                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11460                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11461                serialized_completion.resolved = *resolved;
11462            }
11463            CompletionSource::Custom => {
11464                serialized_completion.source = proto::completion::Source::Custom as i32;
11465                serialized_completion.resolved = true;
11466            }
11467            CompletionSource::Dap { sort_text } => {
11468                serialized_completion.source = proto::completion::Source::Dap as i32;
11469                serialized_completion.sort_text = Some(sort_text.clone());
11470            }
11471        }
11472
11473        serialized_completion
11474    }
11475
11476    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11477        let old_replace_start = completion
11478            .old_replace_start
11479            .and_then(deserialize_anchor)
11480            .context("invalid old start")?;
11481        let old_replace_end = completion
11482            .old_replace_end
11483            .and_then(deserialize_anchor)
11484            .context("invalid old end")?;
11485        let insert_range = {
11486            match completion.old_insert_start.zip(completion.old_insert_end) {
11487                Some((start, end)) => {
11488                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11489                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11490                    Some(start..end)
11491                }
11492                None => None,
11493            }
11494        };
11495        Ok(CoreCompletion {
11496            replace_range: old_replace_start..old_replace_end,
11497            new_text: completion.new_text,
11498            source: match proto::completion::Source::from_i32(completion.source) {
11499                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11500                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11501                    insert_range,
11502                    server_id: LanguageServerId::from_proto(completion.server_id),
11503                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11504                    lsp_defaults: completion
11505                        .lsp_defaults
11506                        .as_deref()
11507                        .map(serde_json::from_slice)
11508                        .transpose()?,
11509                    resolved: completion.resolved,
11510                },
11511                Some(proto::completion::Source::BufferWord) => {
11512                    let word_range = completion
11513                        .buffer_word_start
11514                        .and_then(deserialize_anchor)
11515                        .context("invalid buffer word start")?
11516                        ..completion
11517                            .buffer_word_end
11518                            .and_then(deserialize_anchor)
11519                            .context("invalid buffer word end")?;
11520                    CompletionSource::BufferWord {
11521                        word_range,
11522                        resolved: completion.resolved,
11523                    }
11524                }
11525                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11526                    sort_text: completion
11527                        .sort_text
11528                        .context("expected sort text to exist")?,
11529                },
11530                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11531            },
11532        })
11533    }
11534
11535    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11536        let (kind, lsp_action) = match &action.lsp_action {
11537            LspAction::Action(code_action) => (
11538                proto::code_action::Kind::Action as i32,
11539                serde_json::to_vec(code_action).unwrap(),
11540            ),
11541            LspAction::Command(command) => (
11542                proto::code_action::Kind::Command as i32,
11543                serde_json::to_vec(command).unwrap(),
11544            ),
11545            LspAction::CodeLens(code_lens) => (
11546                proto::code_action::Kind::CodeLens as i32,
11547                serde_json::to_vec(code_lens).unwrap(),
11548            ),
11549        };
11550
11551        proto::CodeAction {
11552            server_id: action.server_id.0 as u64,
11553            start: Some(serialize_anchor(&action.range.start)),
11554            end: Some(serialize_anchor(&action.range.end)),
11555            lsp_action,
11556            kind,
11557            resolved: action.resolved,
11558        }
11559    }
11560
11561    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11562        let start = action
11563            .start
11564            .and_then(deserialize_anchor)
11565            .context("invalid start")?;
11566        let end = action
11567            .end
11568            .and_then(deserialize_anchor)
11569            .context("invalid end")?;
11570        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11571            Some(proto::code_action::Kind::Action) => {
11572                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11573            }
11574            Some(proto::code_action::Kind::Command) => {
11575                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11576            }
11577            Some(proto::code_action::Kind::CodeLens) => {
11578                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11579            }
11580            None => anyhow::bail!("Unknown action kind {}", action.kind),
11581        };
11582        Ok(CodeAction {
11583            server_id: LanguageServerId(action.server_id as usize),
11584            range: start..end,
11585            resolved: action.resolved,
11586            lsp_action,
11587        })
11588    }
11589
11590    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11591        match &formatting_result {
11592            Ok(_) => self.last_formatting_failure = None,
11593            Err(error) => {
11594                let error_string = format!("{error:#}");
11595                log::error!("Formatting failed: {error_string}");
11596                self.last_formatting_failure
11597                    .replace(error_string.lines().join(" "));
11598            }
11599        }
11600    }
11601
11602    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11603        self.lsp_server_capabilities.remove(&for_server);
11604        for lsp_data in self.lsp_data.values_mut() {
11605            lsp_data.remove_server_data(for_server);
11606        }
11607        if let Some(local) = self.as_local_mut() {
11608            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11609            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11610                buffer_servers.remove(&for_server);
11611            }
11612        }
11613    }
11614
11615    pub fn result_id(
11616        &self,
11617        server_id: LanguageServerId,
11618        buffer_id: BufferId,
11619        cx: &App,
11620    ) -> Option<String> {
11621        let abs_path = self
11622            .buffer_store
11623            .read(cx)
11624            .get(buffer_id)
11625            .and_then(|b| File::from_dyn(b.read(cx).file()))
11626            .map(|f| f.abs_path(cx))?;
11627        self.as_local()?
11628            .buffer_pull_diagnostics_result_ids
11629            .get(&server_id)?
11630            .get(&abs_path)?
11631            .clone()
11632    }
11633
11634    pub fn all_result_ids(&self, server_id: LanguageServerId) -> HashMap<PathBuf, String> {
11635        let Some(local) = self.as_local() else {
11636            return HashMap::default();
11637        };
11638        local
11639            .buffer_pull_diagnostics_result_ids
11640            .get(&server_id)
11641            .into_iter()
11642            .flatten()
11643            .filter_map(|(abs_path, result_id)| Some((abs_path.clone(), result_id.clone()?)))
11644            .collect()
11645    }
11646
11647    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
11648        if let Some(LanguageServerState::Running {
11649            workspace_diagnostics_refresh_tasks,
11650            ..
11651        }) = self
11652            .as_local_mut()
11653            .and_then(|local| local.language_servers.get_mut(&server_id))
11654        {
11655            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
11656                diagnostics.refresh_tx.try_send(()).ok();
11657            }
11658        }
11659    }
11660
11661    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
11662        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
11663            return;
11664        };
11665        let Some(local) = self.as_local_mut() else {
11666            return;
11667        };
11668
11669        for server_id in buffer.update(cx, |buffer, cx| {
11670            local.language_server_ids_for_buffer(buffer, cx)
11671        }) {
11672            if let Some(LanguageServerState::Running {
11673                workspace_diagnostics_refresh_tasks,
11674                ..
11675            }) = local.language_servers.get_mut(&server_id)
11676            {
11677                for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
11678                    diagnostics.refresh_tx.try_send(()).ok();
11679                }
11680            }
11681        }
11682    }
11683
11684    fn apply_workspace_diagnostic_report(
11685        &mut self,
11686        server_id: LanguageServerId,
11687        report: lsp::WorkspaceDiagnosticReportResult,
11688        cx: &mut Context<Self>,
11689    ) {
11690        let workspace_diagnostics =
11691            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(report, server_id);
11692        let mut unchanged_buffers = HashSet::default();
11693        let mut changed_buffers = HashSet::default();
11694        let workspace_diagnostics_updates = workspace_diagnostics
11695            .into_iter()
11696            .filter_map(
11697                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
11698                    LspPullDiagnostics::Response {
11699                        server_id,
11700                        uri,
11701                        diagnostics,
11702                    } => Some((server_id, uri, diagnostics, workspace_diagnostics.version)),
11703                    LspPullDiagnostics::Default => None,
11704                },
11705            )
11706            .fold(
11707                HashMap::default(),
11708                |mut acc, (server_id, uri, diagnostics, version)| {
11709                    let (result_id, diagnostics) = match diagnostics {
11710                        PulledDiagnostics::Unchanged { result_id } => {
11711                            unchanged_buffers.insert(uri.clone());
11712                            (Some(result_id), Vec::new())
11713                        }
11714                        PulledDiagnostics::Changed {
11715                            result_id,
11716                            diagnostics,
11717                        } => {
11718                            changed_buffers.insert(uri.clone());
11719                            (result_id, diagnostics)
11720                        }
11721                    };
11722                    let disk_based_sources = Cow::Owned(
11723                        self.language_server_adapter_for_id(server_id)
11724                            .as_ref()
11725                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
11726                            .unwrap_or(&[])
11727                            .to_vec(),
11728                    );
11729                    acc.entry(server_id)
11730                        .or_insert_with(Vec::new)
11731                        .push(DocumentDiagnosticsUpdate {
11732                            server_id,
11733                            diagnostics: lsp::PublishDiagnosticsParams {
11734                                uri,
11735                                diagnostics,
11736                                version,
11737                            },
11738                            result_id,
11739                            disk_based_sources,
11740                        });
11741                    acc
11742                },
11743            );
11744
11745        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
11746            self.merge_lsp_diagnostics(
11747                DiagnosticSourceKind::Pulled,
11748                diagnostic_updates,
11749                |buffer, old_diagnostic, cx| {
11750                    File::from_dyn(buffer.file())
11751                        .and_then(|file| {
11752                            let abs_path = file.as_local()?.abs_path(cx);
11753                            lsp::Uri::from_file_path(abs_path).ok()
11754                        })
11755                        .is_none_or(|buffer_uri| {
11756                            unchanged_buffers.contains(&buffer_uri)
11757                                || match old_diagnostic.source_kind {
11758                                    DiagnosticSourceKind::Pulled => {
11759                                        !changed_buffers.contains(&buffer_uri)
11760                                    }
11761                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
11762                                        true
11763                                    }
11764                                }
11765                        })
11766                },
11767                cx,
11768            )
11769            .log_err();
11770        }
11771    }
11772
11773    fn register_server_capabilities(
11774        &mut self,
11775        server_id: LanguageServerId,
11776        params: lsp::RegistrationParams,
11777        cx: &mut Context<Self>,
11778    ) -> anyhow::Result<()> {
11779        let server = self
11780            .language_server_for_id(server_id)
11781            .with_context(|| format!("no server {server_id} found"))?;
11782        for reg in params.registrations {
11783            match reg.method.as_str() {
11784                "workspace/didChangeWatchedFiles" => {
11785                    if let Some(options) = reg.register_options {
11786                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11787                            let caps = serde_json::from_value(options)?;
11788                            local_lsp_store
11789                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
11790                            true
11791                        } else {
11792                            false
11793                        };
11794                        if notify {
11795                            notify_server_capabilities_updated(&server, cx);
11796                        }
11797                    }
11798                }
11799                "workspace/didChangeConfiguration" => {
11800                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11801                }
11802                "workspace/didChangeWorkspaceFolders" => {
11803                    // In this case register options is an empty object, we can ignore it
11804                    let caps = lsp::WorkspaceFoldersServerCapabilities {
11805                        supported: Some(true),
11806                        change_notifications: Some(OneOf::Right(reg.id)),
11807                    };
11808                    server.update_capabilities(|capabilities| {
11809                        capabilities
11810                            .workspace
11811                            .get_or_insert_default()
11812                            .workspace_folders = Some(caps);
11813                    });
11814                    notify_server_capabilities_updated(&server, cx);
11815                }
11816                "workspace/symbol" => {
11817                    let options = parse_register_capabilities(reg)?;
11818                    server.update_capabilities(|capabilities| {
11819                        capabilities.workspace_symbol_provider = Some(options);
11820                    });
11821                    notify_server_capabilities_updated(&server, cx);
11822                }
11823                "workspace/fileOperations" => {
11824                    if let Some(options) = reg.register_options {
11825                        let caps = serde_json::from_value(options)?;
11826                        server.update_capabilities(|capabilities| {
11827                            capabilities
11828                                .workspace
11829                                .get_or_insert_default()
11830                                .file_operations = Some(caps);
11831                        });
11832                        notify_server_capabilities_updated(&server, cx);
11833                    }
11834                }
11835                "workspace/executeCommand" => {
11836                    if let Some(options) = reg.register_options {
11837                        let options = serde_json::from_value(options)?;
11838                        server.update_capabilities(|capabilities| {
11839                            capabilities.execute_command_provider = Some(options);
11840                        });
11841                        notify_server_capabilities_updated(&server, cx);
11842                    }
11843                }
11844                "textDocument/rangeFormatting" => {
11845                    let options = parse_register_capabilities(reg)?;
11846                    server.update_capabilities(|capabilities| {
11847                        capabilities.document_range_formatting_provider = Some(options);
11848                    });
11849                    notify_server_capabilities_updated(&server, cx);
11850                }
11851                "textDocument/onTypeFormatting" => {
11852                    if let Some(options) = reg
11853                        .register_options
11854                        .map(serde_json::from_value)
11855                        .transpose()?
11856                    {
11857                        server.update_capabilities(|capabilities| {
11858                            capabilities.document_on_type_formatting_provider = Some(options);
11859                        });
11860                        notify_server_capabilities_updated(&server, cx);
11861                    }
11862                }
11863                "textDocument/formatting" => {
11864                    let options = parse_register_capabilities(reg)?;
11865                    server.update_capabilities(|capabilities| {
11866                        capabilities.document_formatting_provider = Some(options);
11867                    });
11868                    notify_server_capabilities_updated(&server, cx);
11869                }
11870                "textDocument/rename" => {
11871                    let options = parse_register_capabilities(reg)?;
11872                    server.update_capabilities(|capabilities| {
11873                        capabilities.rename_provider = Some(options);
11874                    });
11875                    notify_server_capabilities_updated(&server, cx);
11876                }
11877                "textDocument/inlayHint" => {
11878                    let options = parse_register_capabilities(reg)?;
11879                    server.update_capabilities(|capabilities| {
11880                        capabilities.inlay_hint_provider = Some(options);
11881                    });
11882                    notify_server_capabilities_updated(&server, cx);
11883                }
11884                "textDocument/documentSymbol" => {
11885                    let options = parse_register_capabilities(reg)?;
11886                    server.update_capabilities(|capabilities| {
11887                        capabilities.document_symbol_provider = Some(options);
11888                    });
11889                    notify_server_capabilities_updated(&server, cx);
11890                }
11891                "textDocument/codeAction" => {
11892                    let options = parse_register_capabilities(reg)?;
11893                    let provider = match options {
11894                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
11895                        OneOf::Right(caps) => caps,
11896                    };
11897                    server.update_capabilities(|capabilities| {
11898                        capabilities.code_action_provider = Some(provider);
11899                    });
11900                    notify_server_capabilities_updated(&server, cx);
11901                }
11902                "textDocument/definition" => {
11903                    let options = parse_register_capabilities(reg)?;
11904                    server.update_capabilities(|capabilities| {
11905                        capabilities.definition_provider = Some(options);
11906                    });
11907                    notify_server_capabilities_updated(&server, cx);
11908                }
11909                "textDocument/completion" => {
11910                    if let Some(caps) = reg
11911                        .register_options
11912                        .map(serde_json::from_value)
11913                        .transpose()?
11914                    {
11915                        server.update_capabilities(|capabilities| {
11916                            capabilities.completion_provider = Some(caps);
11917                        });
11918                        notify_server_capabilities_updated(&server, cx);
11919                    }
11920                }
11921                "textDocument/hover" => {
11922                    let options = parse_register_capabilities(reg)?;
11923                    let provider = match options {
11924                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
11925                        OneOf::Right(caps) => caps,
11926                    };
11927                    server.update_capabilities(|capabilities| {
11928                        capabilities.hover_provider = Some(provider);
11929                    });
11930                    notify_server_capabilities_updated(&server, cx);
11931                }
11932                "textDocument/signatureHelp" => {
11933                    if let Some(caps) = reg
11934                        .register_options
11935                        .map(serde_json::from_value)
11936                        .transpose()?
11937                    {
11938                        server.update_capabilities(|capabilities| {
11939                            capabilities.signature_help_provider = Some(caps);
11940                        });
11941                        notify_server_capabilities_updated(&server, cx);
11942                    }
11943                }
11944                "textDocument/didChange" => {
11945                    if let Some(sync_kind) = reg
11946                        .register_options
11947                        .and_then(|opts| opts.get("syncKind").cloned())
11948                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
11949                        .transpose()?
11950                    {
11951                        server.update_capabilities(|capabilities| {
11952                            let mut sync_options =
11953                                Self::take_text_document_sync_options(capabilities);
11954                            sync_options.change = Some(sync_kind);
11955                            capabilities.text_document_sync =
11956                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11957                        });
11958                        notify_server_capabilities_updated(&server, cx);
11959                    }
11960                }
11961                "textDocument/didSave" => {
11962                    if let Some(include_text) = reg
11963                        .register_options
11964                        .map(|opts| {
11965                            let transpose = opts
11966                                .get("includeText")
11967                                .cloned()
11968                                .map(serde_json::from_value::<Option<bool>>)
11969                                .transpose();
11970                            match transpose {
11971                                Ok(value) => Ok(value.flatten()),
11972                                Err(e) => Err(e),
11973                            }
11974                        })
11975                        .transpose()?
11976                    {
11977                        server.update_capabilities(|capabilities| {
11978                            let mut sync_options =
11979                                Self::take_text_document_sync_options(capabilities);
11980                            sync_options.save =
11981                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
11982                                    include_text,
11983                                }));
11984                            capabilities.text_document_sync =
11985                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11986                        });
11987                        notify_server_capabilities_updated(&server, cx);
11988                    }
11989                }
11990                "textDocument/codeLens" => {
11991                    if let Some(caps) = reg
11992                        .register_options
11993                        .map(serde_json::from_value)
11994                        .transpose()?
11995                    {
11996                        server.update_capabilities(|capabilities| {
11997                            capabilities.code_lens_provider = Some(caps);
11998                        });
11999                        notify_server_capabilities_updated(&server, cx);
12000                    }
12001                }
12002                "textDocument/diagnostic" => {
12003                    if let Some(caps) = reg
12004                        .register_options
12005                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12006                        .transpose()?
12007                    {
12008                        let local = self
12009                            .as_local_mut()
12010                            .context("Expected LSP Store to be local")?;
12011                        let state = local
12012                            .language_servers
12013                            .get_mut(&server_id)
12014                            .context("Could not obtain Language Servers state")?;
12015                        local
12016                            .language_server_dynamic_registrations
12017                            .get_mut(&server_id)
12018                            .and_then(|registrations| {
12019                                registrations
12020                                    .diagnostics
12021                                    .insert(Some(reg.id.clone()), caps.clone())
12022                            });
12023
12024                        let mut can_now_provide_diagnostics = false;
12025                        if let LanguageServerState::Running {
12026                            workspace_diagnostics_refresh_tasks,
12027                            ..
12028                        } = state
12029                            && let Some(task) = lsp_workspace_diagnostics_refresh(
12030                                Some(reg.id.clone()),
12031                                caps.clone(),
12032                                server.clone(),
12033                                cx,
12034                            )
12035                        {
12036                            workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12037                            can_now_provide_diagnostics = true;
12038                        }
12039
12040                        // We don't actually care about capabilities.diagnostic_provider, but it IS relevant for the remote peer
12041                        // to know that there's at least one provider. Otherwise, it will never ask us to issue documentdiagnostic calls on their behalf,
12042                        // as it'll think that they're not supported.
12043                        if can_now_provide_diagnostics {
12044                            server.update_capabilities(|capabilities| {
12045                                debug_assert!(capabilities.diagnostic_provider.is_none());
12046                                capabilities.diagnostic_provider = Some(caps);
12047                            });
12048                        }
12049
12050                        notify_server_capabilities_updated(&server, cx);
12051                    }
12052                }
12053                "textDocument/documentColor" => {
12054                    let options = parse_register_capabilities(reg)?;
12055                    let provider = match options {
12056                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12057                        OneOf::Right(caps) => caps,
12058                    };
12059                    server.update_capabilities(|capabilities| {
12060                        capabilities.color_provider = Some(provider);
12061                    });
12062                    notify_server_capabilities_updated(&server, cx);
12063                }
12064                _ => log::warn!("unhandled capability registration: {reg:?}"),
12065            }
12066        }
12067
12068        Ok(())
12069    }
12070
12071    fn unregister_server_capabilities(
12072        &mut self,
12073        server_id: LanguageServerId,
12074        params: lsp::UnregistrationParams,
12075        cx: &mut Context<Self>,
12076    ) -> anyhow::Result<()> {
12077        let server = self
12078            .language_server_for_id(server_id)
12079            .with_context(|| format!("no server {server_id} found"))?;
12080        for unreg in params.unregisterations.iter() {
12081            match unreg.method.as_str() {
12082                "workspace/didChangeWatchedFiles" => {
12083                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12084                        local_lsp_store
12085                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12086                        true
12087                    } else {
12088                        false
12089                    };
12090                    if notify {
12091                        notify_server_capabilities_updated(&server, cx);
12092                    }
12093                }
12094                "workspace/didChangeConfiguration" => {
12095                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12096                }
12097                "workspace/didChangeWorkspaceFolders" => {
12098                    server.update_capabilities(|capabilities| {
12099                        capabilities
12100                            .workspace
12101                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12102                                workspace_folders: None,
12103                                file_operations: None,
12104                            })
12105                            .workspace_folders = None;
12106                    });
12107                    notify_server_capabilities_updated(&server, cx);
12108                }
12109                "workspace/symbol" => {
12110                    server.update_capabilities(|capabilities| {
12111                        capabilities.workspace_symbol_provider = None
12112                    });
12113                    notify_server_capabilities_updated(&server, cx);
12114                }
12115                "workspace/fileOperations" => {
12116                    server.update_capabilities(|capabilities| {
12117                        capabilities
12118                            .workspace
12119                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12120                                workspace_folders: None,
12121                                file_operations: None,
12122                            })
12123                            .file_operations = None;
12124                    });
12125                    notify_server_capabilities_updated(&server, cx);
12126                }
12127                "workspace/executeCommand" => {
12128                    server.update_capabilities(|capabilities| {
12129                        capabilities.execute_command_provider = None;
12130                    });
12131                    notify_server_capabilities_updated(&server, cx);
12132                }
12133                "textDocument/rangeFormatting" => {
12134                    server.update_capabilities(|capabilities| {
12135                        capabilities.document_range_formatting_provider = None
12136                    });
12137                    notify_server_capabilities_updated(&server, cx);
12138                }
12139                "textDocument/onTypeFormatting" => {
12140                    server.update_capabilities(|capabilities| {
12141                        capabilities.document_on_type_formatting_provider = None;
12142                    });
12143                    notify_server_capabilities_updated(&server, cx);
12144                }
12145                "textDocument/formatting" => {
12146                    server.update_capabilities(|capabilities| {
12147                        capabilities.document_formatting_provider = None;
12148                    });
12149                    notify_server_capabilities_updated(&server, cx);
12150                }
12151                "textDocument/rename" => {
12152                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12153                    notify_server_capabilities_updated(&server, cx);
12154                }
12155                "textDocument/codeAction" => {
12156                    server.update_capabilities(|capabilities| {
12157                        capabilities.code_action_provider = None;
12158                    });
12159                    notify_server_capabilities_updated(&server, cx);
12160                }
12161                "textDocument/definition" => {
12162                    server.update_capabilities(|capabilities| {
12163                        capabilities.definition_provider = None;
12164                    });
12165                    notify_server_capabilities_updated(&server, cx);
12166                }
12167                "textDocument/completion" => {
12168                    server.update_capabilities(|capabilities| {
12169                        capabilities.completion_provider = None;
12170                    });
12171                    notify_server_capabilities_updated(&server, cx);
12172                }
12173                "textDocument/hover" => {
12174                    server.update_capabilities(|capabilities| {
12175                        capabilities.hover_provider = None;
12176                    });
12177                    notify_server_capabilities_updated(&server, cx);
12178                }
12179                "textDocument/signatureHelp" => {
12180                    server.update_capabilities(|capabilities| {
12181                        capabilities.signature_help_provider = None;
12182                    });
12183                    notify_server_capabilities_updated(&server, cx);
12184                }
12185                "textDocument/didChange" => {
12186                    server.update_capabilities(|capabilities| {
12187                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12188                        sync_options.change = None;
12189                        capabilities.text_document_sync =
12190                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12191                    });
12192                    notify_server_capabilities_updated(&server, cx);
12193                }
12194                "textDocument/didSave" => {
12195                    server.update_capabilities(|capabilities| {
12196                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12197                        sync_options.save = None;
12198                        capabilities.text_document_sync =
12199                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12200                    });
12201                    notify_server_capabilities_updated(&server, cx);
12202                }
12203                "textDocument/codeLens" => {
12204                    server.update_capabilities(|capabilities| {
12205                        capabilities.code_lens_provider = None;
12206                    });
12207                    notify_server_capabilities_updated(&server, cx);
12208                }
12209                "textDocument/diagnostic" => {
12210                    let local = self
12211                        .as_local_mut()
12212                        .context("Expected LSP Store to be local")?;
12213
12214                    let state = local
12215                        .language_servers
12216                        .get_mut(&server_id)
12217                        .context("Could not obtain Language Servers state")?;
12218                    let options = local
12219                        .language_server_dynamic_registrations
12220                        .get_mut(&server_id)
12221                        .with_context(|| {
12222                            format!("Expected dynamic registration to exist for server {server_id}")
12223                        })?.diagnostics
12224                        .remove(&Some(unreg.id.clone()))
12225                        .with_context(|| format!(
12226                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12227                            unreg.id)
12228                        )?;
12229
12230                    let mut has_any_diagnostic_providers_still = true;
12231                    if let Some(identifier) = diagnostic_identifier(&options)
12232                        && let LanguageServerState::Running {
12233                            workspace_diagnostics_refresh_tasks,
12234                            ..
12235                        } = state
12236                    {
12237                        workspace_diagnostics_refresh_tasks.remove(&identifier);
12238                        has_any_diagnostic_providers_still =
12239                            !workspace_diagnostics_refresh_tasks.is_empty();
12240                    }
12241
12242                    if !has_any_diagnostic_providers_still {
12243                        server.update_capabilities(|capabilities| {
12244                            debug_assert!(capabilities.diagnostic_provider.is_some());
12245                            capabilities.diagnostic_provider = None;
12246                        });
12247                    }
12248
12249                    notify_server_capabilities_updated(&server, cx);
12250                }
12251                "textDocument/documentColor" => {
12252                    server.update_capabilities(|capabilities| {
12253                        capabilities.color_provider = None;
12254                    });
12255                    notify_server_capabilities_updated(&server, cx);
12256                }
12257                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12258            }
12259        }
12260
12261        Ok(())
12262    }
12263
12264    async fn deduplicate_range_based_lsp_requests<T>(
12265        lsp_store: &Entity<Self>,
12266        server_id: Option<LanguageServerId>,
12267        lsp_request_id: LspRequestId,
12268        proto_request: &T::ProtoRequest,
12269        range: Range<Anchor>,
12270        cx: &mut AsyncApp,
12271    ) -> Result<()>
12272    where
12273        T: LspCommand,
12274        T::ProtoRequest: proto::LspRequestMessage,
12275    {
12276        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12277        let version = deserialize_version(proto_request.buffer_version());
12278        let buffer = lsp_store.update(cx, |this, cx| {
12279            this.buffer_store.read(cx).get_existing(buffer_id)
12280        })??;
12281        buffer
12282            .update(cx, |buffer, _| buffer.wait_for_version(version))?
12283            .await?;
12284        lsp_store.update(cx, |lsp_store, cx| {
12285            let lsp_data = lsp_store
12286                .lsp_data
12287                .entry(buffer_id)
12288                .or_insert_with(|| BufferLspData::new(&buffer, cx));
12289            let chunks_queried_for = lsp_data
12290                .inlay_hints
12291                .applicable_chunks(&[range])
12292                .collect::<Vec<_>>();
12293            match chunks_queried_for.as_slice() {
12294                &[chunk] => {
12295                    let key = LspKey {
12296                        request_type: TypeId::of::<T>(),
12297                        server_queried: server_id,
12298                    };
12299                    let previous_request = lsp_data
12300                        .chunk_lsp_requests
12301                        .entry(key)
12302                        .or_default()
12303                        .insert(chunk, lsp_request_id);
12304                    if let Some((previous_request, running_requests)) =
12305                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12306                    {
12307                        running_requests.remove(&previous_request);
12308                    }
12309                }
12310                _ambiguous_chunks => {
12311                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12312                    // there, a buffer version-based check will be performed and outdated requests discarded.
12313                }
12314            }
12315            anyhow::Ok(())
12316        })??;
12317
12318        Ok(())
12319    }
12320
12321    async fn query_lsp_locally<T>(
12322        lsp_store: Entity<Self>,
12323        for_server_id: Option<LanguageServerId>,
12324        sender_id: proto::PeerId,
12325        lsp_request_id: LspRequestId,
12326        proto_request: T::ProtoRequest,
12327        position: Option<Anchor>,
12328        cx: &mut AsyncApp,
12329    ) -> Result<()>
12330    where
12331        T: LspCommand + Clone,
12332        T::ProtoRequest: proto::LspRequestMessage,
12333        <T::ProtoRequest as proto::RequestMessage>::Response:
12334            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12335    {
12336        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12337        let version = deserialize_version(proto_request.buffer_version());
12338        let buffer = lsp_store.update(cx, |this, cx| {
12339            this.buffer_store.read(cx).get_existing(buffer_id)
12340        })??;
12341        buffer
12342            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))?
12343            .await?;
12344        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version())?;
12345        let request =
12346            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12347        let key = LspKey {
12348            request_type: TypeId::of::<T>(),
12349            server_queried: for_server_id,
12350        };
12351        lsp_store.update(cx, |lsp_store, cx| {
12352            let request_task = match for_server_id {
12353                Some(server_id) => {
12354                    let server_task = lsp_store.request_lsp(
12355                        buffer.clone(),
12356                        LanguageServerToQuery::Other(server_id),
12357                        request.clone(),
12358                        cx,
12359                    );
12360                    cx.background_spawn(async move {
12361                        let mut responses = Vec::new();
12362                        match server_task.await {
12363                            Ok(response) => responses.push((server_id, response)),
12364                            Err(e) => log::error!(
12365                                "Error handling response for request {request:?}: {e:#}"
12366                            ),
12367                        }
12368                        responses
12369                    })
12370                }
12371                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12372            };
12373            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12374            if T::ProtoRequest::stop_previous_requests() {
12375                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12376                    lsp_requests.clear();
12377                }
12378            }
12379            lsp_data.lsp_requests.entry(key).or_default().insert(
12380                lsp_request_id,
12381                cx.spawn(async move |lsp_store, cx| {
12382                    let response = request_task.await;
12383                    lsp_store
12384                        .update(cx, |lsp_store, cx| {
12385                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12386                            {
12387                                let response = response
12388                                    .into_iter()
12389                                    .map(|(server_id, response)| {
12390                                        (
12391                                            server_id.to_proto(),
12392                                            T::response_to_proto(
12393                                                response,
12394                                                lsp_store,
12395                                                sender_id,
12396                                                &buffer_version,
12397                                                cx,
12398                                            )
12399                                            .into(),
12400                                        )
12401                                    })
12402                                    .collect::<HashMap<_, _>>();
12403                                match client.send_lsp_response::<T::ProtoRequest>(
12404                                    project_id,
12405                                    lsp_request_id,
12406                                    response,
12407                                ) {
12408                                    Ok(()) => {}
12409                                    Err(e) => {
12410                                        log::error!("Failed to send LSP response: {e:#}",)
12411                                    }
12412                                }
12413                            }
12414                        })
12415                        .ok();
12416                }),
12417            );
12418        })?;
12419        Ok(())
12420    }
12421
12422    fn take_text_document_sync_options(
12423        capabilities: &mut lsp::ServerCapabilities,
12424    ) -> lsp::TextDocumentSyncOptions {
12425        match capabilities.text_document_sync.take() {
12426            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12427            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12428                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12429                sync_options.change = Some(sync_kind);
12430                sync_options
12431            }
12432            None => lsp::TextDocumentSyncOptions::default(),
12433        }
12434    }
12435
12436    #[cfg(any(test, feature = "test-support"))]
12437    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
12438        Some(
12439            self.lsp_data
12440                .get_mut(&buffer_id)?
12441                .code_lens
12442                .take()?
12443                .update
12444                .take()?
12445                .1,
12446        )
12447    }
12448
12449    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
12450        self.downstream_client.clone()
12451    }
12452
12453    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
12454        self.worktree_store.clone()
12455    }
12456
12457    /// Gets what's stored in the LSP data for the given buffer.
12458    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
12459        self.lsp_data.get_mut(&buffer_id)
12460    }
12461
12462    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
12463    /// new [`BufferLspData`] will be created to replace the previous state.
12464    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
12465        let (buffer_id, buffer_version) =
12466            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
12467        let lsp_data = self
12468            .lsp_data
12469            .entry(buffer_id)
12470            .or_insert_with(|| BufferLspData::new(buffer, cx));
12471        if buffer_version.changed_since(&lsp_data.buffer_version) {
12472            *lsp_data = BufferLspData::new(buffer, cx);
12473        }
12474        lsp_data
12475    }
12476}
12477
12478// Registration with registerOptions as null, should fallback to true.
12479// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
12480fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
12481    reg: lsp::Registration,
12482) -> Result<OneOf<bool, T>> {
12483    Ok(match reg.register_options {
12484        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
12485        None => OneOf::Left(true),
12486    })
12487}
12488
12489fn subscribe_to_binary_statuses(
12490    languages: &Arc<LanguageRegistry>,
12491    cx: &mut Context<'_, LspStore>,
12492) -> Task<()> {
12493    let mut server_statuses = languages.language_server_binary_statuses();
12494    cx.spawn(async move |lsp_store, cx| {
12495        while let Some((server_name, binary_status)) = server_statuses.next().await {
12496            if lsp_store
12497                .update(cx, |_, cx| {
12498                    let mut message = None;
12499                    let binary_status = match binary_status {
12500                        BinaryStatus::None => proto::ServerBinaryStatus::None,
12501                        BinaryStatus::CheckingForUpdate => {
12502                            proto::ServerBinaryStatus::CheckingForUpdate
12503                        }
12504                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
12505                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
12506                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
12507                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
12508                        BinaryStatus::Failed { error } => {
12509                            message = Some(error);
12510                            proto::ServerBinaryStatus::Failed
12511                        }
12512                    };
12513                    cx.emit(LspStoreEvent::LanguageServerUpdate {
12514                        // Binary updates are about the binary that might not have any language server id at that point.
12515                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
12516                        language_server_id: LanguageServerId(0),
12517                        name: Some(server_name),
12518                        message: proto::update_language_server::Variant::StatusUpdate(
12519                            proto::StatusUpdate {
12520                                message,
12521                                status: Some(proto::status_update::Status::Binary(
12522                                    binary_status as i32,
12523                                )),
12524                            },
12525                        ),
12526                    });
12527                })
12528                .is_err()
12529            {
12530                break;
12531            }
12532        }
12533    })
12534}
12535
12536fn lsp_workspace_diagnostics_refresh(
12537    registration_id: Option<String>,
12538    options: DiagnosticServerCapabilities,
12539    server: Arc<LanguageServer>,
12540    cx: &mut Context<'_, LspStore>,
12541) -> Option<WorkspaceRefreshTask> {
12542    let identifier = diagnostic_identifier(&options)?;
12543
12544    let (progress_tx, mut progress_rx) = mpsc::channel(1);
12545    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
12546    refresh_tx.try_send(()).ok();
12547
12548    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
12549        let mut attempts = 0;
12550        let max_attempts = 50;
12551        let mut requests = 0;
12552
12553        loop {
12554            let Some(()) = refresh_rx.recv().await else {
12555                return;
12556            };
12557
12558            'request: loop {
12559                requests += 1;
12560                if attempts > max_attempts {
12561                    log::error!(
12562                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
12563                    );
12564                    return;
12565                }
12566                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
12567                cx.background_executor()
12568                    .timer(Duration::from_millis(backoff_millis))
12569                    .await;
12570                attempts += 1;
12571
12572                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
12573                    lsp_store
12574                        .all_result_ids(server.server_id())
12575                        .into_iter()
12576                        .filter_map(|(abs_path, result_id)| {
12577                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
12578                            Some(lsp::PreviousResultId {
12579                                uri,
12580                                value: result_id,
12581                            })
12582                        })
12583                        .collect()
12584                }) else {
12585                    return;
12586                };
12587
12588                let token = if let Some(identifier) = &registration_id {
12589                    format!(
12590                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{identifier}",
12591                        server.server_id(),
12592                    )
12593                } else {
12594                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
12595                };
12596
12597                progress_rx.try_recv().ok();
12598                let timer =
12599                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
12600                let progress = pin!(progress_rx.recv().fuse());
12601                let response_result = server
12602                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
12603                        lsp::WorkspaceDiagnosticParams {
12604                            previous_result_ids,
12605                            identifier: identifier.clone(),
12606                            work_done_progress_params: Default::default(),
12607                            partial_result_params: lsp::PartialResultParams {
12608                                partial_result_token: Some(lsp::ProgressToken::String(token)),
12609                            },
12610                        },
12611                        select(timer, progress).then(|either| match either {
12612                            Either::Left((message, ..)) => ready(message).left_future(),
12613                            Either::Right(..) => pending::<String>().right_future(),
12614                        }),
12615                    )
12616                    .await;
12617
12618                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
12619                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
12620                match response_result {
12621                    ConnectionResult::Timeout => {
12622                        log::error!("Timeout during workspace diagnostics pull");
12623                        continue 'request;
12624                    }
12625                    ConnectionResult::ConnectionReset => {
12626                        log::error!("Server closed a workspace diagnostics pull request");
12627                        continue 'request;
12628                    }
12629                    ConnectionResult::Result(Err(e)) => {
12630                        log::error!("Error during workspace diagnostics pull: {e:#}");
12631                        break 'request;
12632                    }
12633                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
12634                        attempts = 0;
12635                        if lsp_store
12636                            .update(cx, |lsp_store, cx| {
12637                                lsp_store.apply_workspace_diagnostic_report(
12638                                    server.server_id(),
12639                                    pulled_diagnostics,
12640                                    cx,
12641                                )
12642                            })
12643                            .is_err()
12644                        {
12645                            return;
12646                        }
12647                        break 'request;
12648                    }
12649                }
12650            }
12651        }
12652    });
12653
12654    Some(WorkspaceRefreshTask {
12655        refresh_tx,
12656        progress_tx,
12657        task: workspace_query_language_server,
12658    })
12659}
12660
12661fn diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<Option<String>> {
12662    match &options {
12663        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
12664            if !diagnostic_options.workspace_diagnostics {
12665                return None;
12666            }
12667            Some(diagnostic_options.identifier.clone())
12668        }
12669        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
12670            let diagnostic_options = &registration_options.diagnostic_options;
12671            if !diagnostic_options.workspace_diagnostics {
12672                return None;
12673            }
12674            Some(diagnostic_options.identifier.clone())
12675        }
12676    }
12677}
12678
12679fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
12680    let CompletionSource::BufferWord {
12681        word_range,
12682        resolved,
12683    } = &mut completion.source
12684    else {
12685        return;
12686    };
12687    if *resolved {
12688        return;
12689    }
12690
12691    if completion.new_text
12692        != snapshot
12693            .text_for_range(word_range.clone())
12694            .collect::<String>()
12695    {
12696        return;
12697    }
12698
12699    let mut offset = 0;
12700    for chunk in snapshot.chunks(word_range.clone(), true) {
12701        let end_offset = offset + chunk.text.len();
12702        if let Some(highlight_id) = chunk.syntax_highlight_id {
12703            completion
12704                .label
12705                .runs
12706                .push((offset..end_offset, highlight_id));
12707        }
12708        offset = end_offset;
12709    }
12710    *resolved = true;
12711}
12712
12713impl EventEmitter<LspStoreEvent> for LspStore {}
12714
12715fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
12716    hover
12717        .contents
12718        .retain(|hover_block| !hover_block.text.trim().is_empty());
12719    if hover.contents.is_empty() {
12720        None
12721    } else {
12722        Some(hover)
12723    }
12724}
12725
12726async fn populate_labels_for_completions(
12727    new_completions: Vec<CoreCompletion>,
12728    language: Option<Arc<Language>>,
12729    lsp_adapter: Option<Arc<CachedLspAdapter>>,
12730) -> Vec<Completion> {
12731    let lsp_completions = new_completions
12732        .iter()
12733        .filter_map(|new_completion| {
12734            new_completion
12735                .source
12736                .lsp_completion(true)
12737                .map(|lsp_completion| lsp_completion.into_owned())
12738        })
12739        .collect::<Vec<_>>();
12740
12741    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
12742        lsp_adapter
12743            .labels_for_completions(&lsp_completions, language)
12744            .await
12745            .log_err()
12746            .unwrap_or_default()
12747    } else {
12748        Vec::new()
12749    }
12750    .into_iter()
12751    .fuse();
12752
12753    let mut completions = Vec::new();
12754    for completion in new_completions {
12755        match completion.source.lsp_completion(true) {
12756            Some(lsp_completion) => {
12757                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
12758
12759                let mut label = labels.next().flatten().unwrap_or_else(|| {
12760                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
12761                });
12762                ensure_uniform_list_compatible_label(&mut label);
12763                completions.push(Completion {
12764                    label,
12765                    documentation,
12766                    replace_range: completion.replace_range,
12767                    new_text: completion.new_text,
12768                    insert_text_mode: lsp_completion.insert_text_mode,
12769                    source: completion.source,
12770                    icon_path: None,
12771                    confirm: None,
12772                });
12773            }
12774            None => {
12775                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
12776                ensure_uniform_list_compatible_label(&mut label);
12777                completions.push(Completion {
12778                    label,
12779                    documentation: None,
12780                    replace_range: completion.replace_range,
12781                    new_text: completion.new_text,
12782                    source: completion.source,
12783                    insert_text_mode: None,
12784                    icon_path: None,
12785                    confirm: None,
12786                });
12787            }
12788        }
12789    }
12790    completions
12791}
12792
12793#[derive(Debug)]
12794pub enum LanguageServerToQuery {
12795    /// Query language servers in order of users preference, up until one capable of handling the request is found.
12796    FirstCapable,
12797    /// Query a specific language server.
12798    Other(LanguageServerId),
12799}
12800
12801#[derive(Default)]
12802struct RenamePathsWatchedForServer {
12803    did_rename: Vec<RenameActionPredicate>,
12804    will_rename: Vec<RenameActionPredicate>,
12805}
12806
12807impl RenamePathsWatchedForServer {
12808    fn with_did_rename_patterns(
12809        mut self,
12810        did_rename: Option<&FileOperationRegistrationOptions>,
12811    ) -> Self {
12812        if let Some(did_rename) = did_rename {
12813            self.did_rename = did_rename
12814                .filters
12815                .iter()
12816                .filter_map(|filter| filter.try_into().log_err())
12817                .collect();
12818        }
12819        self
12820    }
12821    fn with_will_rename_patterns(
12822        mut self,
12823        will_rename: Option<&FileOperationRegistrationOptions>,
12824    ) -> Self {
12825        if let Some(will_rename) = will_rename {
12826            self.will_rename = will_rename
12827                .filters
12828                .iter()
12829                .filter_map(|filter| filter.try_into().log_err())
12830                .collect();
12831        }
12832        self
12833    }
12834
12835    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
12836        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
12837    }
12838    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
12839        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
12840    }
12841}
12842
12843impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
12844    type Error = globset::Error;
12845    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
12846        Ok(Self {
12847            kind: ops.pattern.matches.clone(),
12848            glob: GlobBuilder::new(&ops.pattern.glob)
12849                .case_insensitive(
12850                    ops.pattern
12851                        .options
12852                        .as_ref()
12853                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
12854                )
12855                .build()?
12856                .compile_matcher(),
12857        })
12858    }
12859}
12860struct RenameActionPredicate {
12861    glob: GlobMatcher,
12862    kind: Option<FileOperationPatternKind>,
12863}
12864
12865impl RenameActionPredicate {
12866    // Returns true if language server should be notified
12867    fn eval(&self, path: &str, is_dir: bool) -> bool {
12868        self.kind.as_ref().is_none_or(|kind| {
12869            let expected_kind = if is_dir {
12870                FileOperationPatternKind::Folder
12871            } else {
12872                FileOperationPatternKind::File
12873            };
12874            kind == &expected_kind
12875        }) && self.glob.is_match(path)
12876    }
12877}
12878
12879#[derive(Default)]
12880struct LanguageServerWatchedPaths {
12881    worktree_paths: HashMap<WorktreeId, GlobSet>,
12882    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
12883}
12884
12885#[derive(Default)]
12886struct LanguageServerWatchedPathsBuilder {
12887    worktree_paths: HashMap<WorktreeId, GlobSet>,
12888    abs_paths: HashMap<Arc<Path>, GlobSet>,
12889}
12890
12891impl LanguageServerWatchedPathsBuilder {
12892    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
12893        self.worktree_paths.insert(worktree_id, glob_set);
12894    }
12895    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
12896        self.abs_paths.insert(path, glob_set);
12897    }
12898    fn build(
12899        self,
12900        fs: Arc<dyn Fs>,
12901        language_server_id: LanguageServerId,
12902        cx: &mut Context<LspStore>,
12903    ) -> LanguageServerWatchedPaths {
12904        let project = cx.weak_entity();
12905
12906        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
12907        let abs_paths = self
12908            .abs_paths
12909            .into_iter()
12910            .map(|(abs_path, globset)| {
12911                let task = cx.spawn({
12912                    let abs_path = abs_path.clone();
12913                    let fs = fs.clone();
12914
12915                    let lsp_store = project.clone();
12916                    async move |_, cx| {
12917                        maybe!(async move {
12918                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
12919                            while let Some(update) = push_updates.0.next().await {
12920                                let action = lsp_store
12921                                    .update(cx, |this, _| {
12922                                        let Some(local) = this.as_local() else {
12923                                            return ControlFlow::Break(());
12924                                        };
12925                                        let Some(watcher) = local
12926                                            .language_server_watched_paths
12927                                            .get(&language_server_id)
12928                                        else {
12929                                            return ControlFlow::Break(());
12930                                        };
12931                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
12932                                            "Watched abs path is not registered with a watcher",
12933                                        );
12934                                        let matching_entries = update
12935                                            .into_iter()
12936                                            .filter(|event| globs.is_match(&event.path))
12937                                            .collect::<Vec<_>>();
12938                                        this.lsp_notify_abs_paths_changed(
12939                                            language_server_id,
12940                                            matching_entries,
12941                                        );
12942                                        ControlFlow::Continue(())
12943                                    })
12944                                    .ok()?;
12945
12946                                if action.is_break() {
12947                                    break;
12948                                }
12949                            }
12950                            Some(())
12951                        })
12952                        .await;
12953                    }
12954                });
12955                (abs_path, (globset, task))
12956            })
12957            .collect();
12958        LanguageServerWatchedPaths {
12959            worktree_paths: self.worktree_paths,
12960            abs_paths,
12961        }
12962    }
12963}
12964
12965struct LspBufferSnapshot {
12966    version: i32,
12967    snapshot: TextBufferSnapshot,
12968}
12969
12970/// A prompt requested by LSP server.
12971#[derive(Clone, Debug)]
12972pub struct LanguageServerPromptRequest {
12973    pub level: PromptLevel,
12974    pub message: String,
12975    pub actions: Vec<MessageActionItem>,
12976    pub lsp_name: String,
12977    pub(crate) response_channel: Sender<MessageActionItem>,
12978}
12979
12980impl LanguageServerPromptRequest {
12981    pub async fn respond(self, index: usize) -> Option<()> {
12982        if let Some(response) = self.actions.into_iter().nth(index) {
12983            self.response_channel.send(response).await.ok()
12984        } else {
12985            None
12986        }
12987    }
12988}
12989impl PartialEq for LanguageServerPromptRequest {
12990    fn eq(&self, other: &Self) -> bool {
12991        self.message == other.message && self.actions == other.actions
12992    }
12993}
12994
12995#[derive(Clone, Debug, PartialEq)]
12996pub enum LanguageServerLogType {
12997    Log(MessageType),
12998    Trace { verbose_info: Option<String> },
12999    Rpc { received: bool },
13000}
13001
13002impl LanguageServerLogType {
13003    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13004        match self {
13005            Self::Log(log_type) => {
13006                use proto::log_message::LogLevel;
13007                let level = match *log_type {
13008                    MessageType::ERROR => LogLevel::Error,
13009                    MessageType::WARNING => LogLevel::Warning,
13010                    MessageType::INFO => LogLevel::Info,
13011                    MessageType::LOG => LogLevel::Log,
13012                    other => {
13013                        log::warn!("Unknown lsp log message type: {other:?}");
13014                        LogLevel::Log
13015                    }
13016                };
13017                proto::language_server_log::LogType::Log(proto::LogMessage {
13018                    level: level as i32,
13019                })
13020            }
13021            Self::Trace { verbose_info } => {
13022                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13023                    verbose_info: verbose_info.to_owned(),
13024                })
13025            }
13026            Self::Rpc { received } => {
13027                let kind = if *received {
13028                    proto::rpc_message::Kind::Received
13029                } else {
13030                    proto::rpc_message::Kind::Sent
13031                };
13032                let kind = kind as i32;
13033                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13034            }
13035        }
13036    }
13037
13038    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13039        use proto::log_message::LogLevel;
13040        use proto::rpc_message;
13041        match log_type {
13042            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13043                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13044                    LogLevel::Error => MessageType::ERROR,
13045                    LogLevel::Warning => MessageType::WARNING,
13046                    LogLevel::Info => MessageType::INFO,
13047                    LogLevel::Log => MessageType::LOG,
13048                },
13049            ),
13050            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13051                verbose_info: trace_message.verbose_info,
13052            },
13053            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13054                received: match rpc_message::Kind::from_i32(message.kind)
13055                    .unwrap_or(rpc_message::Kind::Received)
13056                {
13057                    rpc_message::Kind::Received => true,
13058                    rpc_message::Kind::Sent => false,
13059                },
13060            },
13061        }
13062    }
13063}
13064
13065pub struct WorkspaceRefreshTask {
13066    refresh_tx: mpsc::Sender<()>,
13067    progress_tx: mpsc::Sender<()>,
13068    #[allow(dead_code)]
13069    task: Task<()>,
13070}
13071
13072pub enum LanguageServerState {
13073    Starting {
13074        startup: Task<Option<Arc<LanguageServer>>>,
13075        /// List of language servers that will be added to the workspace once it's initialization completes.
13076        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13077    },
13078
13079    Running {
13080        adapter: Arc<CachedLspAdapter>,
13081        server: Arc<LanguageServer>,
13082        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13083        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13084    },
13085}
13086
13087impl LanguageServerState {
13088    fn add_workspace_folder(&self, uri: Uri) {
13089        match self {
13090            LanguageServerState::Starting {
13091                pending_workspace_folders,
13092                ..
13093            } => {
13094                pending_workspace_folders.lock().insert(uri);
13095            }
13096            LanguageServerState::Running { server, .. } => {
13097                server.add_workspace_folder(uri);
13098            }
13099        }
13100    }
13101    fn _remove_workspace_folder(&self, uri: Uri) {
13102        match self {
13103            LanguageServerState::Starting {
13104                pending_workspace_folders,
13105                ..
13106            } => {
13107                pending_workspace_folders.lock().remove(&uri);
13108            }
13109            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13110        }
13111    }
13112}
13113
13114impl std::fmt::Debug for LanguageServerState {
13115    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13116        match self {
13117            LanguageServerState::Starting { .. } => {
13118                f.debug_struct("LanguageServerState::Starting").finish()
13119            }
13120            LanguageServerState::Running { .. } => {
13121                f.debug_struct("LanguageServerState::Running").finish()
13122            }
13123        }
13124    }
13125}
13126
13127#[derive(Clone, Debug, Serialize)]
13128pub struct LanguageServerProgress {
13129    pub is_disk_based_diagnostics_progress: bool,
13130    pub is_cancellable: bool,
13131    pub title: Option<String>,
13132    pub message: Option<String>,
13133    pub percentage: Option<usize>,
13134    #[serde(skip_serializing)]
13135    pub last_update_at: Instant,
13136}
13137
13138#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13139pub struct DiagnosticSummary {
13140    pub error_count: usize,
13141    pub warning_count: usize,
13142}
13143
13144impl DiagnosticSummary {
13145    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13146        let mut this = Self {
13147            error_count: 0,
13148            warning_count: 0,
13149        };
13150
13151        for entry in diagnostics {
13152            if entry.diagnostic.is_primary {
13153                match entry.diagnostic.severity {
13154                    DiagnosticSeverity::ERROR => this.error_count += 1,
13155                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13156                    _ => {}
13157                }
13158            }
13159        }
13160
13161        this
13162    }
13163
13164    pub fn is_empty(&self) -> bool {
13165        self.error_count == 0 && self.warning_count == 0
13166    }
13167
13168    pub fn to_proto(
13169        self,
13170        language_server_id: LanguageServerId,
13171        path: &RelPath,
13172    ) -> proto::DiagnosticSummary {
13173        proto::DiagnosticSummary {
13174            path: path.to_proto(),
13175            language_server_id: language_server_id.0 as u64,
13176            error_count: self.error_count as u32,
13177            warning_count: self.warning_count as u32,
13178        }
13179    }
13180}
13181
13182#[derive(Clone, Debug)]
13183pub enum CompletionDocumentation {
13184    /// There is no documentation for this completion.
13185    Undocumented,
13186    /// A single line of documentation.
13187    SingleLine(SharedString),
13188    /// Multiple lines of plain text documentation.
13189    MultiLinePlainText(SharedString),
13190    /// Markdown documentation.
13191    MultiLineMarkdown(SharedString),
13192    /// Both single line and multiple lines of plain text documentation.
13193    SingleLineAndMultiLinePlainText {
13194        single_line: SharedString,
13195        plain_text: Option<SharedString>,
13196    },
13197}
13198
13199impl CompletionDocumentation {
13200    #[cfg(any(test, feature = "test-support"))]
13201    pub fn text(&self) -> SharedString {
13202        match self {
13203            CompletionDocumentation::Undocumented => "".into(),
13204            CompletionDocumentation::SingleLine(s) => s.clone(),
13205            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13206            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13207            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13208                single_line.clone()
13209            }
13210        }
13211    }
13212}
13213
13214impl From<lsp::Documentation> for CompletionDocumentation {
13215    fn from(docs: lsp::Documentation) -> Self {
13216        match docs {
13217            lsp::Documentation::String(text) => {
13218                if text.lines().count() <= 1 {
13219                    CompletionDocumentation::SingleLine(text.into())
13220                } else {
13221                    CompletionDocumentation::MultiLinePlainText(text.into())
13222                }
13223            }
13224
13225            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13226                lsp::MarkupKind::PlainText => {
13227                    if value.lines().count() <= 1 {
13228                        CompletionDocumentation::SingleLine(value.into())
13229                    } else {
13230                        CompletionDocumentation::MultiLinePlainText(value.into())
13231                    }
13232                }
13233
13234                lsp::MarkupKind::Markdown => {
13235                    CompletionDocumentation::MultiLineMarkdown(value.into())
13236                }
13237            },
13238        }
13239    }
13240}
13241
13242pub enum ResolvedHint {
13243    Resolved(InlayHint),
13244    Resolving(Shared<Task<()>>),
13245}
13246
13247fn glob_literal_prefix(glob: &Path) -> PathBuf {
13248    glob.components()
13249        .take_while(|component| match component {
13250            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13251            _ => true,
13252        })
13253        .collect()
13254}
13255
13256pub struct SshLspAdapter {
13257    name: LanguageServerName,
13258    binary: LanguageServerBinary,
13259    initialization_options: Option<String>,
13260    code_action_kinds: Option<Vec<CodeActionKind>>,
13261}
13262
13263impl SshLspAdapter {
13264    pub fn new(
13265        name: LanguageServerName,
13266        binary: LanguageServerBinary,
13267        initialization_options: Option<String>,
13268        code_action_kinds: Option<String>,
13269    ) -> Self {
13270        Self {
13271            name,
13272            binary,
13273            initialization_options,
13274            code_action_kinds: code_action_kinds
13275                .as_ref()
13276                .and_then(|c| serde_json::from_str(c).ok()),
13277        }
13278    }
13279}
13280
13281impl LspInstaller for SshLspAdapter {
13282    type BinaryVersion = ();
13283    async fn check_if_user_installed(
13284        &self,
13285        _: &dyn LspAdapterDelegate,
13286        _: Option<Toolchain>,
13287        _: &AsyncApp,
13288    ) -> Option<LanguageServerBinary> {
13289        Some(self.binary.clone())
13290    }
13291
13292    async fn cached_server_binary(
13293        &self,
13294        _: PathBuf,
13295        _: &dyn LspAdapterDelegate,
13296    ) -> Option<LanguageServerBinary> {
13297        None
13298    }
13299
13300    async fn fetch_latest_server_version(
13301        &self,
13302        _: &dyn LspAdapterDelegate,
13303        _: bool,
13304        _: &mut AsyncApp,
13305    ) -> Result<()> {
13306        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13307    }
13308
13309    async fn fetch_server_binary(
13310        &self,
13311        _: (),
13312        _: PathBuf,
13313        _: &dyn LspAdapterDelegate,
13314    ) -> Result<LanguageServerBinary> {
13315        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13316    }
13317}
13318
13319#[async_trait(?Send)]
13320impl LspAdapter for SshLspAdapter {
13321    fn name(&self) -> LanguageServerName {
13322        self.name.clone()
13323    }
13324
13325    async fn initialization_options(
13326        self: Arc<Self>,
13327        _: &Arc<dyn LspAdapterDelegate>,
13328    ) -> Result<Option<serde_json::Value>> {
13329        let Some(options) = &self.initialization_options else {
13330            return Ok(None);
13331        };
13332        let result = serde_json::from_str(options)?;
13333        Ok(result)
13334    }
13335
13336    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13337        self.code_action_kinds.clone()
13338    }
13339}
13340
13341pub fn language_server_settings<'a>(
13342    delegate: &'a dyn LspAdapterDelegate,
13343    language: &LanguageServerName,
13344    cx: &'a App,
13345) -> Option<&'a LspSettings> {
13346    language_server_settings_for(
13347        SettingsLocation {
13348            worktree_id: delegate.worktree_id(),
13349            path: RelPath::empty(),
13350        },
13351        language,
13352        cx,
13353    )
13354}
13355
13356pub(crate) fn language_server_settings_for<'a>(
13357    location: SettingsLocation<'a>,
13358    language: &LanguageServerName,
13359    cx: &'a App,
13360) -> Option<&'a LspSettings> {
13361    ProjectSettings::get(Some(location), cx).lsp.get(language)
13362}
13363
13364pub struct LocalLspAdapterDelegate {
13365    lsp_store: WeakEntity<LspStore>,
13366    worktree: worktree::Snapshot,
13367    fs: Arc<dyn Fs>,
13368    http_client: Arc<dyn HttpClient>,
13369    language_registry: Arc<LanguageRegistry>,
13370    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13371}
13372
13373impl LocalLspAdapterDelegate {
13374    pub fn new(
13375        language_registry: Arc<LanguageRegistry>,
13376        environment: &Entity<ProjectEnvironment>,
13377        lsp_store: WeakEntity<LspStore>,
13378        worktree: &Entity<Worktree>,
13379        http_client: Arc<dyn HttpClient>,
13380        fs: Arc<dyn Fs>,
13381        cx: &mut App,
13382    ) -> Arc<Self> {
13383        let load_shell_env_task = environment.update(cx, |env, cx| {
13384            env.get_worktree_environment(worktree.clone(), cx)
13385        });
13386
13387        Arc::new(Self {
13388            lsp_store,
13389            worktree: worktree.read(cx).snapshot(),
13390            fs,
13391            http_client,
13392            language_registry,
13393            load_shell_env_task,
13394        })
13395    }
13396
13397    fn from_local_lsp(
13398        local: &LocalLspStore,
13399        worktree: &Entity<Worktree>,
13400        cx: &mut App,
13401    ) -> Arc<Self> {
13402        Self::new(
13403            local.languages.clone(),
13404            &local.environment,
13405            local.weak.clone(),
13406            worktree,
13407            local.http_client.clone(),
13408            local.fs.clone(),
13409            cx,
13410        )
13411    }
13412}
13413
13414#[async_trait]
13415impl LspAdapterDelegate for LocalLspAdapterDelegate {
13416    fn show_notification(&self, message: &str, cx: &mut App) {
13417        self.lsp_store
13418            .update(cx, |_, cx| {
13419                cx.emit(LspStoreEvent::Notification(message.to_owned()))
13420            })
13421            .ok();
13422    }
13423
13424    fn http_client(&self) -> Arc<dyn HttpClient> {
13425        self.http_client.clone()
13426    }
13427
13428    fn worktree_id(&self) -> WorktreeId {
13429        self.worktree.id()
13430    }
13431
13432    fn worktree_root_path(&self) -> &Path {
13433        self.worktree.abs_path().as_ref()
13434    }
13435
13436    async fn shell_env(&self) -> HashMap<String, String> {
13437        let task = self.load_shell_env_task.clone();
13438        task.await.unwrap_or_default()
13439    }
13440
13441    async fn npm_package_installed_version(
13442        &self,
13443        package_name: &str,
13444    ) -> Result<Option<(PathBuf, String)>> {
13445        let local_package_directory = self.worktree_root_path();
13446        let node_modules_directory = local_package_directory.join("node_modules");
13447
13448        if let Some(version) =
13449            read_package_installed_version(node_modules_directory.clone(), package_name).await?
13450        {
13451            return Ok(Some((node_modules_directory, version)));
13452        }
13453        let Some(npm) = self.which("npm".as_ref()).await else {
13454            log::warn!(
13455                "Failed to find npm executable for {:?}",
13456                local_package_directory
13457            );
13458            return Ok(None);
13459        };
13460
13461        let env = self.shell_env().await;
13462        let output = util::command::new_smol_command(&npm)
13463            .args(["root", "-g"])
13464            .envs(env)
13465            .current_dir(local_package_directory)
13466            .output()
13467            .await?;
13468        let global_node_modules =
13469            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
13470
13471        if let Some(version) =
13472            read_package_installed_version(global_node_modules.clone(), package_name).await?
13473        {
13474            return Ok(Some((global_node_modules, version)));
13475        }
13476        return Ok(None);
13477    }
13478
13479    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
13480        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
13481        if self.fs.is_file(&worktree_abs_path).await {
13482            worktree_abs_path.pop();
13483        }
13484
13485        let env = self.shell_env().await;
13486
13487        let shell_path = env.get("PATH").cloned();
13488
13489        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
13490    }
13491
13492    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
13493        let mut working_dir = self.worktree_root_path().to_path_buf();
13494        if self.fs.is_file(&working_dir).await {
13495            working_dir.pop();
13496        }
13497        let output = util::command::new_smol_command(&command.path)
13498            .args(command.arguments)
13499            .envs(command.env.clone().unwrap_or_default())
13500            .current_dir(working_dir)
13501            .output()
13502            .await?;
13503
13504        anyhow::ensure!(
13505            output.status.success(),
13506            "{}, stdout: {:?}, stderr: {:?}",
13507            output.status,
13508            String::from_utf8_lossy(&output.stdout),
13509            String::from_utf8_lossy(&output.stderr)
13510        );
13511        Ok(())
13512    }
13513
13514    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
13515        self.language_registry
13516            .update_lsp_binary_status(server_name, status);
13517    }
13518
13519    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
13520        self.language_registry
13521            .all_lsp_adapters()
13522            .into_iter()
13523            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
13524            .collect()
13525    }
13526
13527    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
13528        let dir = self.language_registry.language_server_download_dir(name)?;
13529
13530        if !dir.exists() {
13531            smol::fs::create_dir_all(&dir)
13532                .await
13533                .context("failed to create container directory")
13534                .log_err()?;
13535        }
13536
13537        Some(dir)
13538    }
13539
13540    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
13541        let entry = self
13542            .worktree
13543            .entry_for_path(path)
13544            .with_context(|| format!("no worktree entry for path {path:?}"))?;
13545        let abs_path = self.worktree.absolutize(&entry.path);
13546        self.fs.load(&abs_path).await
13547    }
13548}
13549
13550async fn populate_labels_for_symbols(
13551    symbols: Vec<CoreSymbol>,
13552    language_registry: &Arc<LanguageRegistry>,
13553    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13554    output: &mut Vec<Symbol>,
13555) {
13556    #[allow(clippy::mutable_key_type)]
13557    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
13558
13559    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
13560    for symbol in symbols {
13561        let Some(file_name) = symbol.path.file_name() else {
13562            continue;
13563        };
13564        let language = language_registry
13565            .load_language_for_file_path(Path::new(file_name))
13566            .await
13567            .ok()
13568            .or_else(|| {
13569                unknown_paths.insert(file_name.into());
13570                None
13571            });
13572        symbols_by_language
13573            .entry(language)
13574            .or_default()
13575            .push(symbol);
13576    }
13577
13578    for unknown_path in unknown_paths {
13579        log::info!("no language found for symbol in file {unknown_path:?}");
13580    }
13581
13582    let mut label_params = Vec::new();
13583    for (language, mut symbols) in symbols_by_language {
13584        label_params.clear();
13585        label_params.extend(
13586            symbols
13587                .iter_mut()
13588                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
13589        );
13590
13591        let mut labels = Vec::new();
13592        if let Some(language) = language {
13593            let lsp_adapter = lsp_adapter.clone().or_else(|| {
13594                language_registry
13595                    .lsp_adapters(&language.name())
13596                    .first()
13597                    .cloned()
13598            });
13599            if let Some(lsp_adapter) = lsp_adapter {
13600                labels = lsp_adapter
13601                    .labels_for_symbols(&label_params, &language)
13602                    .await
13603                    .log_err()
13604                    .unwrap_or_default();
13605            }
13606        }
13607
13608        for ((symbol, (name, _)), label) in symbols
13609            .into_iter()
13610            .zip(label_params.drain(..))
13611            .zip(labels.into_iter().chain(iter::repeat(None)))
13612        {
13613            output.push(Symbol {
13614                language_server_name: symbol.language_server_name,
13615                source_worktree_id: symbol.source_worktree_id,
13616                source_language_server_id: symbol.source_language_server_id,
13617                path: symbol.path,
13618                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
13619                name,
13620                kind: symbol.kind,
13621                range: symbol.range,
13622            });
13623        }
13624    }
13625}
13626
13627fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
13628    match server.capabilities().text_document_sync.as_ref()? {
13629        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
13630            // Server wants didSave but didn't specify includeText.
13631            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
13632            // Server doesn't want didSave at all.
13633            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
13634            // Server provided SaveOptions.
13635            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
13636                Some(save_options.include_text.unwrap_or(false))
13637            }
13638        },
13639        // We do not have any save info. Kind affects didChange only.
13640        lsp::TextDocumentSyncCapability::Kind(_) => None,
13641    }
13642}
13643
13644/// Completion items are displayed in a `UniformList`.
13645/// Usually, those items are single-line strings, but in LSP responses,
13646/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
13647/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
13648/// 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,
13649/// breaking the completions menu presentation.
13650///
13651/// 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.
13652fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
13653    let mut new_text = String::with_capacity(label.text.len());
13654    let mut offset_map = vec![0; label.text.len() + 1];
13655    let mut last_char_was_space = false;
13656    let mut new_idx = 0;
13657    let chars = label.text.char_indices().fuse();
13658    let mut newlines_removed = false;
13659
13660    for (idx, c) in chars {
13661        offset_map[idx] = new_idx;
13662
13663        match c {
13664            '\n' if last_char_was_space => {
13665                newlines_removed = true;
13666            }
13667            '\t' | ' ' if last_char_was_space => {}
13668            '\n' if !last_char_was_space => {
13669                new_text.push(' ');
13670                new_idx += 1;
13671                last_char_was_space = true;
13672                newlines_removed = true;
13673            }
13674            ' ' | '\t' => {
13675                new_text.push(' ');
13676                new_idx += 1;
13677                last_char_was_space = true;
13678            }
13679            _ => {
13680                new_text.push(c);
13681                new_idx += c.len_utf8();
13682                last_char_was_space = false;
13683            }
13684        }
13685    }
13686    offset_map[label.text.len()] = new_idx;
13687
13688    // Only modify the label if newlines were removed.
13689    if !newlines_removed {
13690        return;
13691    }
13692
13693    let last_index = new_idx;
13694    let mut run_ranges_errors = Vec::new();
13695    label.runs.retain_mut(|(range, _)| {
13696        match offset_map.get(range.start) {
13697            Some(&start) => range.start = start,
13698            None => {
13699                run_ranges_errors.push(range.clone());
13700                return false;
13701            }
13702        }
13703
13704        match offset_map.get(range.end) {
13705            Some(&end) => range.end = end,
13706            None => {
13707                run_ranges_errors.push(range.clone());
13708                range.end = last_index;
13709            }
13710        }
13711        true
13712    });
13713    if !run_ranges_errors.is_empty() {
13714        log::error!(
13715            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
13716            label.text
13717        );
13718    }
13719
13720    let mut wrong_filter_range = None;
13721    if label.filter_range == (0..label.text.len()) {
13722        label.filter_range = 0..new_text.len();
13723    } else {
13724        let mut original_filter_range = Some(label.filter_range.clone());
13725        match offset_map.get(label.filter_range.start) {
13726            Some(&start) => label.filter_range.start = start,
13727            None => {
13728                wrong_filter_range = original_filter_range.take();
13729                label.filter_range.start = last_index;
13730            }
13731        }
13732
13733        match offset_map.get(label.filter_range.end) {
13734            Some(&end) => label.filter_range.end = end,
13735            None => {
13736                wrong_filter_range = original_filter_range.take();
13737                label.filter_range.end = last_index;
13738            }
13739        }
13740    }
13741    if let Some(wrong_filter_range) = wrong_filter_range {
13742        log::error!(
13743            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
13744            label.text
13745        );
13746    }
13747
13748    label.text = new_text;
13749}
13750
13751#[cfg(test)]
13752mod tests {
13753    use language::HighlightId;
13754
13755    use super::*;
13756
13757    #[test]
13758    fn test_glob_literal_prefix() {
13759        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
13760        assert_eq!(
13761            glob_literal_prefix(Path::new("node_modules/**/*.js")),
13762            Path::new("node_modules")
13763        );
13764        assert_eq!(
13765            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13766            Path::new("foo")
13767        );
13768        assert_eq!(
13769            glob_literal_prefix(Path::new("foo/bar/baz.js")),
13770            Path::new("foo/bar/baz.js")
13771        );
13772
13773        #[cfg(target_os = "windows")]
13774        {
13775            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
13776            assert_eq!(
13777                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
13778                Path::new("node_modules")
13779            );
13780            assert_eq!(
13781                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13782                Path::new("foo")
13783            );
13784            assert_eq!(
13785                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
13786                Path::new("foo/bar/baz.js")
13787            );
13788        }
13789    }
13790
13791    #[test]
13792    fn test_multi_len_chars_normalization() {
13793        let mut label = CodeLabel::new(
13794            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
13795            0..6,
13796            vec![(0..6, HighlightId(1))],
13797        );
13798        ensure_uniform_list_compatible_label(&mut label);
13799        assert_eq!(
13800            label,
13801            CodeLabel::new(
13802                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
13803                0..6,
13804                vec![(0..6, HighlightId(1))],
13805            )
13806        );
13807    }
13808}