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