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.as_ref()
  567            && settings.path.is_some()
  568        {
  569            let settings = settings.clone();
  570
  571            return cx.background_spawn(async move {
  572                let mut env = delegate.shell_env().await;
  573                env.extend(settings.env.unwrap_or_default());
  574
  575                Ok(LanguageServerBinary {
  576                    path: PathBuf::from(&settings.path.unwrap()),
  577                    env: Some(env),
  578                    arguments: settings
  579                        .arguments
  580                        .unwrap_or_default()
  581                        .iter()
  582                        .map(Into::into)
  583                        .collect(),
  584                })
  585            });
  586        }
  587        let lsp_binary_options = LanguageServerBinaryOptions {
  588            allow_path_lookup: !settings
  589                .binary
  590                .as_ref()
  591                .and_then(|b| b.ignore_system_version)
  592                .unwrap_or_default(),
  593            allow_binary_download,
  594            pre_release: settings
  595                .fetch
  596                .as_ref()
  597                .and_then(|f| f.pre_release)
  598                .unwrap_or(false),
  599        };
  600
  601        cx.spawn(async move |cx| {
  602            let binary_result = adapter
  603                .clone()
  604                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  605                .await;
  606
  607            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  608
  609            let mut binary = binary_result?;
  610            let mut shell_env = delegate.shell_env().await;
  611
  612            shell_env.extend(binary.env.unwrap_or_default());
  613
  614            if let Some(settings) = settings.binary.as_ref() {
  615                if let Some(arguments) = &settings.arguments {
  616                    binary.arguments = arguments.iter().map(Into::into).collect();
  617                }
  618                if let Some(env) = &settings.env {
  619                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  620                }
  621            }
  622
  623            binary.env = Some(shell_env);
  624            Ok(binary)
  625        })
  626    }
  627
  628    fn setup_lsp_messages(
  629        lsp_store: WeakEntity<LspStore>,
  630        language_server: &LanguageServer,
  631        delegate: Arc<dyn LspAdapterDelegate>,
  632        adapter: Arc<CachedLspAdapter>,
  633    ) {
  634        let name = language_server.name();
  635        let server_id = language_server.server_id();
  636        language_server
  637            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  638                let adapter = adapter.clone();
  639                let this = lsp_store.clone();
  640                move |mut params, cx| {
  641                    let adapter = adapter.clone();
  642                    if let Some(this) = this.upgrade() {
  643                        this.update(cx, |this, cx| {
  644                            {
  645                                let buffer = params
  646                                    .uri
  647                                    .to_file_path()
  648                                    .map(|file_path| this.get_buffer(&file_path, cx))
  649                                    .ok()
  650                                    .flatten();
  651                                adapter.process_diagnostics(&mut params, server_id, buffer);
  652                            }
  653
  654                            this.merge_lsp_diagnostics(
  655                                DiagnosticSourceKind::Pushed,
  656                                vec![DocumentDiagnosticsUpdate {
  657                                    server_id,
  658                                    diagnostics: params,
  659                                    result_id: None,
  660                                    disk_based_sources: Cow::Borrowed(
  661                                        &adapter.disk_based_diagnostic_sources,
  662                                    ),
  663                                }],
  664                                |_, diagnostic, cx| match diagnostic.source_kind {
  665                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  666                                        adapter.retain_old_diagnostic(diagnostic, cx)
  667                                    }
  668                                    DiagnosticSourceKind::Pulled => true,
  669                                },
  670                                cx,
  671                            )
  672                            .log_err();
  673                        })
  674                        .ok();
  675                    }
  676                }
  677            })
  678            .detach();
  679        language_server
  680            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  681                let adapter = adapter.adapter.clone();
  682                let delegate = delegate.clone();
  683                let this = lsp_store.clone();
  684                move |params, cx| {
  685                    let adapter = adapter.clone();
  686                    let delegate = delegate.clone();
  687                    let this = this.clone();
  688                    let mut cx = cx.clone();
  689                    async move {
  690                        let toolchain_for_id = this
  691                            .update(&mut cx, |this, _| {
  692                                this.as_local()?.language_server_ids.iter().find_map(
  693                                    |(seed, value)| {
  694                                        (value.id == server_id).then(|| seed.toolchain.clone())
  695                                    },
  696                                )
  697                            })?
  698                            .context("Expected the LSP store to be in a local mode")?;
  699                        let workspace_config = Self::workspace_configuration_for_adapter(
  700                            adapter.clone(),
  701                            &delegate,
  702                            toolchain_for_id,
  703                            &mut cx,
  704                        )
  705                        .await?;
  706
  707                        Ok(params
  708                            .items
  709                            .into_iter()
  710                            .map(|item| {
  711                                if let Some(section) = &item.section {
  712                                    workspace_config
  713                                        .get(section)
  714                                        .cloned()
  715                                        .unwrap_or(serde_json::Value::Null)
  716                                } else {
  717                                    workspace_config.clone()
  718                                }
  719                            })
  720                            .collect())
  721                    }
  722                }
  723            })
  724            .detach();
  725
  726        language_server
  727            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  728                let this = lsp_store.clone();
  729                move |_, cx| {
  730                    let this = this.clone();
  731                    let cx = cx.clone();
  732                    async move {
  733                        let Some(server) =
  734                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  735                        else {
  736                            return Ok(None);
  737                        };
  738                        let root = server.workspace_folders();
  739                        Ok(Some(
  740                            root.into_iter()
  741                                .map(|uri| WorkspaceFolder {
  742                                    uri,
  743                                    name: Default::default(),
  744                                })
  745                                .collect(),
  746                        ))
  747                    }
  748                }
  749            })
  750            .detach();
  751        // Even though we don't have handling for these requests, respond to them to
  752        // avoid stalling any language server like `gopls` which waits for a response
  753        // to these requests when initializing.
  754        language_server
  755            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  756                let this = lsp_store.clone();
  757                move |params, cx| {
  758                    let this = this.clone();
  759                    let mut cx = cx.clone();
  760                    async move {
  761                        this.update(&mut cx, |this, _| {
  762                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  763                            {
  764                                status
  765                                    .progress_tokens
  766                                    .insert(ProgressToken::from_lsp(params.token));
  767                            }
  768                        })?;
  769
  770                        Ok(())
  771                    }
  772                }
  773            })
  774            .detach();
  775
  776        language_server
  777            .on_request::<lsp::request::RegisterCapability, _, _>({
  778                let lsp_store = lsp_store.clone();
  779                move |params, cx| {
  780                    let lsp_store = lsp_store.clone();
  781                    let mut cx = cx.clone();
  782                    async move {
  783                        lsp_store
  784                            .update(&mut cx, |lsp_store, cx| {
  785                                if lsp_store.as_local().is_some() {
  786                                    match lsp_store
  787                                        .register_server_capabilities(server_id, params, cx)
  788                                    {
  789                                        Ok(()) => {}
  790                                        Err(e) => {
  791                                            log::error!(
  792                                                "Failed to register server capabilities: {e:#}"
  793                                            );
  794                                        }
  795                                    };
  796                                }
  797                            })
  798                            .ok();
  799                        Ok(())
  800                    }
  801                }
  802            })
  803            .detach();
  804
  805        language_server
  806            .on_request::<lsp::request::UnregisterCapability, _, _>({
  807                let lsp_store = lsp_store.clone();
  808                move |params, cx| {
  809                    let lsp_store = lsp_store.clone();
  810                    let mut cx = cx.clone();
  811                    async move {
  812                        lsp_store
  813                            .update(&mut cx, |lsp_store, cx| {
  814                                if lsp_store.as_local().is_some() {
  815                                    match lsp_store
  816                                        .unregister_server_capabilities(server_id, params, cx)
  817                                    {
  818                                        Ok(()) => {}
  819                                        Err(e) => {
  820                                            log::error!(
  821                                                "Failed to unregister server capabilities: {e:#}"
  822                                            );
  823                                        }
  824                                    }
  825                                }
  826                            })
  827                            .ok();
  828                        Ok(())
  829                    }
  830                }
  831            })
  832            .detach();
  833
  834        language_server
  835            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  836                let this = lsp_store.clone();
  837                move |params, cx| {
  838                    let mut cx = cx.clone();
  839                    let this = this.clone();
  840                    async move {
  841                        LocalLspStore::on_lsp_workspace_edit(
  842                            this.clone(),
  843                            params,
  844                            server_id,
  845                            &mut cx,
  846                        )
  847                        .await
  848                    }
  849                }
  850            })
  851            .detach();
  852
  853        language_server
  854            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  855                let lsp_store = lsp_store.clone();
  856                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::info!(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_command::<GetCompletions>);
 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    pub fn request_lsp<R>(
 4467        &mut self,
 4468        buffer: Entity<Buffer>,
 4469        server: LanguageServerToQuery,
 4470        request: R,
 4471        cx: &mut Context<Self>,
 4472    ) -> Task<Result<R::Response>>
 4473    where
 4474        R: LspCommand,
 4475        <R::LspRequest as lsp::request::Request>::Result: Send,
 4476        <R::LspRequest as lsp::request::Request>::Params: Send,
 4477    {
 4478        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4479            return self.send_lsp_proto_request(
 4480                buffer,
 4481                upstream_client,
 4482                upstream_project_id,
 4483                request,
 4484                cx,
 4485            );
 4486        }
 4487
 4488        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4489            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4490                local
 4491                    .language_servers_for_buffer(buffer, cx)
 4492                    .find(|(_, server)| {
 4493                        request.check_capabilities(server.adapter_server_capabilities())
 4494                    })
 4495                    .map(|(_, server)| server.clone())
 4496            }),
 4497            LanguageServerToQuery::Other(id) => self
 4498                .language_server_for_local_buffer(buffer, id, cx)
 4499                .and_then(|(_, server)| {
 4500                    request
 4501                        .check_capabilities(server.adapter_server_capabilities())
 4502                        .then(|| Arc::clone(server))
 4503                }),
 4504        }) else {
 4505            return Task::ready(Ok(Default::default()));
 4506        };
 4507
 4508        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4509
 4510        let Some(file) = file else {
 4511            return Task::ready(Ok(Default::default()));
 4512        };
 4513
 4514        let lsp_params = match request.to_lsp_params_or_response(
 4515            &file.abs_path(cx),
 4516            buffer.read(cx),
 4517            &language_server,
 4518            cx,
 4519        ) {
 4520            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4521            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4522
 4523            Err(err) => {
 4524                let message = format!(
 4525                    "{} via {} failed: {}",
 4526                    request.display_name(),
 4527                    language_server.name(),
 4528                    err
 4529                );
 4530                log::warn!("{message}");
 4531                return Task::ready(Err(anyhow!(message)));
 4532            }
 4533        };
 4534
 4535        let status = request.status();
 4536        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4537            return Task::ready(Ok(Default::default()));
 4538        }
 4539        cx.spawn(async move |this, cx| {
 4540            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4541
 4542            let id = lsp_request.id();
 4543            let _cleanup = if status.is_some() {
 4544                cx.update(|cx| {
 4545                    this.update(cx, |this, cx| {
 4546                        this.on_lsp_work_start(
 4547                            language_server.server_id(),
 4548                            ProgressToken::Number(id),
 4549                            LanguageServerProgress {
 4550                                is_disk_based_diagnostics_progress: false,
 4551                                is_cancellable: false,
 4552                                title: None,
 4553                                message: status.clone(),
 4554                                percentage: None,
 4555                                last_update_at: cx.background_executor().now(),
 4556                            },
 4557                            cx,
 4558                        );
 4559                    })
 4560                })
 4561                .log_err();
 4562
 4563                Some(defer(|| {
 4564                    cx.update(|cx| {
 4565                        this.update(cx, |this, cx| {
 4566                            this.on_lsp_work_end(
 4567                                language_server.server_id(),
 4568                                ProgressToken::Number(id),
 4569                                cx,
 4570                            );
 4571                        })
 4572                    })
 4573                    .log_err();
 4574                }))
 4575            } else {
 4576                None
 4577            };
 4578
 4579            let result = lsp_request.await.into_response();
 4580
 4581            let response = result.map_err(|err| {
 4582                let message = format!(
 4583                    "{} via {} failed: {}",
 4584                    request.display_name(),
 4585                    language_server.name(),
 4586                    err
 4587                );
 4588                log::warn!("{message}");
 4589                anyhow::anyhow!(message)
 4590            })?;
 4591
 4592            request
 4593                .response_from_lsp(
 4594                    response,
 4595                    this.upgrade().context("no app context")?,
 4596                    buffer,
 4597                    language_server.server_id(),
 4598                    cx.clone(),
 4599                )
 4600                .await
 4601        })
 4602    }
 4603
 4604    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4605        let mut language_formatters_to_check = Vec::new();
 4606        for buffer in self.buffer_store.read(cx).buffers() {
 4607            let buffer = buffer.read(cx);
 4608            let buffer_file = File::from_dyn(buffer.file());
 4609            let buffer_language = buffer.language();
 4610            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4611            if buffer_language.is_some() {
 4612                language_formatters_to_check.push((
 4613                    buffer_file.map(|f| f.worktree_id(cx)),
 4614                    settings.into_owned(),
 4615                ));
 4616            }
 4617        }
 4618
 4619        self.request_workspace_config_refresh();
 4620
 4621        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4622            prettier_store.update(cx, |prettier_store, cx| {
 4623                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4624            })
 4625        }
 4626
 4627        cx.notify();
 4628    }
 4629
 4630    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4631        let buffer_store = self.buffer_store.clone();
 4632        let Some(local) = self.as_local_mut() else {
 4633            return;
 4634        };
 4635        let mut adapters = BTreeMap::default();
 4636        let get_adapter = {
 4637            let languages = local.languages.clone();
 4638            let environment = local.environment.clone();
 4639            let weak = local.weak.clone();
 4640            let worktree_store = local.worktree_store.clone();
 4641            let http_client = local.http_client.clone();
 4642            let fs = local.fs.clone();
 4643            move |worktree_id, cx: &mut App| {
 4644                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4645                Some(LocalLspAdapterDelegate::new(
 4646                    languages.clone(),
 4647                    &environment,
 4648                    weak.clone(),
 4649                    &worktree,
 4650                    http_client.clone(),
 4651                    fs.clone(),
 4652                    cx,
 4653                ))
 4654            }
 4655        };
 4656
 4657        let mut messages_to_report = Vec::new();
 4658        let (new_tree, to_stop) = {
 4659            let mut rebase = local.lsp_tree.rebase();
 4660            let buffers = buffer_store
 4661                .read(cx)
 4662                .buffers()
 4663                .filter_map(|buffer| {
 4664                    let raw_buffer = buffer.read(cx);
 4665                    if !local
 4666                        .registered_buffers
 4667                        .contains_key(&raw_buffer.remote_id())
 4668                    {
 4669                        return None;
 4670                    }
 4671                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4672                    let language = raw_buffer.language().cloned()?;
 4673                    Some((file, language, raw_buffer.remote_id()))
 4674                })
 4675                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4676            for (file, language, buffer_id) in buffers {
 4677                let worktree_id = file.worktree_id(cx);
 4678                let Some(worktree) = local
 4679                    .worktree_store
 4680                    .read(cx)
 4681                    .worktree_for_id(worktree_id, cx)
 4682                else {
 4683                    continue;
 4684                };
 4685
 4686                if let Some((_, apply)) = local.reuse_existing_language_server(
 4687                    rebase.server_tree(),
 4688                    &worktree,
 4689                    &language.name(),
 4690                    cx,
 4691                ) {
 4692                    (apply)(rebase.server_tree());
 4693                } else if let Some(lsp_delegate) = adapters
 4694                    .entry(worktree_id)
 4695                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4696                    .clone()
 4697                {
 4698                    let delegate =
 4699                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4700                    let path = file
 4701                        .path()
 4702                        .parent()
 4703                        .map(Arc::from)
 4704                        .unwrap_or_else(|| file.path().clone());
 4705                    let worktree_path = ProjectPath { worktree_id, path };
 4706                    let abs_path = file.abs_path(cx);
 4707                    let nodes = rebase
 4708                        .walk(
 4709                            worktree_path,
 4710                            language.name(),
 4711                            language.manifest(),
 4712                            delegate.clone(),
 4713                            cx,
 4714                        )
 4715                        .collect::<Vec<_>>();
 4716                    for node in nodes {
 4717                        let server_id = node.server_id_or_init(|disposition| {
 4718                            let path = &disposition.path;
 4719                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 4720                            let key = LanguageServerSeed {
 4721                                worktree_id,
 4722                                name: disposition.server_name.clone(),
 4723                                settings: disposition.settings.clone(),
 4724                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4725                                    path.worktree_id,
 4726                                    &path.path,
 4727                                    language.name(),
 4728                                ),
 4729                            };
 4730                            local.language_server_ids.remove(&key);
 4731
 4732                            let server_id = local.get_or_insert_language_server(
 4733                                &worktree,
 4734                                lsp_delegate.clone(),
 4735                                disposition,
 4736                                &language.name(),
 4737                                cx,
 4738                            );
 4739                            if let Some(state) = local.language_servers.get(&server_id)
 4740                                && let Ok(uri) = uri
 4741                            {
 4742                                state.add_workspace_folder(uri);
 4743                            };
 4744                            server_id
 4745                        });
 4746
 4747                        if let Some(language_server_id) = server_id {
 4748                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 4749                                language_server_id,
 4750                                name: node.name(),
 4751                                message:
 4752                                    proto::update_language_server::Variant::RegisteredForBuffer(
 4753                                        proto::RegisteredForBuffer {
 4754                                            buffer_abs_path: abs_path
 4755                                                .to_string_lossy()
 4756                                                .into_owned(),
 4757                                            buffer_id: buffer_id.to_proto(),
 4758                                        },
 4759                                    ),
 4760                            });
 4761                        }
 4762                    }
 4763                } else {
 4764                    continue;
 4765                }
 4766            }
 4767            rebase.finish()
 4768        };
 4769        for message in messages_to_report {
 4770            cx.emit(message);
 4771        }
 4772        local.lsp_tree = new_tree;
 4773        for (id, _) in to_stop {
 4774            self.stop_local_language_server(id, cx).detach();
 4775        }
 4776    }
 4777
 4778    pub fn apply_code_action(
 4779        &self,
 4780        buffer_handle: Entity<Buffer>,
 4781        mut action: CodeAction,
 4782        push_to_history: bool,
 4783        cx: &mut Context<Self>,
 4784    ) -> Task<Result<ProjectTransaction>> {
 4785        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4786            let request = proto::ApplyCodeAction {
 4787                project_id,
 4788                buffer_id: buffer_handle.read(cx).remote_id().into(),
 4789                action: Some(Self::serialize_code_action(&action)),
 4790            };
 4791            let buffer_store = self.buffer_store();
 4792            cx.spawn(async move |_, cx| {
 4793                let response = upstream_client
 4794                    .request(request)
 4795                    .await?
 4796                    .transaction
 4797                    .context("missing transaction")?;
 4798
 4799                buffer_store
 4800                    .update(cx, |buffer_store, cx| {
 4801                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 4802                    })?
 4803                    .await
 4804            })
 4805        } else if self.mode.is_local() {
 4806            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 4807                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 4808                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 4809            }) else {
 4810                return Task::ready(Ok(ProjectTransaction::default()));
 4811            };
 4812            cx.spawn(async move |this,  cx| {
 4813                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 4814                    .await
 4815                    .context("resolving a code action")?;
 4816                if let Some(edit) = action.lsp_action.edit()
 4817                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 4818                        return LocalLspStore::deserialize_workspace_edit(
 4819                            this.upgrade().context("no app present")?,
 4820                            edit.clone(),
 4821                            push_to_history,
 4822
 4823                            lang_server.clone(),
 4824                            cx,
 4825                        )
 4826                        .await;
 4827                    }
 4828
 4829                if let Some(command) = action.lsp_action.command() {
 4830                    let server_capabilities = lang_server.capabilities();
 4831                    let available_commands = server_capabilities
 4832                        .execute_command_provider
 4833                        .as_ref()
 4834                        .map(|options| options.commands.as_slice())
 4835                        .unwrap_or_default();
 4836                    if available_commands.contains(&command.command) {
 4837                        this.update(cx, |this, _| {
 4838                            this.as_local_mut()
 4839                                .unwrap()
 4840                                .last_workspace_edits_by_language_server
 4841                                .remove(&lang_server.server_id());
 4842                        })?;
 4843
 4844                        let _result = lang_server
 4845                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 4846                                command: command.command.clone(),
 4847                                arguments: command.arguments.clone().unwrap_or_default(),
 4848                                ..lsp::ExecuteCommandParams::default()
 4849                            })
 4850                            .await.into_response()
 4851                            .context("execute command")?;
 4852
 4853                        return this.update(cx, |this, _| {
 4854                            this.as_local_mut()
 4855                                .unwrap()
 4856                                .last_workspace_edits_by_language_server
 4857                                .remove(&lang_server.server_id())
 4858                                .unwrap_or_default()
 4859                        });
 4860                    } else {
 4861                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 4862                    }
 4863                }
 4864
 4865                Ok(ProjectTransaction::default())
 4866            })
 4867        } else {
 4868            Task::ready(Err(anyhow!("no upstream client and not local")))
 4869        }
 4870    }
 4871
 4872    pub fn apply_code_action_kind(
 4873        &mut self,
 4874        buffers: HashSet<Entity<Buffer>>,
 4875        kind: CodeActionKind,
 4876        push_to_history: bool,
 4877        cx: &mut Context<Self>,
 4878    ) -> Task<anyhow::Result<ProjectTransaction>> {
 4879        if self.as_local().is_some() {
 4880            cx.spawn(async move |lsp_store, cx| {
 4881                let buffers = buffers.into_iter().collect::<Vec<_>>();
 4882                let result = LocalLspStore::execute_code_action_kind_locally(
 4883                    lsp_store.clone(),
 4884                    buffers,
 4885                    kind,
 4886                    push_to_history,
 4887                    cx,
 4888                )
 4889                .await;
 4890                lsp_store.update(cx, |lsp_store, _| {
 4891                    lsp_store.update_last_formatting_failure(&result);
 4892                })?;
 4893                result
 4894            })
 4895        } else if let Some((client, project_id)) = self.upstream_client() {
 4896            let buffer_store = self.buffer_store();
 4897            cx.spawn(async move |lsp_store, cx| {
 4898                let result = client
 4899                    .request(proto::ApplyCodeActionKind {
 4900                        project_id,
 4901                        kind: kind.as_str().to_owned(),
 4902                        buffer_ids: buffers
 4903                            .iter()
 4904                            .map(|buffer| {
 4905                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 4906                            })
 4907                            .collect::<Result<_>>()?,
 4908                    })
 4909                    .await
 4910                    .and_then(|result| result.transaction.context("missing transaction"));
 4911                lsp_store.update(cx, |lsp_store, _| {
 4912                    lsp_store.update_last_formatting_failure(&result);
 4913                })?;
 4914
 4915                let transaction_response = result?;
 4916                buffer_store
 4917                    .update(cx, |buffer_store, cx| {
 4918                        buffer_store.deserialize_project_transaction(
 4919                            transaction_response,
 4920                            push_to_history,
 4921                            cx,
 4922                        )
 4923                    })?
 4924                    .await
 4925            })
 4926        } else {
 4927            Task::ready(Ok(ProjectTransaction::default()))
 4928        }
 4929    }
 4930
 4931    pub fn resolved_hint(
 4932        &mut self,
 4933        buffer_id: BufferId,
 4934        id: InlayId,
 4935        cx: &mut Context<Self>,
 4936    ) -> Option<ResolvedHint> {
 4937        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 4938
 4939        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 4940        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 4941        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 4942        let (server_id, resolve_data) = match &hint.resolve_state {
 4943            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 4944            ResolveState::Resolving => {
 4945                return Some(ResolvedHint::Resolving(
 4946                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 4947                ));
 4948            }
 4949            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 4950        };
 4951
 4952        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 4953        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 4954        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 4955            id,
 4956            cx.spawn(async move |lsp_store, cx| {
 4957                let resolved_hint = resolve_task.await;
 4958                lsp_store
 4959                    .update(cx, |lsp_store, _| {
 4960                        if let Some(old_inlay_hint) = lsp_store
 4961                            .lsp_data
 4962                            .get_mut(&buffer_id)
 4963                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 4964                        {
 4965                            match resolved_hint {
 4966                                Ok(resolved_hint) => {
 4967                                    *old_inlay_hint = resolved_hint;
 4968                                }
 4969                                Err(e) => {
 4970                                    old_inlay_hint.resolve_state =
 4971                                        ResolveState::CanResolve(server_id, resolve_data);
 4972                                    log::error!("Inlay hint resolve failed: {e:#}");
 4973                                }
 4974                            }
 4975                        }
 4976                    })
 4977                    .ok();
 4978            })
 4979            .shared(),
 4980        );
 4981        debug_assert!(
 4982            previous_task.is_none(),
 4983            "Did not change hint's resolve state after spawning its resolve"
 4984        );
 4985        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 4986        None
 4987    }
 4988
 4989    fn resolve_inlay_hint(
 4990        &self,
 4991        mut hint: InlayHint,
 4992        buffer: Entity<Buffer>,
 4993        server_id: LanguageServerId,
 4994        cx: &mut Context<Self>,
 4995    ) -> Task<anyhow::Result<InlayHint>> {
 4996        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4997            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 4998            {
 4999                hint.resolve_state = ResolveState::Resolved;
 5000                return Task::ready(Ok(hint));
 5001            }
 5002            let request = proto::ResolveInlayHint {
 5003                project_id,
 5004                buffer_id: buffer.read(cx).remote_id().into(),
 5005                language_server_id: server_id.0 as u64,
 5006                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 5007            };
 5008            cx.background_spawn(async move {
 5009                let response = upstream_client
 5010                    .request(request)
 5011                    .await
 5012                    .context("inlay hints proto request")?;
 5013                match response.hint {
 5014                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5015                        .context("inlay hints proto resolve response conversion"),
 5016                    None => Ok(hint),
 5017                }
 5018            })
 5019        } else {
 5020            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5021                self.language_server_for_local_buffer(buffer, server_id, cx)
 5022                    .map(|(_, server)| server.clone())
 5023            }) else {
 5024                return Task::ready(Ok(hint));
 5025            };
 5026            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5027                return Task::ready(Ok(hint));
 5028            }
 5029            let buffer_snapshot = buffer.read(cx).snapshot();
 5030            cx.spawn(async move |_, cx| {
 5031                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5032                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5033                );
 5034                let resolved_hint = resolve_task
 5035                    .await
 5036                    .into_response()
 5037                    .context("inlay hint resolve LSP request")?;
 5038                let resolved_hint = InlayHints::lsp_to_project_hint(
 5039                    resolved_hint,
 5040                    &buffer,
 5041                    server_id,
 5042                    ResolveState::Resolved,
 5043                    false,
 5044                    cx,
 5045                )
 5046                .await?;
 5047                Ok(resolved_hint)
 5048            })
 5049        }
 5050    }
 5051
 5052    pub fn resolve_color_presentation(
 5053        &mut self,
 5054        mut color: DocumentColor,
 5055        buffer: Entity<Buffer>,
 5056        server_id: LanguageServerId,
 5057        cx: &mut Context<Self>,
 5058    ) -> Task<Result<DocumentColor>> {
 5059        if color.resolved {
 5060            return Task::ready(Ok(color));
 5061        }
 5062
 5063        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5064            let start = color.lsp_range.start;
 5065            let end = color.lsp_range.end;
 5066            let request = proto::GetColorPresentation {
 5067                project_id,
 5068                server_id: server_id.to_proto(),
 5069                buffer_id: buffer.read(cx).remote_id().into(),
 5070                color: Some(proto::ColorInformation {
 5071                    red: color.color.red,
 5072                    green: color.color.green,
 5073                    blue: color.color.blue,
 5074                    alpha: color.color.alpha,
 5075                    lsp_range_start: Some(proto::PointUtf16 {
 5076                        row: start.line,
 5077                        column: start.character,
 5078                    }),
 5079                    lsp_range_end: Some(proto::PointUtf16 {
 5080                        row: end.line,
 5081                        column: end.character,
 5082                    }),
 5083                }),
 5084            };
 5085            cx.background_spawn(async move {
 5086                let response = upstream_client
 5087                    .request(request)
 5088                    .await
 5089                    .context("color presentation proto request")?;
 5090                color.resolved = true;
 5091                color.color_presentations = response
 5092                    .presentations
 5093                    .into_iter()
 5094                    .map(|presentation| ColorPresentation {
 5095                        label: SharedString::from(presentation.label),
 5096                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5097                        additional_text_edits: presentation
 5098                            .additional_text_edits
 5099                            .into_iter()
 5100                            .filter_map(deserialize_lsp_edit)
 5101                            .collect(),
 5102                    })
 5103                    .collect();
 5104                Ok(color)
 5105            })
 5106        } else {
 5107            let path = match buffer
 5108                .update(cx, |buffer, cx| {
 5109                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5110                })
 5111                .context("buffer with the missing path")
 5112            {
 5113                Ok(path) => path,
 5114                Err(e) => return Task::ready(Err(e)),
 5115            };
 5116            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5117                self.language_server_for_local_buffer(buffer, server_id, cx)
 5118                    .map(|(_, server)| server.clone())
 5119            }) else {
 5120                return Task::ready(Ok(color));
 5121            };
 5122            cx.background_spawn(async move {
 5123                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5124                    lsp::ColorPresentationParams {
 5125                        text_document: make_text_document_identifier(&path)?,
 5126                        color: color.color,
 5127                        range: color.lsp_range,
 5128                        work_done_progress_params: Default::default(),
 5129                        partial_result_params: Default::default(),
 5130                    },
 5131                );
 5132                color.color_presentations = resolve_task
 5133                    .await
 5134                    .into_response()
 5135                    .context("color presentation resolve LSP request")?
 5136                    .into_iter()
 5137                    .map(|presentation| ColorPresentation {
 5138                        label: SharedString::from(presentation.label),
 5139                        text_edit: presentation.text_edit,
 5140                        additional_text_edits: presentation
 5141                            .additional_text_edits
 5142                            .unwrap_or_default(),
 5143                    })
 5144                    .collect();
 5145                color.resolved = true;
 5146                Ok(color)
 5147            })
 5148        }
 5149    }
 5150
 5151    pub(crate) fn linked_edits(
 5152        &mut self,
 5153        buffer: &Entity<Buffer>,
 5154        position: Anchor,
 5155        cx: &mut Context<Self>,
 5156    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5157        let snapshot = buffer.read(cx).snapshot();
 5158        let scope = snapshot.language_scope_at(position);
 5159        let Some(server_id) = self
 5160            .as_local()
 5161            .and_then(|local| {
 5162                buffer.update(cx, |buffer, cx| {
 5163                    local
 5164                        .language_servers_for_buffer(buffer, cx)
 5165                        .filter(|(_, server)| {
 5166                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5167                        })
 5168                        .filter(|(adapter, _)| {
 5169                            scope
 5170                                .as_ref()
 5171                                .map(|scope| scope.language_allowed(&adapter.name))
 5172                                .unwrap_or(true)
 5173                        })
 5174                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5175                        .next()
 5176                })
 5177            })
 5178            .or_else(|| {
 5179                self.upstream_client()
 5180                    .is_some()
 5181                    .then_some(LanguageServerToQuery::FirstCapable)
 5182            })
 5183            .filter(|_| {
 5184                maybe!({
 5185                    let language = buffer.read(cx).language_at(position)?;
 5186                    Some(
 5187                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5188                            .linked_edits,
 5189                    )
 5190                }) == Some(true)
 5191            })
 5192        else {
 5193            return Task::ready(Ok(Vec::new()));
 5194        };
 5195
 5196        self.request_lsp(
 5197            buffer.clone(),
 5198            server_id,
 5199            LinkedEditingRange { position },
 5200            cx,
 5201        )
 5202    }
 5203
 5204    fn apply_on_type_formatting(
 5205        &mut self,
 5206        buffer: Entity<Buffer>,
 5207        position: Anchor,
 5208        trigger: String,
 5209        cx: &mut Context<Self>,
 5210    ) -> Task<Result<Option<Transaction>>> {
 5211        if let Some((client, project_id)) = self.upstream_client() {
 5212            if !self.check_if_capable_for_proto_request(
 5213                &buffer,
 5214                |capabilities| {
 5215                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5216                },
 5217                cx,
 5218            ) {
 5219                return Task::ready(Ok(None));
 5220            }
 5221            let request = proto::OnTypeFormatting {
 5222                project_id,
 5223                buffer_id: buffer.read(cx).remote_id().into(),
 5224                position: Some(serialize_anchor(&position)),
 5225                trigger,
 5226                version: serialize_version(&buffer.read(cx).version()),
 5227            };
 5228            cx.background_spawn(async move {
 5229                client
 5230                    .request(request)
 5231                    .await?
 5232                    .transaction
 5233                    .map(language::proto::deserialize_transaction)
 5234                    .transpose()
 5235            })
 5236        } else if let Some(local) = self.as_local_mut() {
 5237            let buffer_id = buffer.read(cx).remote_id();
 5238            local.buffers_being_formatted.insert(buffer_id);
 5239            cx.spawn(async move |this, cx| {
 5240                let _cleanup = defer({
 5241                    let this = this.clone();
 5242                    let mut cx = cx.clone();
 5243                    move || {
 5244                        this.update(&mut cx, |this, _| {
 5245                            if let Some(local) = this.as_local_mut() {
 5246                                local.buffers_being_formatted.remove(&buffer_id);
 5247                            }
 5248                        })
 5249                        .ok();
 5250                    }
 5251                });
 5252
 5253                buffer
 5254                    .update(cx, |buffer, _| {
 5255                        buffer.wait_for_edits(Some(position.timestamp))
 5256                    })?
 5257                    .await?;
 5258                this.update(cx, |this, cx| {
 5259                    let position = position.to_point_utf16(buffer.read(cx));
 5260                    this.on_type_format(buffer, position, trigger, false, cx)
 5261                })?
 5262                .await
 5263            })
 5264        } else {
 5265            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5266        }
 5267    }
 5268
 5269    pub fn on_type_format<T: ToPointUtf16>(
 5270        &mut self,
 5271        buffer: Entity<Buffer>,
 5272        position: T,
 5273        trigger: String,
 5274        push_to_history: bool,
 5275        cx: &mut Context<Self>,
 5276    ) -> Task<Result<Option<Transaction>>> {
 5277        let position = position.to_point_utf16(buffer.read(cx));
 5278        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5279    }
 5280
 5281    fn on_type_format_impl(
 5282        &mut self,
 5283        buffer: Entity<Buffer>,
 5284        position: PointUtf16,
 5285        trigger: String,
 5286        push_to_history: bool,
 5287        cx: &mut Context<Self>,
 5288    ) -> Task<Result<Option<Transaction>>> {
 5289        let options = buffer.update(cx, |buffer, cx| {
 5290            lsp_command::lsp_formatting_options(
 5291                language_settings(
 5292                    buffer.language_at(position).map(|l| l.name()),
 5293                    buffer.file(),
 5294                    cx,
 5295                )
 5296                .as_ref(),
 5297            )
 5298        });
 5299
 5300        cx.spawn(async move |this, cx| {
 5301            if let Some(waiter) =
 5302                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5303            {
 5304                waiter.await?;
 5305            }
 5306            cx.update(|cx| {
 5307                this.update(cx, |this, cx| {
 5308                    this.request_lsp(
 5309                        buffer.clone(),
 5310                        LanguageServerToQuery::FirstCapable,
 5311                        OnTypeFormatting {
 5312                            position,
 5313                            trigger,
 5314                            options,
 5315                            push_to_history,
 5316                        },
 5317                        cx,
 5318                    )
 5319                })
 5320            })??
 5321            .await
 5322        })
 5323    }
 5324
 5325    pub fn definitions(
 5326        &mut self,
 5327        buffer: &Entity<Buffer>,
 5328        position: PointUtf16,
 5329        cx: &mut Context<Self>,
 5330    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5331        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5332            let request = GetDefinitions { position };
 5333            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5334                return Task::ready(Ok(None));
 5335            }
 5336            let request_task = upstream_client.request_lsp(
 5337                project_id,
 5338                None,
 5339                LSP_REQUEST_TIMEOUT,
 5340                cx.background_executor().clone(),
 5341                request.to_proto(project_id, buffer.read(cx)),
 5342            );
 5343            let buffer = buffer.clone();
 5344            cx.spawn(async move |weak_lsp_store, cx| {
 5345                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5346                    return Ok(None);
 5347                };
 5348                let Some(responses) = request_task.await? else {
 5349                    return Ok(None);
 5350                };
 5351                let actions = join_all(responses.payload.into_iter().map(|response| {
 5352                    GetDefinitions { position }.response_from_proto(
 5353                        response.response,
 5354                        lsp_store.clone(),
 5355                        buffer.clone(),
 5356                        cx.clone(),
 5357                    )
 5358                }))
 5359                .await;
 5360
 5361                Ok(Some(
 5362                    actions
 5363                        .into_iter()
 5364                        .collect::<Result<Vec<Vec<_>>>>()?
 5365                        .into_iter()
 5366                        .flatten()
 5367                        .dedup()
 5368                        .collect(),
 5369                ))
 5370            })
 5371        } else {
 5372            let definitions_task = self.request_multiple_lsp_locally(
 5373                buffer,
 5374                Some(position),
 5375                GetDefinitions { position },
 5376                cx,
 5377            );
 5378            cx.background_spawn(async move {
 5379                Ok(Some(
 5380                    definitions_task
 5381                        .await
 5382                        .into_iter()
 5383                        .flat_map(|(_, definitions)| definitions)
 5384                        .dedup()
 5385                        .collect(),
 5386                ))
 5387            })
 5388        }
 5389    }
 5390
 5391    pub fn declarations(
 5392        &mut self,
 5393        buffer: &Entity<Buffer>,
 5394        position: PointUtf16,
 5395        cx: &mut Context<Self>,
 5396    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5397        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5398            let request = GetDeclarations { position };
 5399            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5400                return Task::ready(Ok(None));
 5401            }
 5402            let request_task = upstream_client.request_lsp(
 5403                project_id,
 5404                None,
 5405                LSP_REQUEST_TIMEOUT,
 5406                cx.background_executor().clone(),
 5407                request.to_proto(project_id, buffer.read(cx)),
 5408            );
 5409            let buffer = buffer.clone();
 5410            cx.spawn(async move |weak_lsp_store, cx| {
 5411                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5412                    return Ok(None);
 5413                };
 5414                let Some(responses) = request_task.await? else {
 5415                    return Ok(None);
 5416                };
 5417                let actions = join_all(responses.payload.into_iter().map(|response| {
 5418                    GetDeclarations { position }.response_from_proto(
 5419                        response.response,
 5420                        lsp_store.clone(),
 5421                        buffer.clone(),
 5422                        cx.clone(),
 5423                    )
 5424                }))
 5425                .await;
 5426
 5427                Ok(Some(
 5428                    actions
 5429                        .into_iter()
 5430                        .collect::<Result<Vec<Vec<_>>>>()?
 5431                        .into_iter()
 5432                        .flatten()
 5433                        .dedup()
 5434                        .collect(),
 5435                ))
 5436            })
 5437        } else {
 5438            let declarations_task = self.request_multiple_lsp_locally(
 5439                buffer,
 5440                Some(position),
 5441                GetDeclarations { position },
 5442                cx,
 5443            );
 5444            cx.background_spawn(async move {
 5445                Ok(Some(
 5446                    declarations_task
 5447                        .await
 5448                        .into_iter()
 5449                        .flat_map(|(_, declarations)| declarations)
 5450                        .dedup()
 5451                        .collect(),
 5452                ))
 5453            })
 5454        }
 5455    }
 5456
 5457    pub fn type_definitions(
 5458        &mut self,
 5459        buffer: &Entity<Buffer>,
 5460        position: PointUtf16,
 5461        cx: &mut Context<Self>,
 5462    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5463        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5464            let request = GetTypeDefinitions { position };
 5465            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5466                return Task::ready(Ok(None));
 5467            }
 5468            let request_task = upstream_client.request_lsp(
 5469                project_id,
 5470                None,
 5471                LSP_REQUEST_TIMEOUT,
 5472                cx.background_executor().clone(),
 5473                request.to_proto(project_id, buffer.read(cx)),
 5474            );
 5475            let buffer = buffer.clone();
 5476            cx.spawn(async move |weak_lsp_store, cx| {
 5477                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5478                    return Ok(None);
 5479                };
 5480                let Some(responses) = request_task.await? else {
 5481                    return Ok(None);
 5482                };
 5483                let actions = join_all(responses.payload.into_iter().map(|response| {
 5484                    GetTypeDefinitions { position }.response_from_proto(
 5485                        response.response,
 5486                        lsp_store.clone(),
 5487                        buffer.clone(),
 5488                        cx.clone(),
 5489                    )
 5490                }))
 5491                .await;
 5492
 5493                Ok(Some(
 5494                    actions
 5495                        .into_iter()
 5496                        .collect::<Result<Vec<Vec<_>>>>()?
 5497                        .into_iter()
 5498                        .flatten()
 5499                        .dedup()
 5500                        .collect(),
 5501                ))
 5502            })
 5503        } else {
 5504            let type_definitions_task = self.request_multiple_lsp_locally(
 5505                buffer,
 5506                Some(position),
 5507                GetTypeDefinitions { position },
 5508                cx,
 5509            );
 5510            cx.background_spawn(async move {
 5511                Ok(Some(
 5512                    type_definitions_task
 5513                        .await
 5514                        .into_iter()
 5515                        .flat_map(|(_, type_definitions)| type_definitions)
 5516                        .dedup()
 5517                        .collect(),
 5518                ))
 5519            })
 5520        }
 5521    }
 5522
 5523    pub fn implementations(
 5524        &mut self,
 5525        buffer: &Entity<Buffer>,
 5526        position: PointUtf16,
 5527        cx: &mut Context<Self>,
 5528    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5529        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5530            let request = GetImplementations { position };
 5531            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5532                return Task::ready(Ok(None));
 5533            }
 5534            let request_task = upstream_client.request_lsp(
 5535                project_id,
 5536                None,
 5537                LSP_REQUEST_TIMEOUT,
 5538                cx.background_executor().clone(),
 5539                request.to_proto(project_id, buffer.read(cx)),
 5540            );
 5541            let buffer = buffer.clone();
 5542            cx.spawn(async move |weak_lsp_store, cx| {
 5543                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5544                    return Ok(None);
 5545                };
 5546                let Some(responses) = request_task.await? else {
 5547                    return Ok(None);
 5548                };
 5549                let actions = join_all(responses.payload.into_iter().map(|response| {
 5550                    GetImplementations { position }.response_from_proto(
 5551                        response.response,
 5552                        lsp_store.clone(),
 5553                        buffer.clone(),
 5554                        cx.clone(),
 5555                    )
 5556                }))
 5557                .await;
 5558
 5559                Ok(Some(
 5560                    actions
 5561                        .into_iter()
 5562                        .collect::<Result<Vec<Vec<_>>>>()?
 5563                        .into_iter()
 5564                        .flatten()
 5565                        .dedup()
 5566                        .collect(),
 5567                ))
 5568            })
 5569        } else {
 5570            let implementations_task = self.request_multiple_lsp_locally(
 5571                buffer,
 5572                Some(position),
 5573                GetImplementations { position },
 5574                cx,
 5575            );
 5576            cx.background_spawn(async move {
 5577                Ok(Some(
 5578                    implementations_task
 5579                        .await
 5580                        .into_iter()
 5581                        .flat_map(|(_, implementations)| implementations)
 5582                        .dedup()
 5583                        .collect(),
 5584                ))
 5585            })
 5586        }
 5587    }
 5588
 5589    pub fn references(
 5590        &mut self,
 5591        buffer: &Entity<Buffer>,
 5592        position: PointUtf16,
 5593        cx: &mut Context<Self>,
 5594    ) -> Task<Result<Option<Vec<Location>>>> {
 5595        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5596            let request = GetReferences { position };
 5597            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5598                return Task::ready(Ok(None));
 5599            }
 5600
 5601            let request_task = upstream_client.request_lsp(
 5602                project_id,
 5603                None,
 5604                LSP_REQUEST_TIMEOUT,
 5605                cx.background_executor().clone(),
 5606                request.to_proto(project_id, buffer.read(cx)),
 5607            );
 5608            let buffer = buffer.clone();
 5609            cx.spawn(async move |weak_lsp_store, cx| {
 5610                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5611                    return Ok(None);
 5612                };
 5613                let Some(responses) = request_task.await? else {
 5614                    return Ok(None);
 5615                };
 5616
 5617                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5618                    GetReferences { position }.response_from_proto(
 5619                        lsp_response.response,
 5620                        lsp_store.clone(),
 5621                        buffer.clone(),
 5622                        cx.clone(),
 5623                    )
 5624                }))
 5625                .await
 5626                .into_iter()
 5627                .collect::<Result<Vec<Vec<_>>>>()?
 5628                .into_iter()
 5629                .flatten()
 5630                .dedup()
 5631                .collect();
 5632                Ok(Some(locations))
 5633            })
 5634        } else {
 5635            let references_task = self.request_multiple_lsp_locally(
 5636                buffer,
 5637                Some(position),
 5638                GetReferences { position },
 5639                cx,
 5640            );
 5641            cx.background_spawn(async move {
 5642                Ok(Some(
 5643                    references_task
 5644                        .await
 5645                        .into_iter()
 5646                        .flat_map(|(_, references)| references)
 5647                        .dedup()
 5648                        .collect(),
 5649                ))
 5650            })
 5651        }
 5652    }
 5653
 5654    pub fn code_actions(
 5655        &mut self,
 5656        buffer: &Entity<Buffer>,
 5657        range: Range<Anchor>,
 5658        kinds: Option<Vec<CodeActionKind>>,
 5659        cx: &mut Context<Self>,
 5660    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5661        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5662            let request = GetCodeActions {
 5663                range: range.clone(),
 5664                kinds: kinds.clone(),
 5665            };
 5666            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5667                return Task::ready(Ok(None));
 5668            }
 5669            let request_task = upstream_client.request_lsp(
 5670                project_id,
 5671                None,
 5672                LSP_REQUEST_TIMEOUT,
 5673                cx.background_executor().clone(),
 5674                request.to_proto(project_id, buffer.read(cx)),
 5675            );
 5676            let buffer = buffer.clone();
 5677            cx.spawn(async move |weak_lsp_store, cx| {
 5678                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5679                    return Ok(None);
 5680                };
 5681                let Some(responses) = request_task.await? else {
 5682                    return Ok(None);
 5683                };
 5684                let actions = join_all(responses.payload.into_iter().map(|response| {
 5685                    GetCodeActions {
 5686                        range: range.clone(),
 5687                        kinds: kinds.clone(),
 5688                    }
 5689                    .response_from_proto(
 5690                        response.response,
 5691                        lsp_store.clone(),
 5692                        buffer.clone(),
 5693                        cx.clone(),
 5694                    )
 5695                }))
 5696                .await;
 5697
 5698                Ok(Some(
 5699                    actions
 5700                        .into_iter()
 5701                        .collect::<Result<Vec<Vec<_>>>>()?
 5702                        .into_iter()
 5703                        .flatten()
 5704                        .collect(),
 5705                ))
 5706            })
 5707        } else {
 5708            let all_actions_task = self.request_multiple_lsp_locally(
 5709                buffer,
 5710                Some(range.start),
 5711                GetCodeActions { range, kinds },
 5712                cx,
 5713            );
 5714            cx.background_spawn(async move {
 5715                Ok(Some(
 5716                    all_actions_task
 5717                        .await
 5718                        .into_iter()
 5719                        .flat_map(|(_, actions)| actions)
 5720                        .collect(),
 5721                ))
 5722            })
 5723        }
 5724    }
 5725
 5726    pub fn code_lens_actions(
 5727        &mut self,
 5728        buffer: &Entity<Buffer>,
 5729        cx: &mut Context<Self>,
 5730    ) -> CodeLensTask {
 5731        let version_queried_for = buffer.read(cx).version();
 5732        let buffer_id = buffer.read(cx).remote_id();
 5733        let existing_servers = self.as_local().map(|local| {
 5734            local
 5735                .buffers_opened_in_servers
 5736                .get(&buffer_id)
 5737                .cloned()
 5738                .unwrap_or_default()
 5739        });
 5740
 5741        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 5742            if let Some(cached_lens) = &lsp_data.code_lens {
 5743                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 5744                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 5745                        existing_servers != cached_lens.lens.keys().copied().collect()
 5746                    });
 5747                    if !has_different_servers {
 5748                        return Task::ready(Ok(Some(
 5749                            cached_lens.lens.values().flatten().cloned().collect(),
 5750                        )))
 5751                        .shared();
 5752                    }
 5753                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 5754                    if !version_queried_for.changed_since(updating_for) {
 5755                        return running_update.clone();
 5756                    }
 5757                }
 5758            }
 5759        }
 5760
 5761        let lens_lsp_data = self
 5762            .latest_lsp_data(buffer, cx)
 5763            .code_lens
 5764            .get_or_insert_default();
 5765        let buffer = buffer.clone();
 5766        let query_version_queried_for = version_queried_for.clone();
 5767        let new_task = cx
 5768            .spawn(async move |lsp_store, cx| {
 5769                cx.background_executor()
 5770                    .timer(Duration::from_millis(30))
 5771                    .await;
 5772                let fetched_lens = lsp_store
 5773                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 5774                    .map_err(Arc::new)?
 5775                    .await
 5776                    .context("fetching code lens")
 5777                    .map_err(Arc::new);
 5778                let fetched_lens = match fetched_lens {
 5779                    Ok(fetched_lens) => fetched_lens,
 5780                    Err(e) => {
 5781                        lsp_store
 5782                            .update(cx, |lsp_store, _| {
 5783                                if let Some(lens_lsp_data) = lsp_store
 5784                                    .lsp_data
 5785                                    .get_mut(&buffer_id)
 5786                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 5787                                {
 5788                                    lens_lsp_data.update = None;
 5789                                }
 5790                            })
 5791                            .ok();
 5792                        return Err(e);
 5793                    }
 5794                };
 5795
 5796                lsp_store
 5797                    .update(cx, |lsp_store, _| {
 5798                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 5799                        let code_lens = lsp_data.code_lens.as_mut()?;
 5800                        if let Some(fetched_lens) = fetched_lens {
 5801                            if lsp_data.buffer_version == query_version_queried_for {
 5802                                code_lens.lens.extend(fetched_lens);
 5803                            } else if !lsp_data
 5804                                .buffer_version
 5805                                .changed_since(&query_version_queried_for)
 5806                            {
 5807                                lsp_data.buffer_version = query_version_queried_for;
 5808                                code_lens.lens = fetched_lens;
 5809                            }
 5810                        }
 5811                        code_lens.update = None;
 5812                        Some(code_lens.lens.values().flatten().cloned().collect())
 5813                    })
 5814                    .map_err(Arc::new)
 5815            })
 5816            .shared();
 5817        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 5818        new_task
 5819    }
 5820
 5821    fn fetch_code_lens(
 5822        &mut self,
 5823        buffer: &Entity<Buffer>,
 5824        cx: &mut Context<Self>,
 5825    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 5826        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5827            let request = GetCodeLens;
 5828            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5829                return Task::ready(Ok(None));
 5830            }
 5831            let request_task = upstream_client.request_lsp(
 5832                project_id,
 5833                None,
 5834                LSP_REQUEST_TIMEOUT,
 5835                cx.background_executor().clone(),
 5836                request.to_proto(project_id, buffer.read(cx)),
 5837            );
 5838            let buffer = buffer.clone();
 5839            cx.spawn(async move |weak_lsp_store, cx| {
 5840                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5841                    return Ok(None);
 5842                };
 5843                let Some(responses) = request_task.await? else {
 5844                    return Ok(None);
 5845                };
 5846
 5847                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 5848                    let lsp_store = lsp_store.clone();
 5849                    let buffer = buffer.clone();
 5850                    let cx = cx.clone();
 5851                    async move {
 5852                        (
 5853                            LanguageServerId::from_proto(response.server_id),
 5854                            GetCodeLens
 5855                                .response_from_proto(response.response, lsp_store, buffer, cx)
 5856                                .await,
 5857                        )
 5858                    }
 5859                }))
 5860                .await;
 5861
 5862                let mut has_errors = false;
 5863                let code_lens_actions = code_lens_actions
 5864                    .into_iter()
 5865                    .filter_map(|(server_id, code_lens)| match code_lens {
 5866                        Ok(code_lens) => Some((server_id, code_lens)),
 5867                        Err(e) => {
 5868                            has_errors = true;
 5869                            log::error!("{e:#}");
 5870                            None
 5871                        }
 5872                    })
 5873                    .collect::<HashMap<_, _>>();
 5874                anyhow::ensure!(
 5875                    !has_errors || !code_lens_actions.is_empty(),
 5876                    "Failed to fetch code lens"
 5877                );
 5878                Ok(Some(code_lens_actions))
 5879            })
 5880        } else {
 5881            let code_lens_actions_task =
 5882                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 5883            cx.background_spawn(async move {
 5884                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 5885            })
 5886        }
 5887    }
 5888
 5889    #[inline(never)]
 5890    pub fn completions(
 5891        &self,
 5892        buffer: &Entity<Buffer>,
 5893        position: PointUtf16,
 5894        context: CompletionContext,
 5895        cx: &mut Context<Self>,
 5896    ) -> Task<Result<Vec<CompletionResponse>>> {
 5897        let language_registry = self.languages.clone();
 5898
 5899        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5900            let request = GetCompletions { position, context };
 5901            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5902                return Task::ready(Ok(Vec::new()));
 5903            }
 5904            let task = self.send_lsp_proto_request(
 5905                buffer.clone(),
 5906                upstream_client,
 5907                project_id,
 5908                request,
 5909                cx,
 5910            );
 5911            let language = buffer.read(cx).language().cloned();
 5912
 5913            // In the future, we should provide project guests with the names of LSP adapters,
 5914            // so that they can use the correct LSP adapter when computing labels. For now,
 5915            // guests just use the first LSP adapter associated with the buffer's language.
 5916            let lsp_adapter = language.as_ref().and_then(|language| {
 5917                language_registry
 5918                    .lsp_adapters(&language.name())
 5919                    .first()
 5920                    .cloned()
 5921            });
 5922
 5923            cx.foreground_executor().spawn(async move {
 5924                let completion_response = task.await?;
 5925                let completions = populate_labels_for_completions(
 5926                    completion_response.completions,
 5927                    language,
 5928                    lsp_adapter,
 5929                )
 5930                .await;
 5931                Ok(vec![CompletionResponse {
 5932                    completions,
 5933                    display_options: CompletionDisplayOptions::default(),
 5934                    is_incomplete: completion_response.is_incomplete,
 5935                }])
 5936            })
 5937        } else if let Some(local) = self.as_local() {
 5938            let snapshot = buffer.read(cx).snapshot();
 5939            let offset = position.to_offset(&snapshot);
 5940            let scope = snapshot.language_scope_at(offset);
 5941            let language = snapshot.language().cloned();
 5942            let completion_settings = language_settings(
 5943                language.as_ref().map(|language| language.name()),
 5944                buffer.read(cx).file(),
 5945                cx,
 5946            )
 5947            .completions
 5948            .clone();
 5949            if !completion_settings.lsp {
 5950                return Task::ready(Ok(Vec::new()));
 5951            }
 5952
 5953            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 5954                local
 5955                    .language_servers_for_buffer(buffer, cx)
 5956                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 5957                    .filter(|(adapter, _)| {
 5958                        scope
 5959                            .as_ref()
 5960                            .map(|scope| scope.language_allowed(&adapter.name))
 5961                            .unwrap_or(true)
 5962                    })
 5963                    .map(|(_, server)| server.server_id())
 5964                    .collect()
 5965            });
 5966
 5967            let buffer = buffer.clone();
 5968            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 5969            let lsp_timeout = if lsp_timeout > 0 {
 5970                Some(Duration::from_millis(lsp_timeout))
 5971            } else {
 5972                None
 5973            };
 5974            cx.spawn(async move |this,  cx| {
 5975                let mut tasks = Vec::with_capacity(server_ids.len());
 5976                this.update(cx, |lsp_store, cx| {
 5977                    for server_id in server_ids {
 5978                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 5979                        let lsp_timeout = lsp_timeout
 5980                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 5981                        let mut timeout = cx.background_spawn(async move {
 5982                            match lsp_timeout {
 5983                                Some(lsp_timeout) => {
 5984                                    lsp_timeout.await;
 5985                                    true
 5986                                },
 5987                                None => false,
 5988                            }
 5989                        }).fuse();
 5990                        let mut lsp_request = lsp_store.request_lsp(
 5991                            buffer.clone(),
 5992                            LanguageServerToQuery::Other(server_id),
 5993                            GetCompletions {
 5994                                position,
 5995                                context: context.clone(),
 5996                            },
 5997                            cx,
 5998                        ).fuse();
 5999                        let new_task = cx.background_spawn(async move {
 6000                            select_biased! {
 6001                                response = lsp_request => anyhow::Ok(Some(response?)),
 6002                                timeout_happened = timeout => {
 6003                                    if timeout_happened {
 6004                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6005                                        Ok(None)
 6006                                    } else {
 6007                                        let completions = lsp_request.await?;
 6008                                        Ok(Some(completions))
 6009                                    }
 6010                                },
 6011                            }
 6012                        });
 6013                        tasks.push((lsp_adapter, new_task));
 6014                    }
 6015                })?;
 6016
 6017                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6018                    let completion_response = task.await.ok()??;
 6019                    let completions = populate_labels_for_completions(
 6020                            completion_response.completions,
 6021                            language.clone(),
 6022                            lsp_adapter,
 6023                        )
 6024                        .await;
 6025                    Some(CompletionResponse {
 6026                        completions,
 6027                        display_options: CompletionDisplayOptions::default(),
 6028                        is_incomplete: completion_response.is_incomplete,
 6029                    })
 6030                });
 6031
 6032                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6033
 6034                Ok(responses.into_iter().flatten().collect())
 6035            })
 6036        } else {
 6037            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6038        }
 6039    }
 6040
 6041    pub fn resolve_completions(
 6042        &self,
 6043        buffer: Entity<Buffer>,
 6044        completion_indices: Vec<usize>,
 6045        completions: Rc<RefCell<Box<[Completion]>>>,
 6046        cx: &mut Context<Self>,
 6047    ) -> Task<Result<bool>> {
 6048        let client = self.upstream_client();
 6049        let buffer_id = buffer.read(cx).remote_id();
 6050        let buffer_snapshot = buffer.read(cx).snapshot();
 6051
 6052        if !self.check_if_capable_for_proto_request(
 6053            &buffer,
 6054            GetCompletions::can_resolve_completions,
 6055            cx,
 6056        ) {
 6057            return Task::ready(Ok(false));
 6058        }
 6059        cx.spawn(async move |lsp_store, cx| {
 6060            let mut did_resolve = false;
 6061            if let Some((client, project_id)) = client {
 6062                for completion_index in completion_indices {
 6063                    let server_id = {
 6064                        let completion = &completions.borrow()[completion_index];
 6065                        completion.source.server_id()
 6066                    };
 6067                    if let Some(server_id) = server_id {
 6068                        if Self::resolve_completion_remote(
 6069                            project_id,
 6070                            server_id,
 6071                            buffer_id,
 6072                            completions.clone(),
 6073                            completion_index,
 6074                            client.clone(),
 6075                        )
 6076                        .await
 6077                        .log_err()
 6078                        .is_some()
 6079                        {
 6080                            did_resolve = true;
 6081                        }
 6082                    } else {
 6083                        resolve_word_completion(
 6084                            &buffer_snapshot,
 6085                            &mut completions.borrow_mut()[completion_index],
 6086                        );
 6087                    }
 6088                }
 6089            } else {
 6090                for completion_index in completion_indices {
 6091                    let server_id = {
 6092                        let completion = &completions.borrow()[completion_index];
 6093                        completion.source.server_id()
 6094                    };
 6095                    if let Some(server_id) = server_id {
 6096                        let server_and_adapter = lsp_store
 6097                            .read_with(cx, |lsp_store, _| {
 6098                                let server = lsp_store.language_server_for_id(server_id)?;
 6099                                let adapter =
 6100                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6101                                Some((server, adapter))
 6102                            })
 6103                            .ok()
 6104                            .flatten();
 6105                        let Some((server, adapter)) = server_and_adapter else {
 6106                            continue;
 6107                        };
 6108
 6109                        let resolved = Self::resolve_completion_local(
 6110                            server,
 6111                            completions.clone(),
 6112                            completion_index,
 6113                        )
 6114                        .await
 6115                        .log_err()
 6116                        .is_some();
 6117                        if resolved {
 6118                            Self::regenerate_completion_labels(
 6119                                adapter,
 6120                                &buffer_snapshot,
 6121                                completions.clone(),
 6122                                completion_index,
 6123                            )
 6124                            .await
 6125                            .log_err();
 6126                            did_resolve = true;
 6127                        }
 6128                    } else {
 6129                        resolve_word_completion(
 6130                            &buffer_snapshot,
 6131                            &mut completions.borrow_mut()[completion_index],
 6132                        );
 6133                    }
 6134                }
 6135            }
 6136
 6137            Ok(did_resolve)
 6138        })
 6139    }
 6140
 6141    async fn resolve_completion_local(
 6142        server: Arc<lsp::LanguageServer>,
 6143        completions: Rc<RefCell<Box<[Completion]>>>,
 6144        completion_index: usize,
 6145    ) -> Result<()> {
 6146        let server_id = server.server_id();
 6147        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6148            return Ok(());
 6149        }
 6150
 6151        let request = {
 6152            let completion = &completions.borrow()[completion_index];
 6153            match &completion.source {
 6154                CompletionSource::Lsp {
 6155                    lsp_completion,
 6156                    resolved,
 6157                    server_id: completion_server_id,
 6158                    ..
 6159                } => {
 6160                    if *resolved {
 6161                        return Ok(());
 6162                    }
 6163                    anyhow::ensure!(
 6164                        server_id == *completion_server_id,
 6165                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6166                    );
 6167                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6168                }
 6169                CompletionSource::BufferWord { .. }
 6170                | CompletionSource::Dap { .. }
 6171                | CompletionSource::Custom => {
 6172                    return Ok(());
 6173                }
 6174            }
 6175        };
 6176        let resolved_completion = request
 6177            .await
 6178            .into_response()
 6179            .context("resolve completion")?;
 6180
 6181        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6182        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6183
 6184        let mut completions = completions.borrow_mut();
 6185        let completion = &mut completions[completion_index];
 6186        if let CompletionSource::Lsp {
 6187            lsp_completion,
 6188            resolved,
 6189            server_id: completion_server_id,
 6190            ..
 6191        } = &mut completion.source
 6192        {
 6193            if *resolved {
 6194                return Ok(());
 6195            }
 6196            anyhow::ensure!(
 6197                server_id == *completion_server_id,
 6198                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6199            );
 6200            *lsp_completion = Box::new(resolved_completion);
 6201            *resolved = true;
 6202        }
 6203        Ok(())
 6204    }
 6205
 6206    async fn regenerate_completion_labels(
 6207        adapter: Arc<CachedLspAdapter>,
 6208        snapshot: &BufferSnapshot,
 6209        completions: Rc<RefCell<Box<[Completion]>>>,
 6210        completion_index: usize,
 6211    ) -> Result<()> {
 6212        let completion_item = completions.borrow()[completion_index]
 6213            .source
 6214            .lsp_completion(true)
 6215            .map(Cow::into_owned);
 6216        if let Some(lsp_documentation) = completion_item
 6217            .as_ref()
 6218            .and_then(|completion_item| completion_item.documentation.clone())
 6219        {
 6220            let mut completions = completions.borrow_mut();
 6221            let completion = &mut completions[completion_index];
 6222            completion.documentation = Some(lsp_documentation.into());
 6223        } else {
 6224            let mut completions = completions.borrow_mut();
 6225            let completion = &mut completions[completion_index];
 6226            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6227        }
 6228
 6229        let mut new_label = match completion_item {
 6230            Some(completion_item) => {
 6231                // 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
 6232                // So we have to update the label here anyway...
 6233                let language = snapshot.language();
 6234                match language {
 6235                    Some(language) => {
 6236                        adapter
 6237                            .labels_for_completions(
 6238                                std::slice::from_ref(&completion_item),
 6239                                language,
 6240                            )
 6241                            .await?
 6242                    }
 6243                    None => Vec::new(),
 6244                }
 6245                .pop()
 6246                .flatten()
 6247                .unwrap_or_else(|| {
 6248                    CodeLabel::fallback_for_completion(
 6249                        &completion_item,
 6250                        language.map(|language| language.as_ref()),
 6251                    )
 6252                })
 6253            }
 6254            None => CodeLabel::plain(
 6255                completions.borrow()[completion_index].new_text.clone(),
 6256                None,
 6257            ),
 6258        };
 6259        ensure_uniform_list_compatible_label(&mut new_label);
 6260
 6261        let mut completions = completions.borrow_mut();
 6262        let completion = &mut completions[completion_index];
 6263        if completion.label.filter_text() == new_label.filter_text() {
 6264            completion.label = new_label;
 6265        } else {
 6266            log::error!(
 6267                "Resolved completion changed display label from {} to {}. \
 6268                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6269                completion.label.text(),
 6270                new_label.text(),
 6271                completion.label.filter_text(),
 6272                new_label.filter_text()
 6273            );
 6274        }
 6275
 6276        Ok(())
 6277    }
 6278
 6279    async fn resolve_completion_remote(
 6280        project_id: u64,
 6281        server_id: LanguageServerId,
 6282        buffer_id: BufferId,
 6283        completions: Rc<RefCell<Box<[Completion]>>>,
 6284        completion_index: usize,
 6285        client: AnyProtoClient,
 6286    ) -> Result<()> {
 6287        let lsp_completion = {
 6288            let completion = &completions.borrow()[completion_index];
 6289            match &completion.source {
 6290                CompletionSource::Lsp {
 6291                    lsp_completion,
 6292                    resolved,
 6293                    server_id: completion_server_id,
 6294                    ..
 6295                } => {
 6296                    anyhow::ensure!(
 6297                        server_id == *completion_server_id,
 6298                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6299                    );
 6300                    if *resolved {
 6301                        return Ok(());
 6302                    }
 6303                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6304                }
 6305                CompletionSource::Custom
 6306                | CompletionSource::Dap { .. }
 6307                | CompletionSource::BufferWord { .. } => {
 6308                    return Ok(());
 6309                }
 6310            }
 6311        };
 6312        let request = proto::ResolveCompletionDocumentation {
 6313            project_id,
 6314            language_server_id: server_id.0 as u64,
 6315            lsp_completion,
 6316            buffer_id: buffer_id.into(),
 6317        };
 6318
 6319        let response = client
 6320            .request(request)
 6321            .await
 6322            .context("completion documentation resolve proto request")?;
 6323        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6324
 6325        let documentation = if response.documentation.is_empty() {
 6326            CompletionDocumentation::Undocumented
 6327        } else if response.documentation_is_markdown {
 6328            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6329        } else if response.documentation.lines().count() <= 1 {
 6330            CompletionDocumentation::SingleLine(response.documentation.into())
 6331        } else {
 6332            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6333        };
 6334
 6335        let mut completions = completions.borrow_mut();
 6336        let completion = &mut completions[completion_index];
 6337        completion.documentation = Some(documentation);
 6338        if let CompletionSource::Lsp {
 6339            insert_range,
 6340            lsp_completion,
 6341            resolved,
 6342            server_id: completion_server_id,
 6343            lsp_defaults: _,
 6344        } = &mut completion.source
 6345        {
 6346            let completion_insert_range = response
 6347                .old_insert_start
 6348                .and_then(deserialize_anchor)
 6349                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6350            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6351
 6352            if *resolved {
 6353                return Ok(());
 6354            }
 6355            anyhow::ensure!(
 6356                server_id == *completion_server_id,
 6357                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6358            );
 6359            *lsp_completion = Box::new(resolved_lsp_completion);
 6360            *resolved = true;
 6361        }
 6362
 6363        let replace_range = response
 6364            .old_replace_start
 6365            .and_then(deserialize_anchor)
 6366            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6367        if let Some((old_replace_start, old_replace_end)) = replace_range
 6368            && !response.new_text.is_empty()
 6369        {
 6370            completion.new_text = response.new_text;
 6371            completion.replace_range = old_replace_start..old_replace_end;
 6372        }
 6373
 6374        Ok(())
 6375    }
 6376
 6377    pub fn apply_additional_edits_for_completion(
 6378        &self,
 6379        buffer_handle: Entity<Buffer>,
 6380        completions: Rc<RefCell<Box<[Completion]>>>,
 6381        completion_index: usize,
 6382        push_to_history: bool,
 6383        cx: &mut Context<Self>,
 6384    ) -> Task<Result<Option<Transaction>>> {
 6385        if let Some((client, project_id)) = self.upstream_client() {
 6386            let buffer = buffer_handle.read(cx);
 6387            let buffer_id = buffer.remote_id();
 6388            cx.spawn(async move |_, cx| {
 6389                let request = {
 6390                    let completion = completions.borrow()[completion_index].clone();
 6391                    proto::ApplyCompletionAdditionalEdits {
 6392                        project_id,
 6393                        buffer_id: buffer_id.into(),
 6394                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6395                            replace_range: completion.replace_range,
 6396                            new_text: completion.new_text,
 6397                            source: completion.source,
 6398                        })),
 6399                    }
 6400                };
 6401
 6402                if let Some(transaction) = client.request(request).await?.transaction {
 6403                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6404                    buffer_handle
 6405                        .update(cx, |buffer, _| {
 6406                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6407                        })?
 6408                        .await?;
 6409                    if push_to_history {
 6410                        buffer_handle.update(cx, |buffer, _| {
 6411                            buffer.push_transaction(transaction.clone(), Instant::now());
 6412                            buffer.finalize_last_transaction();
 6413                        })?;
 6414                    }
 6415                    Ok(Some(transaction))
 6416                } else {
 6417                    Ok(None)
 6418                }
 6419            })
 6420        } else {
 6421            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6422                let completion = &completions.borrow()[completion_index];
 6423                let server_id = completion.source.server_id()?;
 6424                Some(
 6425                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6426                        .1
 6427                        .clone(),
 6428                )
 6429            }) else {
 6430                return Task::ready(Ok(None));
 6431            };
 6432
 6433            cx.spawn(async move |this, cx| {
 6434                Self::resolve_completion_local(
 6435                    server.clone(),
 6436                    completions.clone(),
 6437                    completion_index,
 6438                )
 6439                .await
 6440                .context("resolving completion")?;
 6441                let completion = completions.borrow()[completion_index].clone();
 6442                let additional_text_edits = completion
 6443                    .source
 6444                    .lsp_completion(true)
 6445                    .as_ref()
 6446                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6447                if let Some(edits) = additional_text_edits {
 6448                    let edits = this
 6449                        .update(cx, |this, cx| {
 6450                            this.as_local_mut().unwrap().edits_from_lsp(
 6451                                &buffer_handle,
 6452                                edits,
 6453                                server.server_id(),
 6454                                None,
 6455                                cx,
 6456                            )
 6457                        })?
 6458                        .await?;
 6459
 6460                    buffer_handle.update(cx, |buffer, cx| {
 6461                        buffer.finalize_last_transaction();
 6462                        buffer.start_transaction();
 6463
 6464                        for (range, text) in edits {
 6465                            let primary = &completion.replace_range;
 6466
 6467                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6468                            // and the primary completion is just an insertion (empty range), then this is likely
 6469                            // an auto-import scenario and should not be considered overlapping
 6470                            // https://github.com/zed-industries/zed/issues/26136
 6471                            let is_file_start_auto_import = {
 6472                                let snapshot = buffer.snapshot();
 6473                                let primary_start_point = primary.start.to_point(&snapshot);
 6474                                let range_start_point = range.start.to_point(&snapshot);
 6475
 6476                                let result = primary_start_point.row == 0
 6477                                    && primary_start_point.column == 0
 6478                                    && range_start_point.row == 0
 6479                                    && range_start_point.column == 0;
 6480
 6481                                result
 6482                            };
 6483
 6484                            let has_overlap = if is_file_start_auto_import {
 6485                                false
 6486                            } else {
 6487                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6488                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6489                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6490                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6491                                let result = start_within || end_within;
 6492                                result
 6493                            };
 6494
 6495                            //Skip additional edits which overlap with the primary completion edit
 6496                            //https://github.com/zed-industries/zed/pull/1871
 6497                            if !has_overlap {
 6498                                buffer.edit([(range, text)], None, cx);
 6499                            }
 6500                        }
 6501
 6502                        let transaction = if buffer.end_transaction(cx).is_some() {
 6503                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6504                            if !push_to_history {
 6505                                buffer.forget_transaction(transaction.id);
 6506                            }
 6507                            Some(transaction)
 6508                        } else {
 6509                            None
 6510                        };
 6511                        Ok(transaction)
 6512                    })?
 6513                } else {
 6514                    Ok(None)
 6515                }
 6516            })
 6517        }
 6518    }
 6519
 6520    pub fn pull_diagnostics(
 6521        &mut self,
 6522        buffer: Entity<Buffer>,
 6523        cx: &mut Context<Self>,
 6524    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6525        let buffer_id = buffer.read(cx).remote_id();
 6526
 6527        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6528            let mut suitable_capabilities = None;
 6529            // Are we capable for proto request?
 6530            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6531                &buffer,
 6532                |capabilities| {
 6533                    if let Some(caps) = &capabilities.diagnostic_provider {
 6534                        suitable_capabilities = Some(caps.clone());
 6535                        true
 6536                    } else {
 6537                        false
 6538                    }
 6539                },
 6540                cx,
 6541            );
 6542            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6543            let Some(dynamic_caps) = suitable_capabilities else {
 6544                return Task::ready(Ok(None));
 6545            };
 6546            assert!(any_server_has_diagnostics_provider);
 6547
 6548            let request = GetDocumentDiagnostics {
 6549                previous_result_id: None,
 6550                dynamic_caps,
 6551            };
 6552            let request_task = client.request_lsp(
 6553                upstream_project_id,
 6554                None,
 6555                LSP_REQUEST_TIMEOUT,
 6556                cx.background_executor().clone(),
 6557                request.to_proto(upstream_project_id, buffer.read(cx)),
 6558            );
 6559            cx.background_spawn(async move {
 6560                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6561                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6562                // Do not attempt to further process the dummy responses here.
 6563                let _response = request_task.await?;
 6564                Ok(None)
 6565            })
 6566        } else {
 6567            let servers = buffer.update(cx, |buffer, cx| {
 6568                self.language_servers_for_local_buffer(buffer, cx)
 6569                    .map(|(_, server)| server.clone())
 6570                    .collect::<Vec<_>>()
 6571            });
 6572
 6573            let pull_diagnostics = servers
 6574                .into_iter()
 6575                .flat_map(|server| {
 6576                    let result = maybe!({
 6577                        let local = self.as_local()?;
 6578                        let server_id = server.server_id();
 6579                        let providers_with_identifiers = local
 6580                            .language_server_dynamic_registrations
 6581                            .get(&server_id)
 6582                            .into_iter()
 6583                            .flat_map(|registrations| registrations.diagnostics.values().cloned())
 6584                            .collect::<Vec<_>>();
 6585                        Some(
 6586                            providers_with_identifiers
 6587                                .into_iter()
 6588                                .map(|dynamic_caps| {
 6589                                    let result_id = self.result_id(server_id, buffer_id, cx);
 6590                                    self.request_lsp(
 6591                                        buffer.clone(),
 6592                                        LanguageServerToQuery::Other(server_id),
 6593                                        GetDocumentDiagnostics {
 6594                                            previous_result_id: result_id,
 6595                                            dynamic_caps,
 6596                                        },
 6597                                        cx,
 6598                                    )
 6599                                })
 6600                                .collect::<Vec<_>>(),
 6601                        )
 6602                    });
 6603
 6604                    result.unwrap_or_default()
 6605                })
 6606                .collect::<Vec<_>>();
 6607
 6608            cx.background_spawn(async move {
 6609                let mut responses = Vec::new();
 6610                for diagnostics in join_all(pull_diagnostics).await {
 6611                    responses.extend(diagnostics?);
 6612                }
 6613                Ok(Some(responses))
 6614            })
 6615        }
 6616    }
 6617
 6618    pub fn applicable_inlay_chunks(
 6619        &mut self,
 6620        buffer: &Entity<Buffer>,
 6621        ranges: &[Range<text::Anchor>],
 6622        cx: &mut Context<Self>,
 6623    ) -> Vec<Range<BufferRow>> {
 6624        self.latest_lsp_data(buffer, cx)
 6625            .inlay_hints
 6626            .applicable_chunks(ranges)
 6627            .map(|chunk| chunk.start..chunk.end)
 6628            .collect()
 6629    }
 6630
 6631    pub fn invalidate_inlay_hints<'a>(
 6632        &'a mut self,
 6633        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6634    ) {
 6635        for buffer_id in for_buffers {
 6636            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6637                lsp_data.inlay_hints.clear();
 6638            }
 6639        }
 6640    }
 6641
 6642    pub fn inlay_hints(
 6643        &mut self,
 6644        invalidate: InvalidationStrategy,
 6645        buffer: Entity<Buffer>,
 6646        ranges: Vec<Range<text::Anchor>>,
 6647        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6648        cx: &mut Context<Self>,
 6649    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6650        let buffer_snapshot = buffer.read(cx).snapshot();
 6651        let next_hint_id = self.next_hint_id.clone();
 6652        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6653        let query_version = lsp_data.buffer_version.clone();
 6654        let mut lsp_refresh_requested = false;
 6655        let for_server = if let InvalidationStrategy::RefreshRequested {
 6656            server_id,
 6657            request_id,
 6658        } = invalidate
 6659        {
 6660            let invalidated = lsp_data
 6661                .inlay_hints
 6662                .invalidate_for_server_refresh(server_id, request_id);
 6663            lsp_refresh_requested = invalidated;
 6664            Some(server_id)
 6665        } else {
 6666            None
 6667        };
 6668        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6669        let known_chunks = known_chunks
 6670            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6671            .map(|(_, known_chunks)| known_chunks)
 6672            .unwrap_or_default();
 6673
 6674        let mut hint_fetch_tasks = Vec::new();
 6675        let mut cached_inlay_hints = None;
 6676        let mut ranges_to_query = None;
 6677        let applicable_chunks = existing_inlay_hints
 6678            .applicable_chunks(ranges.as_slice())
 6679            .filter(|chunk| !known_chunks.contains(&(chunk.start..chunk.end)))
 6680            .collect::<Vec<_>>();
 6681        if applicable_chunks.is_empty() {
 6682            return HashMap::default();
 6683        }
 6684
 6685        let last_chunk_number = existing_inlay_hints.buffer_chunks_len() - 1;
 6686
 6687        for row_chunk in applicable_chunks {
 6688            match (
 6689                existing_inlay_hints
 6690                    .cached_hints(&row_chunk)
 6691                    .filter(|_| !lsp_refresh_requested)
 6692                    .cloned(),
 6693                existing_inlay_hints
 6694                    .fetched_hints(&row_chunk)
 6695                    .as_ref()
 6696                    .filter(|_| !lsp_refresh_requested)
 6697                    .cloned(),
 6698            ) {
 6699                (None, None) => {
 6700                    let end = if last_chunk_number == row_chunk.id {
 6701                        Point::new(row_chunk.end, buffer_snapshot.line_len(row_chunk.end))
 6702                    } else {
 6703                        Point::new(row_chunk.end, 0)
 6704                    };
 6705                    ranges_to_query.get_or_insert_with(Vec::new).push((
 6706                        row_chunk,
 6707                        buffer_snapshot.anchor_before(Point::new(row_chunk.start, 0))
 6708                            ..buffer_snapshot.anchor_after(end),
 6709                    ));
 6710                }
 6711                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 6712                (Some(cached_hints), None) => {
 6713                    for (server_id, cached_hints) in cached_hints {
 6714                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6715                            cached_inlay_hints
 6716                                .get_or_insert_with(HashMap::default)
 6717                                .entry(row_chunk.start..row_chunk.end)
 6718                                .or_insert_with(HashMap::default)
 6719                                .entry(server_id)
 6720                                .or_insert_with(Vec::new)
 6721                                .extend(cached_hints);
 6722                        }
 6723                    }
 6724                }
 6725                (Some(cached_hints), Some(fetched_hints)) => {
 6726                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 6727                    for (server_id, cached_hints) in cached_hints {
 6728                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6729                            cached_inlay_hints
 6730                                .get_or_insert_with(HashMap::default)
 6731                                .entry(row_chunk.start..row_chunk.end)
 6732                                .or_insert_with(HashMap::default)
 6733                                .entry(server_id)
 6734                                .or_insert_with(Vec::new)
 6735                                .extend(cached_hints);
 6736                        }
 6737                    }
 6738                }
 6739            }
 6740        }
 6741
 6742        if hint_fetch_tasks.is_empty()
 6743            && ranges_to_query
 6744                .as_ref()
 6745                .is_none_or(|ranges| ranges.is_empty())
 6746            && let Some(cached_inlay_hints) = cached_inlay_hints
 6747        {
 6748            cached_inlay_hints
 6749                .into_iter()
 6750                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 6751                .collect()
 6752        } else {
 6753            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 6754                let next_hint_id = next_hint_id.clone();
 6755                let buffer = buffer.clone();
 6756                let query_version = query_version.clone();
 6757                let new_inlay_hints = cx
 6758                    .spawn(async move |lsp_store, cx| {
 6759                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 6760                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 6761                        })?;
 6762                        new_fetch_task
 6763                            .await
 6764                            .and_then(|new_hints_by_server| {
 6765                                lsp_store.update(cx, |lsp_store, cx| {
 6766                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 6767                                    let update_cache = lsp_data.buffer_version == query_version;
 6768                                    if new_hints_by_server.is_empty() {
 6769                                        if update_cache {
 6770                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 6771                                        }
 6772                                        HashMap::default()
 6773                                    } else {
 6774                                        new_hints_by_server
 6775                                            .into_iter()
 6776                                            .map(|(server_id, new_hints)| {
 6777                                                let new_hints = new_hints
 6778                                                    .into_iter()
 6779                                                    .map(|new_hint| {
 6780                                                        (
 6781                                                            InlayId::Hint(next_hint_id.fetch_add(
 6782                                                                1,
 6783                                                                atomic::Ordering::AcqRel,
 6784                                                            )),
 6785                                                            new_hint,
 6786                                                        )
 6787                                                    })
 6788                                                    .collect::<Vec<_>>();
 6789                                                if update_cache {
 6790                                                    lsp_data.inlay_hints.insert_new_hints(
 6791                                                        chunk,
 6792                                                        server_id,
 6793                                                        new_hints.clone(),
 6794                                                    );
 6795                                                }
 6796                                                (server_id, new_hints)
 6797                                            })
 6798                                            .collect()
 6799                                    }
 6800                                })
 6801                            })
 6802                            .map_err(Arc::new)
 6803                    })
 6804                    .shared();
 6805
 6806                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 6807                *fetch_task = Some(new_inlay_hints.clone());
 6808                hint_fetch_tasks.push((chunk, new_inlay_hints));
 6809            }
 6810
 6811            cached_inlay_hints
 6812                .unwrap_or_default()
 6813                .into_iter()
 6814                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 6815                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 6816                    (
 6817                        chunk.start..chunk.end,
 6818                        cx.spawn(async move |_, _| {
 6819                            hints_fetch.await.map_err(|e| {
 6820                                if e.error_code() != ErrorCode::Internal {
 6821                                    anyhow!(e.error_code())
 6822                                } else {
 6823                                    anyhow!("{e:#}")
 6824                                }
 6825                            })
 6826                        }),
 6827                    )
 6828                }))
 6829                .collect()
 6830        }
 6831    }
 6832
 6833    fn fetch_inlay_hints(
 6834        &mut self,
 6835        for_server: Option<LanguageServerId>,
 6836        buffer: &Entity<Buffer>,
 6837        range: Range<Anchor>,
 6838        cx: &mut Context<Self>,
 6839    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 6840        let request = InlayHints {
 6841            range: range.clone(),
 6842        };
 6843        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6844            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6845                return Task::ready(Ok(HashMap::default()));
 6846            }
 6847            let request_task = upstream_client.request_lsp(
 6848                project_id,
 6849                for_server.map(|id| id.to_proto()),
 6850                LSP_REQUEST_TIMEOUT,
 6851                cx.background_executor().clone(),
 6852                request.to_proto(project_id, buffer.read(cx)),
 6853            );
 6854            let buffer = buffer.clone();
 6855            cx.spawn(async move |weak_lsp_store, cx| {
 6856                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6857                    return Ok(HashMap::default());
 6858                };
 6859                let Some(responses) = request_task.await? else {
 6860                    return Ok(HashMap::default());
 6861                };
 6862
 6863                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 6864                    let lsp_store = lsp_store.clone();
 6865                    let buffer = buffer.clone();
 6866                    let cx = cx.clone();
 6867                    let request = request.clone();
 6868                    async move {
 6869                        (
 6870                            LanguageServerId::from_proto(response.server_id),
 6871                            request
 6872                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6873                                .await,
 6874                        )
 6875                    }
 6876                }))
 6877                .await;
 6878
 6879                let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot())?;
 6880                let mut has_errors = false;
 6881                let inlay_hints = inlay_hints
 6882                    .into_iter()
 6883                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 6884                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 6885                        Err(e) => {
 6886                            has_errors = true;
 6887                            log::error!("{e:#}");
 6888                            None
 6889                        }
 6890                    })
 6891                    .map(|(server_id, mut new_hints)| {
 6892                        new_hints.retain(|hint| {
 6893                            hint.position.is_valid(&buffer_snapshot)
 6894                                && range.start.is_valid(&buffer_snapshot)
 6895                                && range.end.is_valid(&buffer_snapshot)
 6896                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 6897                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 6898                        });
 6899                        (server_id, new_hints)
 6900                    })
 6901                    .collect::<HashMap<_, _>>();
 6902                anyhow::ensure!(
 6903                    !has_errors || !inlay_hints.is_empty(),
 6904                    "Failed to fetch inlay hints"
 6905                );
 6906                Ok(inlay_hints)
 6907            })
 6908        } else {
 6909            let inlay_hints_task = match for_server {
 6910                Some(server_id) => {
 6911                    let server_task = self.request_lsp(
 6912                        buffer.clone(),
 6913                        LanguageServerToQuery::Other(server_id),
 6914                        request,
 6915                        cx,
 6916                    );
 6917                    cx.background_spawn(async move {
 6918                        let mut responses = Vec::new();
 6919                        match server_task.await {
 6920                            Ok(response) => responses.push((server_id, response)),
 6921                            Err(e) => log::error!(
 6922                                "Error handling response for inlay hints request: {e:#}"
 6923                            ),
 6924                        }
 6925                        responses
 6926                    })
 6927                }
 6928                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 6929            };
 6930            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 6931            cx.background_spawn(async move {
 6932                Ok(inlay_hints_task
 6933                    .await
 6934                    .into_iter()
 6935                    .map(|(server_id, mut new_hints)| {
 6936                        new_hints.retain(|hint| {
 6937                            hint.position.is_valid(&buffer_snapshot)
 6938                                && range.start.is_valid(&buffer_snapshot)
 6939                                && range.end.is_valid(&buffer_snapshot)
 6940                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 6941                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 6942                        });
 6943                        (server_id, new_hints)
 6944                    })
 6945                    .collect())
 6946            })
 6947        }
 6948    }
 6949
 6950    pub fn pull_diagnostics_for_buffer(
 6951        &mut self,
 6952        buffer: Entity<Buffer>,
 6953        cx: &mut Context<Self>,
 6954    ) -> Task<anyhow::Result<()>> {
 6955        let diagnostics = self.pull_diagnostics(buffer, cx);
 6956        cx.spawn(async move |lsp_store, cx| {
 6957            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 6958                return Ok(());
 6959            };
 6960            lsp_store.update(cx, |lsp_store, cx| {
 6961                if lsp_store.as_local().is_none() {
 6962                    return;
 6963                }
 6964
 6965                let mut unchanged_buffers = HashSet::default();
 6966                let mut changed_buffers = HashSet::default();
 6967                let server_diagnostics_updates = diagnostics
 6968                    .into_iter()
 6969                    .filter_map(|diagnostics_set| match diagnostics_set {
 6970                        LspPullDiagnostics::Response {
 6971                            server_id,
 6972                            uri,
 6973                            diagnostics,
 6974                        } => Some((server_id, uri, diagnostics)),
 6975                        LspPullDiagnostics::Default => None,
 6976                    })
 6977                    .fold(
 6978                        HashMap::default(),
 6979                        |mut acc, (server_id, uri, diagnostics)| {
 6980                            let (result_id, diagnostics) = match diagnostics {
 6981                                PulledDiagnostics::Unchanged { result_id } => {
 6982                                    unchanged_buffers.insert(uri.clone());
 6983                                    (Some(result_id), Vec::new())
 6984                                }
 6985                                PulledDiagnostics::Changed {
 6986                                    result_id,
 6987                                    diagnostics,
 6988                                } => {
 6989                                    changed_buffers.insert(uri.clone());
 6990                                    (result_id, diagnostics)
 6991                                }
 6992                            };
 6993                            let disk_based_sources = Cow::Owned(
 6994                                lsp_store
 6995                                    .language_server_adapter_for_id(server_id)
 6996                                    .as_ref()
 6997                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 6998                                    .unwrap_or(&[])
 6999                                    .to_vec(),
 7000                            );
 7001                            acc.entry(server_id).or_insert_with(Vec::new).push(
 7002                                DocumentDiagnosticsUpdate {
 7003                                    server_id,
 7004                                    diagnostics: lsp::PublishDiagnosticsParams {
 7005                                        uri,
 7006                                        diagnostics,
 7007                                        version: None,
 7008                                    },
 7009                                    result_id,
 7010                                    disk_based_sources,
 7011                                },
 7012                            );
 7013                            acc
 7014                        },
 7015                    );
 7016
 7017                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7018                    lsp_store
 7019                        .merge_lsp_diagnostics(
 7020                            DiagnosticSourceKind::Pulled,
 7021                            diagnostic_updates,
 7022                            |buffer, old_diagnostic, cx| {
 7023                                File::from_dyn(buffer.file())
 7024                                    .and_then(|file| {
 7025                                        let abs_path = file.as_local()?.abs_path(cx);
 7026                                        lsp::Uri::from_file_path(abs_path).ok()
 7027                                    })
 7028                                    .is_none_or(|buffer_uri| {
 7029                                        unchanged_buffers.contains(&buffer_uri)
 7030                                            || match old_diagnostic.source_kind {
 7031                                                DiagnosticSourceKind::Pulled => {
 7032                                                    !changed_buffers.contains(&buffer_uri)
 7033                                                }
 7034                                                DiagnosticSourceKind::Other
 7035                                                | DiagnosticSourceKind::Pushed => true,
 7036                                            }
 7037                                    })
 7038                            },
 7039                            cx,
 7040                        )
 7041                        .log_err();
 7042                }
 7043            })
 7044        })
 7045    }
 7046
 7047    pub fn document_colors(
 7048        &mut self,
 7049        known_cache_version: Option<usize>,
 7050        buffer: Entity<Buffer>,
 7051        cx: &mut Context<Self>,
 7052    ) -> Option<DocumentColorTask> {
 7053        let version_queried_for = buffer.read(cx).version();
 7054        let buffer_id = buffer.read(cx).remote_id();
 7055
 7056        let current_language_servers = self.as_local().map(|local| {
 7057            local
 7058                .buffers_opened_in_servers
 7059                .get(&buffer_id)
 7060                .cloned()
 7061                .unwrap_or_default()
 7062        });
 7063
 7064        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7065            if let Some(cached_colors) = &lsp_data.document_colors {
 7066                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7067                    let has_different_servers =
 7068                        current_language_servers.is_some_and(|current_language_servers| {
 7069                            current_language_servers
 7070                                != cached_colors.colors.keys().copied().collect()
 7071                        });
 7072                    if !has_different_servers {
 7073                        let cache_version = cached_colors.cache_version;
 7074                        if Some(cache_version) == known_cache_version {
 7075                            return None;
 7076                        } else {
 7077                            return Some(
 7078                                Task::ready(Ok(DocumentColors {
 7079                                    colors: cached_colors
 7080                                        .colors
 7081                                        .values()
 7082                                        .flatten()
 7083                                        .cloned()
 7084                                        .collect(),
 7085                                    cache_version: Some(cache_version),
 7086                                }))
 7087                                .shared(),
 7088                            );
 7089                        }
 7090                    }
 7091                }
 7092            }
 7093        }
 7094
 7095        let color_lsp_data = self
 7096            .latest_lsp_data(&buffer, cx)
 7097            .document_colors
 7098            .get_or_insert_default();
 7099        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7100            && !version_queried_for.changed_since(updating_for)
 7101        {
 7102            return Some(running_update.clone());
 7103        }
 7104        let buffer_version_queried_for = version_queried_for.clone();
 7105        let new_task = cx
 7106            .spawn(async move |lsp_store, cx| {
 7107                cx.background_executor()
 7108                    .timer(Duration::from_millis(30))
 7109                    .await;
 7110                let fetched_colors = lsp_store
 7111                    .update(cx, |lsp_store, cx| {
 7112                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7113                    })?
 7114                    .await
 7115                    .context("fetching document colors")
 7116                    .map_err(Arc::new);
 7117                let fetched_colors = match fetched_colors {
 7118                    Ok(fetched_colors) => {
 7119                        if Some(true)
 7120                            == buffer
 7121                                .update(cx, |buffer, _| {
 7122                                    buffer.version() != buffer_version_queried_for
 7123                                })
 7124                                .ok()
 7125                        {
 7126                            return Ok(DocumentColors::default());
 7127                        }
 7128                        fetched_colors
 7129                    }
 7130                    Err(e) => {
 7131                        lsp_store
 7132                            .update(cx, |lsp_store, _| {
 7133                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7134                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7135                                        document_colors.colors_update = None;
 7136                                    }
 7137                                }
 7138                            })
 7139                            .ok();
 7140                        return Err(e);
 7141                    }
 7142                };
 7143
 7144                lsp_store
 7145                    .update(cx, |lsp_store, cx| {
 7146                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7147                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7148
 7149                        if let Some(fetched_colors) = fetched_colors {
 7150                            if lsp_data.buffer_version == buffer_version_queried_for {
 7151                                lsp_colors.colors.extend(fetched_colors);
 7152                                lsp_colors.cache_version += 1;
 7153                            } else if !lsp_data
 7154                                .buffer_version
 7155                                .changed_since(&buffer_version_queried_for)
 7156                            {
 7157                                lsp_data.buffer_version = buffer_version_queried_for;
 7158                                lsp_colors.colors = fetched_colors;
 7159                                lsp_colors.cache_version += 1;
 7160                            }
 7161                        }
 7162                        lsp_colors.colors_update = None;
 7163                        let colors = lsp_colors
 7164                            .colors
 7165                            .values()
 7166                            .flatten()
 7167                            .cloned()
 7168                            .collect::<HashSet<_>>();
 7169                        DocumentColors {
 7170                            colors,
 7171                            cache_version: Some(lsp_colors.cache_version),
 7172                        }
 7173                    })
 7174                    .map_err(Arc::new)
 7175            })
 7176            .shared();
 7177        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7178        Some(new_task)
 7179    }
 7180
 7181    fn fetch_document_colors_for_buffer(
 7182        &mut self,
 7183        buffer: &Entity<Buffer>,
 7184        cx: &mut Context<Self>,
 7185    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7186        if let Some((client, project_id)) = self.upstream_client() {
 7187            let request = GetDocumentColor {};
 7188            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7189                return Task::ready(Ok(None));
 7190            }
 7191
 7192            let request_task = client.request_lsp(
 7193                project_id,
 7194                None,
 7195                LSP_REQUEST_TIMEOUT,
 7196                cx.background_executor().clone(),
 7197                request.to_proto(project_id, buffer.read(cx)),
 7198            );
 7199            let buffer = buffer.clone();
 7200            cx.spawn(async move |lsp_store, cx| {
 7201                let Some(lsp_store) = lsp_store.upgrade() else {
 7202                    return Ok(None);
 7203                };
 7204                let colors = join_all(
 7205                    request_task
 7206                        .await
 7207                        .log_err()
 7208                        .flatten()
 7209                        .map(|response| response.payload)
 7210                        .unwrap_or_default()
 7211                        .into_iter()
 7212                        .map(|color_response| {
 7213                            let response = request.response_from_proto(
 7214                                color_response.response,
 7215                                lsp_store.clone(),
 7216                                buffer.clone(),
 7217                                cx.clone(),
 7218                            );
 7219                            async move {
 7220                                (
 7221                                    LanguageServerId::from_proto(color_response.server_id),
 7222                                    response.await.log_err().unwrap_or_default(),
 7223                                )
 7224                            }
 7225                        }),
 7226                )
 7227                .await
 7228                .into_iter()
 7229                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7230                    acc.entry(server_id)
 7231                        .or_insert_with(HashSet::default)
 7232                        .extend(colors);
 7233                    acc
 7234                });
 7235                Ok(Some(colors))
 7236            })
 7237        } else {
 7238            let document_colors_task =
 7239                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7240            cx.background_spawn(async move {
 7241                Ok(Some(
 7242                    document_colors_task
 7243                        .await
 7244                        .into_iter()
 7245                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7246                            acc.entry(server_id)
 7247                                .or_insert_with(HashSet::default)
 7248                                .extend(colors);
 7249                            acc
 7250                        })
 7251                        .into_iter()
 7252                        .collect(),
 7253                ))
 7254            })
 7255        }
 7256    }
 7257
 7258    pub fn signature_help<T: ToPointUtf16>(
 7259        &mut self,
 7260        buffer: &Entity<Buffer>,
 7261        position: T,
 7262        cx: &mut Context<Self>,
 7263    ) -> Task<Option<Vec<SignatureHelp>>> {
 7264        let position = position.to_point_utf16(buffer.read(cx));
 7265
 7266        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7267            let request = GetSignatureHelp { position };
 7268            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7269                return Task::ready(None);
 7270            }
 7271            let request_task = client.request_lsp(
 7272                upstream_project_id,
 7273                None,
 7274                LSP_REQUEST_TIMEOUT,
 7275                cx.background_executor().clone(),
 7276                request.to_proto(upstream_project_id, buffer.read(cx)),
 7277            );
 7278            let buffer = buffer.clone();
 7279            cx.spawn(async move |weak_lsp_store, cx| {
 7280                let lsp_store = weak_lsp_store.upgrade()?;
 7281                let signatures = join_all(
 7282                    request_task
 7283                        .await
 7284                        .log_err()
 7285                        .flatten()
 7286                        .map(|response| response.payload)
 7287                        .unwrap_or_default()
 7288                        .into_iter()
 7289                        .map(|response| {
 7290                            let response = GetSignatureHelp { position }.response_from_proto(
 7291                                response.response,
 7292                                lsp_store.clone(),
 7293                                buffer.clone(),
 7294                                cx.clone(),
 7295                            );
 7296                            async move { response.await.log_err().flatten() }
 7297                        }),
 7298                )
 7299                .await
 7300                .into_iter()
 7301                .flatten()
 7302                .collect();
 7303                Some(signatures)
 7304            })
 7305        } else {
 7306            let all_actions_task = self.request_multiple_lsp_locally(
 7307                buffer,
 7308                Some(position),
 7309                GetSignatureHelp { position },
 7310                cx,
 7311            );
 7312            cx.background_spawn(async move {
 7313                Some(
 7314                    all_actions_task
 7315                        .await
 7316                        .into_iter()
 7317                        .flat_map(|(_, actions)| actions)
 7318                        .collect::<Vec<_>>(),
 7319                )
 7320            })
 7321        }
 7322    }
 7323
 7324    pub fn hover(
 7325        &mut self,
 7326        buffer: &Entity<Buffer>,
 7327        position: PointUtf16,
 7328        cx: &mut Context<Self>,
 7329    ) -> Task<Option<Vec<Hover>>> {
 7330        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7331            let request = GetHover { position };
 7332            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7333                return Task::ready(None);
 7334            }
 7335            let request_task = client.request_lsp(
 7336                upstream_project_id,
 7337                None,
 7338                LSP_REQUEST_TIMEOUT,
 7339                cx.background_executor().clone(),
 7340                request.to_proto(upstream_project_id, buffer.read(cx)),
 7341            );
 7342            let buffer = buffer.clone();
 7343            cx.spawn(async move |weak_lsp_store, cx| {
 7344                let lsp_store = weak_lsp_store.upgrade()?;
 7345                let hovers = join_all(
 7346                    request_task
 7347                        .await
 7348                        .log_err()
 7349                        .flatten()
 7350                        .map(|response| response.payload)
 7351                        .unwrap_or_default()
 7352                        .into_iter()
 7353                        .map(|response| {
 7354                            let response = GetHover { position }.response_from_proto(
 7355                                response.response,
 7356                                lsp_store.clone(),
 7357                                buffer.clone(),
 7358                                cx.clone(),
 7359                            );
 7360                            async move {
 7361                                response
 7362                                    .await
 7363                                    .log_err()
 7364                                    .flatten()
 7365                                    .and_then(remove_empty_hover_blocks)
 7366                            }
 7367                        }),
 7368                )
 7369                .await
 7370                .into_iter()
 7371                .flatten()
 7372                .collect();
 7373                Some(hovers)
 7374            })
 7375        } else {
 7376            let all_actions_task = self.request_multiple_lsp_locally(
 7377                buffer,
 7378                Some(position),
 7379                GetHover { position },
 7380                cx,
 7381            );
 7382            cx.background_spawn(async move {
 7383                Some(
 7384                    all_actions_task
 7385                        .await
 7386                        .into_iter()
 7387                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7388                        .collect::<Vec<Hover>>(),
 7389                )
 7390            })
 7391        }
 7392    }
 7393
 7394    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7395        let language_registry = self.languages.clone();
 7396
 7397        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7398            let request = upstream_client.request(proto::GetProjectSymbols {
 7399                project_id: *project_id,
 7400                query: query.to_string(),
 7401            });
 7402            cx.foreground_executor().spawn(async move {
 7403                let response = request.await?;
 7404                let mut symbols = Vec::new();
 7405                let core_symbols = response
 7406                    .symbols
 7407                    .into_iter()
 7408                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7409                    .collect::<Vec<_>>();
 7410                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7411                    .await;
 7412                Ok(symbols)
 7413            })
 7414        } else if let Some(local) = self.as_local() {
 7415            struct WorkspaceSymbolsResult {
 7416                server_id: LanguageServerId,
 7417                lsp_adapter: Arc<CachedLspAdapter>,
 7418                worktree: WeakEntity<Worktree>,
 7419                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7420            }
 7421
 7422            let mut requests = Vec::new();
 7423            let mut requested_servers = BTreeSet::new();
 7424            for (seed, state) in local.language_server_ids.iter() {
 7425                let Some(worktree_handle) = self
 7426                    .worktree_store
 7427                    .read(cx)
 7428                    .worktree_for_id(seed.worktree_id, cx)
 7429                else {
 7430                    continue;
 7431                };
 7432                let worktree = worktree_handle.read(cx);
 7433                if !worktree.is_visible() {
 7434                    continue;
 7435                }
 7436
 7437                if !requested_servers.insert(state.id) {
 7438                    continue;
 7439                }
 7440
 7441                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7442                    Some(LanguageServerState::Running {
 7443                        adapter, server, ..
 7444                    }) => (adapter.clone(), server),
 7445
 7446                    _ => continue,
 7447                };
 7448                let supports_workspace_symbol_request =
 7449                    match server.capabilities().workspace_symbol_provider {
 7450                        Some(OneOf::Left(supported)) => supported,
 7451                        Some(OneOf::Right(_)) => true,
 7452                        None => false,
 7453                    };
 7454                if !supports_workspace_symbol_request {
 7455                    continue;
 7456                }
 7457                let worktree_handle = worktree_handle.clone();
 7458                let server_id = server.server_id();
 7459                requests.push(
 7460                        server
 7461                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7462                                lsp::WorkspaceSymbolParams {
 7463                                    query: query.to_string(),
 7464                                    ..Default::default()
 7465                                },
 7466                            )
 7467                            .map(move |response| {
 7468                                let lsp_symbols = response.into_response()
 7469                                    .context("workspace symbols request")
 7470                                    .log_err()
 7471                                    .flatten()
 7472                                    .map(|symbol_response| match symbol_response {
 7473                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7474                                            flat_responses.into_iter().map(|lsp_symbol| {
 7475                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7476                                            }).collect::<Vec<_>>()
 7477                                        }
 7478                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7479                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7480                                                let location = match lsp_symbol.location {
 7481                                                    OneOf::Left(location) => location,
 7482                                                    OneOf::Right(_) => {
 7483                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7484                                                        return None
 7485                                                    }
 7486                                                };
 7487                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7488                                            }).collect::<Vec<_>>()
 7489                                        }
 7490                                    }).unwrap_or_default();
 7491
 7492                                WorkspaceSymbolsResult {
 7493                                    server_id,
 7494                                    lsp_adapter,
 7495                                    worktree: worktree_handle.downgrade(),
 7496                                    lsp_symbols,
 7497                                }
 7498                            }),
 7499                    );
 7500            }
 7501
 7502            cx.spawn(async move |this, cx| {
 7503                let responses = futures::future::join_all(requests).await;
 7504                let this = match this.upgrade() {
 7505                    Some(this) => this,
 7506                    None => return Ok(Vec::new()),
 7507                };
 7508
 7509                let mut symbols = Vec::new();
 7510                for result in responses {
 7511                    let core_symbols = this.update(cx, |this, cx| {
 7512                        result
 7513                            .lsp_symbols
 7514                            .into_iter()
 7515                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7516                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7517                                let source_worktree = result.worktree.upgrade()?;
 7518                                let source_worktree_id = source_worktree.read(cx).id();
 7519
 7520                                let path = if let Some((tree, rel_path)) =
 7521                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7522                                {
 7523                                    let worktree_id = tree.read(cx).id();
 7524                                    SymbolLocation::InProject(ProjectPath {
 7525                                        worktree_id,
 7526                                        path: rel_path,
 7527                                    })
 7528                                } else {
 7529                                    SymbolLocation::OutsideProject {
 7530                                        signature: this.symbol_signature(&abs_path),
 7531                                        abs_path: abs_path.into(),
 7532                                    }
 7533                                };
 7534
 7535                                Some(CoreSymbol {
 7536                                    source_language_server_id: result.server_id,
 7537                                    language_server_name: result.lsp_adapter.name.clone(),
 7538                                    source_worktree_id,
 7539                                    path,
 7540                                    kind: symbol_kind,
 7541                                    name: symbol_name,
 7542                                    range: range_from_lsp(symbol_location.range),
 7543                                })
 7544                            })
 7545                            .collect()
 7546                    })?;
 7547
 7548                    populate_labels_for_symbols(
 7549                        core_symbols,
 7550                        &language_registry,
 7551                        Some(result.lsp_adapter),
 7552                        &mut symbols,
 7553                    )
 7554                    .await;
 7555                }
 7556
 7557                Ok(symbols)
 7558            })
 7559        } else {
 7560            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7561        }
 7562    }
 7563
 7564    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7565        let mut summary = DiagnosticSummary::default();
 7566        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7567            summary.error_count += path_summary.error_count;
 7568            summary.warning_count += path_summary.warning_count;
 7569        }
 7570        summary
 7571    }
 7572
 7573    /// Returns the diagnostic summary for a specific project path.
 7574    pub fn diagnostic_summary_for_path(
 7575        &self,
 7576        project_path: &ProjectPath,
 7577        _: &App,
 7578    ) -> DiagnosticSummary {
 7579        if let Some(summaries) = self
 7580            .diagnostic_summaries
 7581            .get(&project_path.worktree_id)
 7582            .and_then(|map| map.get(&project_path.path))
 7583        {
 7584            let (error_count, warning_count) = summaries.iter().fold(
 7585                (0, 0),
 7586                |(error_count, warning_count), (_language_server_id, summary)| {
 7587                    (
 7588                        error_count + summary.error_count,
 7589                        warning_count + summary.warning_count,
 7590                    )
 7591                },
 7592            );
 7593
 7594            DiagnosticSummary {
 7595                error_count,
 7596                warning_count,
 7597            }
 7598        } else {
 7599            DiagnosticSummary::default()
 7600        }
 7601    }
 7602
 7603    pub fn diagnostic_summaries<'a>(
 7604        &'a self,
 7605        include_ignored: bool,
 7606        cx: &'a App,
 7607    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7608        self.worktree_store
 7609            .read(cx)
 7610            .visible_worktrees(cx)
 7611            .filter_map(|worktree| {
 7612                let worktree = worktree.read(cx);
 7613                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7614            })
 7615            .flat_map(move |(worktree, summaries)| {
 7616                let worktree_id = worktree.id();
 7617                summaries
 7618                    .iter()
 7619                    .filter(move |(path, _)| {
 7620                        include_ignored
 7621                            || worktree
 7622                                .entry_for_path(path.as_ref())
 7623                                .is_some_and(|entry| !entry.is_ignored)
 7624                    })
 7625                    .flat_map(move |(path, summaries)| {
 7626                        summaries.iter().map(move |(server_id, summary)| {
 7627                            (
 7628                                ProjectPath {
 7629                                    worktree_id,
 7630                                    path: path.clone(),
 7631                                },
 7632                                *server_id,
 7633                                *summary,
 7634                            )
 7635                        })
 7636                    })
 7637            })
 7638    }
 7639
 7640    pub fn on_buffer_edited(
 7641        &mut self,
 7642        buffer: Entity<Buffer>,
 7643        cx: &mut Context<Self>,
 7644    ) -> Option<()> {
 7645        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7646            Some(
 7647                self.as_local()?
 7648                    .language_servers_for_buffer(buffer, cx)
 7649                    .map(|i| i.1.clone())
 7650                    .collect(),
 7651            )
 7652        })?;
 7653
 7654        let buffer = buffer.read(cx);
 7655        let file = File::from_dyn(buffer.file())?;
 7656        let abs_path = file.as_local()?.abs_path(cx);
 7657        let uri = lsp::Uri::from_file_path(&abs_path)
 7658            .ok()
 7659            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7660            .unwrap();
 7661        let next_snapshot = buffer.text_snapshot();
 7662        for language_server in language_servers {
 7663            let language_server = language_server.clone();
 7664
 7665            let buffer_snapshots = self
 7666                .as_local_mut()
 7667                .unwrap()
 7668                .buffer_snapshots
 7669                .get_mut(&buffer.remote_id())
 7670                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7671            let previous_snapshot = buffer_snapshots.last()?;
 7672
 7673            let build_incremental_change = || {
 7674                buffer
 7675                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7676                        previous_snapshot.snapshot.version(),
 7677                    )
 7678                    .map(|edit| {
 7679                        let edit_start = edit.new.start.0;
 7680                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7681                        let new_text = next_snapshot
 7682                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7683                            .collect();
 7684                        lsp::TextDocumentContentChangeEvent {
 7685                            range: Some(lsp::Range::new(
 7686                                point_to_lsp(edit_start),
 7687                                point_to_lsp(edit_end),
 7688                            )),
 7689                            range_length: None,
 7690                            text: new_text,
 7691                        }
 7692                    })
 7693                    .collect()
 7694            };
 7695
 7696            let document_sync_kind = language_server
 7697                .capabilities()
 7698                .text_document_sync
 7699                .as_ref()
 7700                .and_then(|sync| match sync {
 7701                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7702                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7703                });
 7704
 7705            let content_changes: Vec<_> = match document_sync_kind {
 7706                Some(lsp::TextDocumentSyncKind::FULL) => {
 7707                    vec![lsp::TextDocumentContentChangeEvent {
 7708                        range: None,
 7709                        range_length: None,
 7710                        text: next_snapshot.text(),
 7711                    }]
 7712                }
 7713                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7714                _ => {
 7715                    #[cfg(any(test, feature = "test-support"))]
 7716                    {
 7717                        build_incremental_change()
 7718                    }
 7719
 7720                    #[cfg(not(any(test, feature = "test-support")))]
 7721                    {
 7722                        continue;
 7723                    }
 7724                }
 7725            };
 7726
 7727            let next_version = previous_snapshot.version + 1;
 7728            buffer_snapshots.push(LspBufferSnapshot {
 7729                version: next_version,
 7730                snapshot: next_snapshot.clone(),
 7731            });
 7732
 7733            language_server
 7734                .notify::<lsp::notification::DidChangeTextDocument>(
 7735                    lsp::DidChangeTextDocumentParams {
 7736                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7737                            uri.clone(),
 7738                            next_version,
 7739                        ),
 7740                        content_changes,
 7741                    },
 7742                )
 7743                .ok();
 7744            self.pull_workspace_diagnostics(language_server.server_id());
 7745        }
 7746
 7747        None
 7748    }
 7749
 7750    pub fn on_buffer_saved(
 7751        &mut self,
 7752        buffer: Entity<Buffer>,
 7753        cx: &mut Context<Self>,
 7754    ) -> Option<()> {
 7755        let file = File::from_dyn(buffer.read(cx).file())?;
 7756        let worktree_id = file.worktree_id(cx);
 7757        let abs_path = file.as_local()?.abs_path(cx);
 7758        let text_document = lsp::TextDocumentIdentifier {
 7759            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7760        };
 7761        let local = self.as_local()?;
 7762
 7763        for server in local.language_servers_for_worktree(worktree_id) {
 7764            if let Some(include_text) = include_text(server.as_ref()) {
 7765                let text = if include_text {
 7766                    Some(buffer.read(cx).text())
 7767                } else {
 7768                    None
 7769                };
 7770                server
 7771                    .notify::<lsp::notification::DidSaveTextDocument>(
 7772                        lsp::DidSaveTextDocumentParams {
 7773                            text_document: text_document.clone(),
 7774                            text,
 7775                        },
 7776                    )
 7777                    .ok();
 7778            }
 7779        }
 7780
 7781        let language_servers = buffer.update(cx, |buffer, cx| {
 7782            local.language_server_ids_for_buffer(buffer, cx)
 7783        });
 7784        for language_server_id in language_servers {
 7785            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7786        }
 7787
 7788        None
 7789    }
 7790
 7791    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 7792        maybe!(async move {
 7793            let mut refreshed_servers = HashSet::default();
 7794            let servers = lsp_store
 7795                .update(cx, |lsp_store, cx| {
 7796                    let local = lsp_store.as_local()?;
 7797
 7798                    let servers = local
 7799                        .language_server_ids
 7800                        .iter()
 7801                        .filter_map(|(seed, state)| {
 7802                            let worktree = lsp_store
 7803                                .worktree_store
 7804                                .read(cx)
 7805                                .worktree_for_id(seed.worktree_id, cx);
 7806                            let delegate: Arc<dyn LspAdapterDelegate> =
 7807                                worktree.map(|worktree| {
 7808                                    LocalLspAdapterDelegate::new(
 7809                                        local.languages.clone(),
 7810                                        &local.environment,
 7811                                        cx.weak_entity(),
 7812                                        &worktree,
 7813                                        local.http_client.clone(),
 7814                                        local.fs.clone(),
 7815                                        cx,
 7816                                    )
 7817                                })?;
 7818                            let server_id = state.id;
 7819
 7820                            let states = local.language_servers.get(&server_id)?;
 7821
 7822                            match states {
 7823                                LanguageServerState::Starting { .. } => None,
 7824                                LanguageServerState::Running {
 7825                                    adapter, server, ..
 7826                                } => {
 7827                                    let adapter = adapter.clone();
 7828                                    let server = server.clone();
 7829                                    refreshed_servers.insert(server.name());
 7830                                    let toolchain = seed.toolchain.clone();
 7831                                    Some(cx.spawn(async move |_, cx| {
 7832                                        let settings =
 7833                                            LocalLspStore::workspace_configuration_for_adapter(
 7834                                                adapter.adapter.clone(),
 7835                                                &delegate,
 7836                                                toolchain,
 7837                                                cx,
 7838                                            )
 7839                                            .await
 7840                                            .ok()?;
 7841                                        server
 7842                                            .notify::<lsp::notification::DidChangeConfiguration>(
 7843                                                lsp::DidChangeConfigurationParams { settings },
 7844                                            )
 7845                                            .ok()?;
 7846                                        Some(())
 7847                                    }))
 7848                                }
 7849                            }
 7850                        })
 7851                        .collect::<Vec<_>>();
 7852
 7853                    Some(servers)
 7854                })
 7855                .ok()
 7856                .flatten()?;
 7857
 7858            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 7859            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 7860            // to stop and unregister its language server wrapper.
 7861            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 7862            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 7863            let _: Vec<Option<()>> = join_all(servers).await;
 7864
 7865            Some(())
 7866        })
 7867        .await;
 7868    }
 7869
 7870    fn maintain_workspace_config(
 7871        external_refresh_requests: watch::Receiver<()>,
 7872        cx: &mut Context<Self>,
 7873    ) -> Task<Result<()>> {
 7874        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 7875        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 7876
 7877        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 7878            *settings_changed_tx.borrow_mut() = ();
 7879        });
 7880
 7881        let mut joint_future =
 7882            futures::stream::select(settings_changed_rx, external_refresh_requests);
 7883        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 7884        // - 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).
 7885        // - 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.
 7886        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 7887        // - 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,
 7888        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 7889        cx.spawn(async move |this, cx| {
 7890            while let Some(()) = joint_future.next().await {
 7891                this.update(cx, |this, cx| {
 7892                    this.refresh_server_tree(cx);
 7893                })
 7894                .ok();
 7895
 7896                Self::refresh_workspace_configurations(&this, cx).await;
 7897            }
 7898
 7899            drop(settings_observation);
 7900            anyhow::Ok(())
 7901        })
 7902    }
 7903
 7904    pub fn language_servers_for_local_buffer<'a>(
 7905        &'a self,
 7906        buffer: &Buffer,
 7907        cx: &mut App,
 7908    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7909        let local = self.as_local();
 7910        let language_server_ids = local
 7911            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 7912            .unwrap_or_default();
 7913
 7914        language_server_ids
 7915            .into_iter()
 7916            .filter_map(
 7917                move |server_id| match local?.language_servers.get(&server_id)? {
 7918                    LanguageServerState::Running {
 7919                        adapter, server, ..
 7920                    } => Some((adapter, server)),
 7921                    _ => None,
 7922                },
 7923            )
 7924    }
 7925
 7926    pub fn language_server_for_local_buffer<'a>(
 7927        &'a self,
 7928        buffer: &'a Buffer,
 7929        server_id: LanguageServerId,
 7930        cx: &'a mut App,
 7931    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7932        self.as_local()?
 7933            .language_servers_for_buffer(buffer, cx)
 7934            .find(|(_, s)| s.server_id() == server_id)
 7935    }
 7936
 7937    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 7938        self.diagnostic_summaries.remove(&id_to_remove);
 7939        if let Some(local) = self.as_local_mut() {
 7940            let to_remove = local.remove_worktree(id_to_remove, cx);
 7941            for server in to_remove {
 7942                self.language_server_statuses.remove(&server);
 7943            }
 7944        }
 7945    }
 7946
 7947    pub fn shared(
 7948        &mut self,
 7949        project_id: u64,
 7950        downstream_client: AnyProtoClient,
 7951        _: &mut Context<Self>,
 7952    ) {
 7953        self.downstream_client = Some((downstream_client.clone(), project_id));
 7954
 7955        for (server_id, status) in &self.language_server_statuses {
 7956            if let Some(server) = self.language_server_for_id(*server_id) {
 7957                downstream_client
 7958                    .send(proto::StartLanguageServer {
 7959                        project_id,
 7960                        server: Some(proto::LanguageServer {
 7961                            id: server_id.to_proto(),
 7962                            name: status.name.to_string(),
 7963                            worktree_id: status.worktree.map(|id| id.to_proto()),
 7964                        }),
 7965                        capabilities: serde_json::to_string(&server.capabilities())
 7966                            .expect("serializing server LSP capabilities"),
 7967                    })
 7968                    .log_err();
 7969            }
 7970        }
 7971    }
 7972
 7973    pub fn disconnected_from_host(&mut self) {
 7974        self.downstream_client.take();
 7975    }
 7976
 7977    pub fn disconnected_from_ssh_remote(&mut self) {
 7978        if let LspStoreMode::Remote(RemoteLspStore {
 7979            upstream_client, ..
 7980        }) = &mut self.mode
 7981        {
 7982            upstream_client.take();
 7983        }
 7984    }
 7985
 7986    pub(crate) fn set_language_server_statuses_from_proto(
 7987        &mut self,
 7988        project: WeakEntity<Project>,
 7989        language_servers: Vec<proto::LanguageServer>,
 7990        server_capabilities: Vec<String>,
 7991        cx: &mut Context<Self>,
 7992    ) {
 7993        let lsp_logs = cx
 7994            .try_global::<GlobalLogStore>()
 7995            .map(|lsp_store| lsp_store.0.clone());
 7996
 7997        self.language_server_statuses = language_servers
 7998            .into_iter()
 7999            .zip(server_capabilities)
 8000            .map(|(server, server_capabilities)| {
 8001                let server_id = LanguageServerId(server.id as usize);
 8002                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8003                    self.lsp_server_capabilities
 8004                        .insert(server_id, server_capabilities);
 8005                }
 8006
 8007                let name = LanguageServerName::from_proto(server.name);
 8008                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8009
 8010                if let Some(lsp_logs) = &lsp_logs {
 8011                    lsp_logs.update(cx, |lsp_logs, cx| {
 8012                        lsp_logs.add_language_server(
 8013                            // Only remote clients get their language servers set from proto
 8014                            LanguageServerKind::Remote {
 8015                                project: project.clone(),
 8016                            },
 8017                            server_id,
 8018                            Some(name.clone()),
 8019                            worktree,
 8020                            None,
 8021                            cx,
 8022                        );
 8023                    });
 8024                }
 8025
 8026                (
 8027                    server_id,
 8028                    LanguageServerStatus {
 8029                        name,
 8030                        pending_work: Default::default(),
 8031                        has_pending_diagnostic_updates: false,
 8032                        progress_tokens: Default::default(),
 8033                        worktree,
 8034                    },
 8035                )
 8036            })
 8037            .collect();
 8038    }
 8039
 8040    #[cfg(test)]
 8041    pub fn update_diagnostic_entries(
 8042        &mut self,
 8043        server_id: LanguageServerId,
 8044        abs_path: PathBuf,
 8045        result_id: Option<String>,
 8046        version: Option<i32>,
 8047        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8048        cx: &mut Context<Self>,
 8049    ) -> anyhow::Result<()> {
 8050        self.merge_diagnostic_entries(
 8051            vec![DocumentDiagnosticsUpdate {
 8052                diagnostics: DocumentDiagnostics {
 8053                    diagnostics,
 8054                    document_abs_path: abs_path,
 8055                    version,
 8056                },
 8057                result_id,
 8058                server_id,
 8059                disk_based_sources: Cow::Borrowed(&[]),
 8060            }],
 8061            |_, _, _| false,
 8062            cx,
 8063        )?;
 8064        Ok(())
 8065    }
 8066
 8067    pub fn merge_diagnostic_entries<'a>(
 8068        &mut self,
 8069        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8070        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
 8071        cx: &mut Context<Self>,
 8072    ) -> anyhow::Result<()> {
 8073        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8074        let mut updated_diagnostics_paths = HashMap::default();
 8075        for mut update in diagnostic_updates {
 8076            let abs_path = &update.diagnostics.document_abs_path;
 8077            let server_id = update.server_id;
 8078            let Some((worktree, relative_path)) =
 8079                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8080            else {
 8081                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8082                return Ok(());
 8083            };
 8084
 8085            let worktree_id = worktree.read(cx).id();
 8086            let project_path = ProjectPath {
 8087                worktree_id,
 8088                path: relative_path,
 8089            };
 8090
 8091            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8092                let snapshot = buffer_handle.read(cx).snapshot();
 8093                let buffer = buffer_handle.read(cx);
 8094                let reused_diagnostics = buffer
 8095                    .buffer_diagnostics(Some(server_id))
 8096                    .iter()
 8097                    .filter(|v| merge(buffer, &v.diagnostic, cx))
 8098                    .map(|v| {
 8099                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8100                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8101                        DiagnosticEntry {
 8102                            range: start..end,
 8103                            diagnostic: v.diagnostic.clone(),
 8104                        }
 8105                    })
 8106                    .collect::<Vec<_>>();
 8107
 8108                self.as_local_mut()
 8109                    .context("cannot merge diagnostics on a remote LspStore")?
 8110                    .update_buffer_diagnostics(
 8111                        &buffer_handle,
 8112                        server_id,
 8113                        update.result_id,
 8114                        update.diagnostics.version,
 8115                        update.diagnostics.diagnostics.clone(),
 8116                        reused_diagnostics.clone(),
 8117                        cx,
 8118                    )?;
 8119
 8120                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8121            }
 8122
 8123            let updated = worktree.update(cx, |worktree, cx| {
 8124                self.update_worktree_diagnostics(
 8125                    worktree.id(),
 8126                    server_id,
 8127                    project_path.path.clone(),
 8128                    update.diagnostics.diagnostics,
 8129                    cx,
 8130                )
 8131            })?;
 8132            match updated {
 8133                ControlFlow::Continue(new_summary) => {
 8134                    if let Some((project_id, new_summary)) = new_summary {
 8135                        match &mut diagnostics_summary {
 8136                            Some(diagnostics_summary) => {
 8137                                diagnostics_summary
 8138                                    .more_summaries
 8139                                    .push(proto::DiagnosticSummary {
 8140                                        path: project_path.path.as_ref().to_proto(),
 8141                                        language_server_id: server_id.0 as u64,
 8142                                        error_count: new_summary.error_count,
 8143                                        warning_count: new_summary.warning_count,
 8144                                    })
 8145                            }
 8146                            None => {
 8147                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8148                                    project_id,
 8149                                    worktree_id: worktree_id.to_proto(),
 8150                                    summary: Some(proto::DiagnosticSummary {
 8151                                        path: project_path.path.as_ref().to_proto(),
 8152                                        language_server_id: server_id.0 as u64,
 8153                                        error_count: new_summary.error_count,
 8154                                        warning_count: new_summary.warning_count,
 8155                                    }),
 8156                                    more_summaries: Vec::new(),
 8157                                })
 8158                            }
 8159                        }
 8160                    }
 8161                    updated_diagnostics_paths
 8162                        .entry(server_id)
 8163                        .or_insert_with(Vec::new)
 8164                        .push(project_path);
 8165                }
 8166                ControlFlow::Break(()) => {}
 8167            }
 8168        }
 8169
 8170        if let Some((diagnostics_summary, (downstream_client, _))) =
 8171            diagnostics_summary.zip(self.downstream_client.as_ref())
 8172        {
 8173            downstream_client.send(diagnostics_summary).log_err();
 8174        }
 8175        for (server_id, paths) in updated_diagnostics_paths {
 8176            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8177        }
 8178        Ok(())
 8179    }
 8180
 8181    fn update_worktree_diagnostics(
 8182        &mut self,
 8183        worktree_id: WorktreeId,
 8184        server_id: LanguageServerId,
 8185        path_in_worktree: Arc<RelPath>,
 8186        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8187        _: &mut Context<Worktree>,
 8188    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8189        let local = match &mut self.mode {
 8190            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8191            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8192        };
 8193
 8194        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8195        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8196        let summaries_by_server_id = summaries_for_tree
 8197            .entry(path_in_worktree.clone())
 8198            .or_default();
 8199
 8200        let old_summary = summaries_by_server_id
 8201            .remove(&server_id)
 8202            .unwrap_or_default();
 8203
 8204        let new_summary = DiagnosticSummary::new(&diagnostics);
 8205        if new_summary.is_empty() {
 8206            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8207            {
 8208                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8209                    diagnostics_by_server_id.remove(ix);
 8210                }
 8211                if diagnostics_by_server_id.is_empty() {
 8212                    diagnostics_for_tree.remove(&path_in_worktree);
 8213                }
 8214            }
 8215        } else {
 8216            summaries_by_server_id.insert(server_id, new_summary);
 8217            let diagnostics_by_server_id = diagnostics_for_tree
 8218                .entry(path_in_worktree.clone())
 8219                .or_default();
 8220            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8221                Ok(ix) => {
 8222                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8223                }
 8224                Err(ix) => {
 8225                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8226                }
 8227            }
 8228        }
 8229
 8230        if !old_summary.is_empty() || !new_summary.is_empty() {
 8231            if let Some((_, project_id)) = &self.downstream_client {
 8232                Ok(ControlFlow::Continue(Some((
 8233                    *project_id,
 8234                    proto::DiagnosticSummary {
 8235                        path: path_in_worktree.to_proto(),
 8236                        language_server_id: server_id.0 as u64,
 8237                        error_count: new_summary.error_count as u32,
 8238                        warning_count: new_summary.warning_count as u32,
 8239                    },
 8240                ))))
 8241            } else {
 8242                Ok(ControlFlow::Continue(None))
 8243            }
 8244        } else {
 8245            Ok(ControlFlow::Break(()))
 8246        }
 8247    }
 8248
 8249    pub fn open_buffer_for_symbol(
 8250        &mut self,
 8251        symbol: &Symbol,
 8252        cx: &mut Context<Self>,
 8253    ) -> Task<Result<Entity<Buffer>>> {
 8254        if let Some((client, project_id)) = self.upstream_client() {
 8255            let request = client.request(proto::OpenBufferForSymbol {
 8256                project_id,
 8257                symbol: Some(Self::serialize_symbol(symbol)),
 8258            });
 8259            cx.spawn(async move |this, cx| {
 8260                let response = request.await?;
 8261                let buffer_id = BufferId::new(response.buffer_id)?;
 8262                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8263                    .await
 8264            })
 8265        } else if let Some(local) = self.as_local() {
 8266            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8267                seed.worktree_id == symbol.source_worktree_id
 8268                    && state.id == symbol.source_language_server_id
 8269                    && symbol.language_server_name == seed.name
 8270            });
 8271            if !is_valid {
 8272                return Task::ready(Err(anyhow!(
 8273                    "language server for worktree and language not found"
 8274                )));
 8275            };
 8276
 8277            let symbol_abs_path = match &symbol.path {
 8278                SymbolLocation::InProject(project_path) => self
 8279                    .worktree_store
 8280                    .read(cx)
 8281                    .absolutize(&project_path, cx)
 8282                    .context("no such worktree"),
 8283                SymbolLocation::OutsideProject {
 8284                    abs_path,
 8285                    signature: _,
 8286                } => Ok(abs_path.to_path_buf()),
 8287            };
 8288            let symbol_abs_path = match symbol_abs_path {
 8289                Ok(abs_path) => abs_path,
 8290                Err(err) => return Task::ready(Err(err)),
 8291            };
 8292            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8293                uri
 8294            } else {
 8295                return Task::ready(Err(anyhow!("invalid symbol path")));
 8296            };
 8297
 8298            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8299        } else {
 8300            Task::ready(Err(anyhow!("no upstream client or local store")))
 8301        }
 8302    }
 8303
 8304    pub(crate) fn open_local_buffer_via_lsp(
 8305        &mut self,
 8306        abs_path: lsp::Uri,
 8307        language_server_id: LanguageServerId,
 8308        cx: &mut Context<Self>,
 8309    ) -> Task<Result<Entity<Buffer>>> {
 8310        cx.spawn(async move |lsp_store, cx| {
 8311            // Escape percent-encoded string.
 8312            let current_scheme = abs_path.scheme().to_owned();
 8313            // Uri is immutable, so we can't modify the scheme
 8314
 8315            let abs_path = abs_path
 8316                .to_file_path()
 8317                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8318            let p = abs_path.clone();
 8319            let yarn_worktree = lsp_store
 8320                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8321                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8322                        cx.spawn(async move |this, cx| {
 8323                            let t = this
 8324                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8325                                .ok()?;
 8326                            t.await
 8327                        })
 8328                    }),
 8329                    None => Task::ready(None),
 8330                })?
 8331                .await;
 8332            let (worktree_root_target, known_relative_path) =
 8333                if let Some((zip_root, relative_path)) = yarn_worktree {
 8334                    (zip_root, Some(relative_path))
 8335                } else {
 8336                    (Arc::<Path>::from(abs_path.as_path()), None)
 8337                };
 8338            let (worktree, relative_path) = if let Some(result) =
 8339                lsp_store.update(cx, |lsp_store, cx| {
 8340                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8341                        worktree_store.find_worktree(&worktree_root_target, cx)
 8342                    })
 8343                })? {
 8344                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8345                (result.0, relative_path)
 8346            } else {
 8347                let worktree = lsp_store
 8348                    .update(cx, |lsp_store, cx| {
 8349                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8350                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8351                        })
 8352                    })?
 8353                    .await?;
 8354                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8355                    lsp_store
 8356                        .update(cx, |lsp_store, cx| {
 8357                            if let Some(local) = lsp_store.as_local_mut() {
 8358                                local.register_language_server_for_invisible_worktree(
 8359                                    &worktree,
 8360                                    language_server_id,
 8361                                    cx,
 8362                                )
 8363                            }
 8364                        })
 8365                        .ok();
 8366                }
 8367                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8368                let relative_path = if let Some(known_path) = known_relative_path {
 8369                    known_path
 8370                } else {
 8371                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8372                        .into_arc()
 8373                };
 8374                (worktree, relative_path)
 8375            };
 8376            let project_path = ProjectPath {
 8377                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8378                path: relative_path,
 8379            };
 8380            lsp_store
 8381                .update(cx, |lsp_store, cx| {
 8382                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8383                        buffer_store.open_buffer(project_path, cx)
 8384                    })
 8385                })?
 8386                .await
 8387        })
 8388    }
 8389
 8390    fn request_multiple_lsp_locally<P, R>(
 8391        &mut self,
 8392        buffer: &Entity<Buffer>,
 8393        position: Option<P>,
 8394        request: R,
 8395        cx: &mut Context<Self>,
 8396    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8397    where
 8398        P: ToOffset,
 8399        R: LspCommand + Clone,
 8400        <R::LspRequest as lsp::request::Request>::Result: Send,
 8401        <R::LspRequest as lsp::request::Request>::Params: Send,
 8402    {
 8403        let Some(local) = self.as_local() else {
 8404            return Task::ready(Vec::new());
 8405        };
 8406
 8407        let snapshot = buffer.read(cx).snapshot();
 8408        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8409
 8410        let server_ids = buffer.update(cx, |buffer, cx| {
 8411            local
 8412                .language_servers_for_buffer(buffer, cx)
 8413                .filter(|(adapter, _)| {
 8414                    scope
 8415                        .as_ref()
 8416                        .map(|scope| scope.language_allowed(&adapter.name))
 8417                        .unwrap_or(true)
 8418                })
 8419                .map(|(_, server)| server.server_id())
 8420                .filter(|server_id| {
 8421                    self.as_local().is_none_or(|local| {
 8422                        local
 8423                            .buffers_opened_in_servers
 8424                            .get(&snapshot.remote_id())
 8425                            .is_some_and(|servers| servers.contains(server_id))
 8426                    })
 8427                })
 8428                .collect::<Vec<_>>()
 8429        });
 8430
 8431        let mut response_results = server_ids
 8432            .into_iter()
 8433            .map(|server_id| {
 8434                let task = self.request_lsp(
 8435                    buffer.clone(),
 8436                    LanguageServerToQuery::Other(server_id),
 8437                    request.clone(),
 8438                    cx,
 8439                );
 8440                async move { (server_id, task.await) }
 8441            })
 8442            .collect::<FuturesUnordered<_>>();
 8443
 8444        cx.background_spawn(async move {
 8445            let mut responses = Vec::with_capacity(response_results.len());
 8446            while let Some((server_id, response_result)) = response_results.next().await {
 8447                match response_result {
 8448                    Ok(response) => responses.push((server_id, response)),
 8449                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8450                }
 8451            }
 8452            responses
 8453        })
 8454    }
 8455
 8456    async fn handle_lsp_command<T: LspCommand>(
 8457        this: Entity<Self>,
 8458        envelope: TypedEnvelope<T::ProtoRequest>,
 8459        mut cx: AsyncApp,
 8460    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8461    where
 8462        <T::LspRequest as lsp::request::Request>::Params: Send,
 8463        <T::LspRequest as lsp::request::Request>::Result: Send,
 8464    {
 8465        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8466        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8467        let buffer_handle = this.update(&mut cx, |this, cx| {
 8468            this.buffer_store.read(cx).get_existing(buffer_id)
 8469        })??;
 8470        let request = T::from_proto(
 8471            envelope.payload,
 8472            this.clone(),
 8473            buffer_handle.clone(),
 8474            cx.clone(),
 8475        )
 8476        .await?;
 8477        let response = this
 8478            .update(&mut cx, |this, cx| {
 8479                this.request_lsp(
 8480                    buffer_handle.clone(),
 8481                    LanguageServerToQuery::FirstCapable,
 8482                    request,
 8483                    cx,
 8484                )
 8485            })?
 8486            .await?;
 8487        this.update(&mut cx, |this, cx| {
 8488            Ok(T::response_to_proto(
 8489                response,
 8490                this,
 8491                sender_id,
 8492                &buffer_handle.read(cx).version(),
 8493                cx,
 8494            ))
 8495        })?
 8496    }
 8497
 8498    async fn handle_lsp_query(
 8499        lsp_store: Entity<Self>,
 8500        envelope: TypedEnvelope<proto::LspQuery>,
 8501        mut cx: AsyncApp,
 8502    ) -> Result<proto::Ack> {
 8503        use proto::lsp_query::Request;
 8504        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8505        let lsp_query = envelope.payload;
 8506        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8507        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8508        match lsp_query.request.context("invalid LSP query request")? {
 8509            Request::GetReferences(get_references) => {
 8510                let position = get_references.position.clone().and_then(deserialize_anchor);
 8511                Self::query_lsp_locally::<GetReferences>(
 8512                    lsp_store,
 8513                    server_id,
 8514                    sender_id,
 8515                    lsp_request_id,
 8516                    get_references,
 8517                    position,
 8518                    &mut cx,
 8519                )
 8520                .await?;
 8521            }
 8522            Request::GetDocumentColor(get_document_color) => {
 8523                Self::query_lsp_locally::<GetDocumentColor>(
 8524                    lsp_store,
 8525                    server_id,
 8526                    sender_id,
 8527                    lsp_request_id,
 8528                    get_document_color,
 8529                    None,
 8530                    &mut cx,
 8531                )
 8532                .await?;
 8533            }
 8534            Request::GetHover(get_hover) => {
 8535                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8536                Self::query_lsp_locally::<GetHover>(
 8537                    lsp_store,
 8538                    server_id,
 8539                    sender_id,
 8540                    lsp_request_id,
 8541                    get_hover,
 8542                    position,
 8543                    &mut cx,
 8544                )
 8545                .await?;
 8546            }
 8547            Request::GetCodeActions(get_code_actions) => {
 8548                Self::query_lsp_locally::<GetCodeActions>(
 8549                    lsp_store,
 8550                    server_id,
 8551                    sender_id,
 8552                    lsp_request_id,
 8553                    get_code_actions,
 8554                    None,
 8555                    &mut cx,
 8556                )
 8557                .await?;
 8558            }
 8559            Request::GetSignatureHelp(get_signature_help) => {
 8560                let position = get_signature_help
 8561                    .position
 8562                    .clone()
 8563                    .and_then(deserialize_anchor);
 8564                Self::query_lsp_locally::<GetSignatureHelp>(
 8565                    lsp_store,
 8566                    server_id,
 8567                    sender_id,
 8568                    lsp_request_id,
 8569                    get_signature_help,
 8570                    position,
 8571                    &mut cx,
 8572                )
 8573                .await?;
 8574            }
 8575            Request::GetCodeLens(get_code_lens) => {
 8576                Self::query_lsp_locally::<GetCodeLens>(
 8577                    lsp_store,
 8578                    server_id,
 8579                    sender_id,
 8580                    lsp_request_id,
 8581                    get_code_lens,
 8582                    None,
 8583                    &mut cx,
 8584                )
 8585                .await?;
 8586            }
 8587            Request::GetDefinition(get_definition) => {
 8588                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8589                Self::query_lsp_locally::<GetDefinitions>(
 8590                    lsp_store,
 8591                    server_id,
 8592                    sender_id,
 8593                    lsp_request_id,
 8594                    get_definition,
 8595                    position,
 8596                    &mut cx,
 8597                )
 8598                .await?;
 8599            }
 8600            Request::GetDeclaration(get_declaration) => {
 8601                let position = get_declaration
 8602                    .position
 8603                    .clone()
 8604                    .and_then(deserialize_anchor);
 8605                Self::query_lsp_locally::<GetDeclarations>(
 8606                    lsp_store,
 8607                    server_id,
 8608                    sender_id,
 8609                    lsp_request_id,
 8610                    get_declaration,
 8611                    position,
 8612                    &mut cx,
 8613                )
 8614                .await?;
 8615            }
 8616            Request::GetTypeDefinition(get_type_definition) => {
 8617                let position = get_type_definition
 8618                    .position
 8619                    .clone()
 8620                    .and_then(deserialize_anchor);
 8621                Self::query_lsp_locally::<GetTypeDefinitions>(
 8622                    lsp_store,
 8623                    server_id,
 8624                    sender_id,
 8625                    lsp_request_id,
 8626                    get_type_definition,
 8627                    position,
 8628                    &mut cx,
 8629                )
 8630                .await?;
 8631            }
 8632            Request::GetImplementation(get_implementation) => {
 8633                let position = get_implementation
 8634                    .position
 8635                    .clone()
 8636                    .and_then(deserialize_anchor);
 8637                Self::query_lsp_locally::<GetImplementations>(
 8638                    lsp_store,
 8639                    server_id,
 8640                    sender_id,
 8641                    lsp_request_id,
 8642                    get_implementation,
 8643                    position,
 8644                    &mut cx,
 8645                )
 8646                .await?;
 8647            }
 8648            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 8649                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 8650                let version = deserialize_version(get_document_diagnostics.buffer_version());
 8651                let buffer = lsp_store.update(&mut cx, |this, cx| {
 8652                    this.buffer_store.read(cx).get_existing(buffer_id)
 8653                })??;
 8654                buffer
 8655                    .update(&mut cx, |buffer, _| {
 8656                        buffer.wait_for_version(version.clone())
 8657                    })?
 8658                    .await?;
 8659                lsp_store.update(&mut cx, |lsp_store, cx| {
 8660                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 8661                    let key = LspKey {
 8662                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 8663                        server_queried: server_id,
 8664                    };
 8665                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 8666                    ) {
 8667                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 8668                            lsp_requests.clear();
 8669                        };
 8670                    }
 8671
 8672                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 8673                    existing_queries.insert(
 8674                        lsp_request_id,
 8675                        cx.spawn(async move |lsp_store, cx| {
 8676                            let diagnostics_pull = lsp_store
 8677                                .update(cx, |lsp_store, cx| {
 8678                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8679                                })
 8680                                .ok();
 8681                            if let Some(diagnostics_pull) = diagnostics_pull {
 8682                                match diagnostics_pull.await {
 8683                                    Ok(()) => {}
 8684                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 8685                                };
 8686                            }
 8687                        }),
 8688                    );
 8689                })?;
 8690            }
 8691            Request::InlayHints(inlay_hints) => {
 8692                let query_start = inlay_hints
 8693                    .start
 8694                    .clone()
 8695                    .and_then(deserialize_anchor)
 8696                    .context("invalid inlay hints range start")?;
 8697                let query_end = inlay_hints
 8698                    .end
 8699                    .clone()
 8700                    .and_then(deserialize_anchor)
 8701                    .context("invalid inlay hints range end")?;
 8702                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 8703                    &lsp_store,
 8704                    server_id,
 8705                    lsp_request_id,
 8706                    &inlay_hints,
 8707                    query_start..query_end,
 8708                    &mut cx,
 8709                )
 8710                .await
 8711                .context("preparing inlay hints request")?;
 8712                Self::query_lsp_locally::<InlayHints>(
 8713                    lsp_store,
 8714                    server_id,
 8715                    sender_id,
 8716                    lsp_request_id,
 8717                    inlay_hints,
 8718                    None,
 8719                    &mut cx,
 8720                )
 8721                .await
 8722                .context("querying for inlay hints")?
 8723            }
 8724        }
 8725        Ok(proto::Ack {})
 8726    }
 8727
 8728    async fn handle_lsp_query_response(
 8729        lsp_store: Entity<Self>,
 8730        envelope: TypedEnvelope<proto::LspQueryResponse>,
 8731        cx: AsyncApp,
 8732    ) -> Result<()> {
 8733        lsp_store.read_with(&cx, |lsp_store, _| {
 8734            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 8735                upstream_client.handle_lsp_response(envelope.clone());
 8736            }
 8737        })?;
 8738        Ok(())
 8739    }
 8740
 8741    async fn handle_apply_code_action(
 8742        this: Entity<Self>,
 8743        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 8744        mut cx: AsyncApp,
 8745    ) -> Result<proto::ApplyCodeActionResponse> {
 8746        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8747        let action =
 8748            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 8749        let apply_code_action = this.update(&mut cx, |this, cx| {
 8750            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8751            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 8752            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 8753        })??;
 8754
 8755        let project_transaction = apply_code_action.await?;
 8756        let project_transaction = this.update(&mut cx, |this, cx| {
 8757            this.buffer_store.update(cx, |buffer_store, cx| {
 8758                buffer_store.serialize_project_transaction_for_peer(
 8759                    project_transaction,
 8760                    sender_id,
 8761                    cx,
 8762                )
 8763            })
 8764        })?;
 8765        Ok(proto::ApplyCodeActionResponse {
 8766            transaction: Some(project_transaction),
 8767        })
 8768    }
 8769
 8770    async fn handle_register_buffer_with_language_servers(
 8771        this: Entity<Self>,
 8772        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 8773        mut cx: AsyncApp,
 8774    ) -> Result<proto::Ack> {
 8775        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8776        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 8777        this.update(&mut cx, |this, cx| {
 8778            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 8779                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 8780                    project_id: upstream_project_id,
 8781                    buffer_id: buffer_id.to_proto(),
 8782                    only_servers: envelope.payload.only_servers,
 8783                });
 8784            }
 8785
 8786            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 8787                anyhow::bail!("buffer is not open");
 8788            };
 8789
 8790            let handle = this.register_buffer_with_language_servers(
 8791                &buffer,
 8792                envelope
 8793                    .payload
 8794                    .only_servers
 8795                    .into_iter()
 8796                    .filter_map(|selector| {
 8797                        Some(match selector.selector? {
 8798                            proto::language_server_selector::Selector::ServerId(server_id) => {
 8799                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 8800                            }
 8801                            proto::language_server_selector::Selector::Name(name) => {
 8802                                LanguageServerSelector::Name(LanguageServerName(
 8803                                    SharedString::from(name),
 8804                                ))
 8805                            }
 8806                        })
 8807                    })
 8808                    .collect(),
 8809                false,
 8810                cx,
 8811            );
 8812            this.buffer_store().update(cx, |buffer_store, _| {
 8813                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 8814            });
 8815
 8816            Ok(())
 8817        })??;
 8818        Ok(proto::Ack {})
 8819    }
 8820
 8821    async fn handle_rename_project_entry(
 8822        this: Entity<Self>,
 8823        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 8824        mut cx: AsyncApp,
 8825    ) -> Result<proto::ProjectEntryResponse> {
 8826        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 8827        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 8828        let new_path =
 8829            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 8830
 8831        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 8832            .update(&mut cx, |this, cx| {
 8833                let (worktree, entry) = this
 8834                    .worktree_store
 8835                    .read(cx)
 8836                    .worktree_and_entry_for_id(entry_id, cx)?;
 8837                let new_worktree = this
 8838                    .worktree_store
 8839                    .read(cx)
 8840                    .worktree_for_id(new_worktree_id, cx)?;
 8841                Some((
 8842                    this.worktree_store.clone(),
 8843                    worktree,
 8844                    new_worktree,
 8845                    entry.clone(),
 8846                ))
 8847            })?
 8848            .context("worktree not found")?;
 8849        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 8850            (worktree.absolutize(&old_entry.path), worktree.id())
 8851        })?;
 8852        let new_abs_path =
 8853            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 8854
 8855        let _transaction = Self::will_rename_entry(
 8856            this.downgrade(),
 8857            old_worktree_id,
 8858            &old_abs_path,
 8859            &new_abs_path,
 8860            old_entry.is_dir(),
 8861            cx.clone(),
 8862        )
 8863        .await;
 8864        let response = WorktreeStore::handle_rename_project_entry(
 8865            worktree_store,
 8866            envelope.payload,
 8867            cx.clone(),
 8868        )
 8869        .await;
 8870        this.read_with(&cx, |this, _| {
 8871            this.did_rename_entry(
 8872                old_worktree_id,
 8873                &old_abs_path,
 8874                &new_abs_path,
 8875                old_entry.is_dir(),
 8876            );
 8877        })
 8878        .ok();
 8879        response
 8880    }
 8881
 8882    async fn handle_update_diagnostic_summary(
 8883        this: Entity<Self>,
 8884        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 8885        mut cx: AsyncApp,
 8886    ) -> Result<()> {
 8887        this.update(&mut cx, |lsp_store, cx| {
 8888            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 8889            let mut updated_diagnostics_paths = HashMap::default();
 8890            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8891            for message_summary in envelope
 8892                .payload
 8893                .summary
 8894                .into_iter()
 8895                .chain(envelope.payload.more_summaries)
 8896            {
 8897                let project_path = ProjectPath {
 8898                    worktree_id,
 8899                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 8900                };
 8901                let path = project_path.path.clone();
 8902                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 8903                let summary = DiagnosticSummary {
 8904                    error_count: message_summary.error_count as usize,
 8905                    warning_count: message_summary.warning_count as usize,
 8906                };
 8907
 8908                if summary.is_empty() {
 8909                    if let Some(worktree_summaries) =
 8910                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 8911                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 8912                    {
 8913                        summaries.remove(&server_id);
 8914                        if summaries.is_empty() {
 8915                            worktree_summaries.remove(&path);
 8916                        }
 8917                    }
 8918                } else {
 8919                    lsp_store
 8920                        .diagnostic_summaries
 8921                        .entry(worktree_id)
 8922                        .or_default()
 8923                        .entry(path)
 8924                        .or_default()
 8925                        .insert(server_id, summary);
 8926                }
 8927
 8928                if let Some((_, project_id)) = &lsp_store.downstream_client {
 8929                    match &mut diagnostics_summary {
 8930                        Some(diagnostics_summary) => {
 8931                            diagnostics_summary
 8932                                .more_summaries
 8933                                .push(proto::DiagnosticSummary {
 8934                                    path: project_path.path.as_ref().to_proto(),
 8935                                    language_server_id: server_id.0 as u64,
 8936                                    error_count: summary.error_count as u32,
 8937                                    warning_count: summary.warning_count as u32,
 8938                                })
 8939                        }
 8940                        None => {
 8941                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8942                                project_id: *project_id,
 8943                                worktree_id: worktree_id.to_proto(),
 8944                                summary: Some(proto::DiagnosticSummary {
 8945                                    path: project_path.path.as_ref().to_proto(),
 8946                                    language_server_id: server_id.0 as u64,
 8947                                    error_count: summary.error_count as u32,
 8948                                    warning_count: summary.warning_count as u32,
 8949                                }),
 8950                                more_summaries: Vec::new(),
 8951                            })
 8952                        }
 8953                    }
 8954                }
 8955                updated_diagnostics_paths
 8956                    .entry(server_id)
 8957                    .or_insert_with(Vec::new)
 8958                    .push(project_path);
 8959            }
 8960
 8961            if let Some((diagnostics_summary, (downstream_client, _))) =
 8962                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 8963            {
 8964                downstream_client.send(diagnostics_summary).log_err();
 8965            }
 8966            for (server_id, paths) in updated_diagnostics_paths {
 8967                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8968            }
 8969            Ok(())
 8970        })?
 8971    }
 8972
 8973    async fn handle_start_language_server(
 8974        lsp_store: Entity<Self>,
 8975        envelope: TypedEnvelope<proto::StartLanguageServer>,
 8976        mut cx: AsyncApp,
 8977    ) -> Result<()> {
 8978        let server = envelope.payload.server.context("invalid server")?;
 8979        let server_capabilities =
 8980            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 8981                .with_context(|| {
 8982                    format!(
 8983                        "incorrect server capabilities {}",
 8984                        envelope.payload.capabilities
 8985                    )
 8986                })?;
 8987        lsp_store.update(&mut cx, |lsp_store, cx| {
 8988            let server_id = LanguageServerId(server.id as usize);
 8989            let server_name = LanguageServerName::from_proto(server.name.clone());
 8990            lsp_store
 8991                .lsp_server_capabilities
 8992                .insert(server_id, server_capabilities);
 8993            lsp_store.language_server_statuses.insert(
 8994                server_id,
 8995                LanguageServerStatus {
 8996                    name: server_name.clone(),
 8997                    pending_work: Default::default(),
 8998                    has_pending_diagnostic_updates: false,
 8999                    progress_tokens: Default::default(),
 9000                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9001                },
 9002            );
 9003            cx.emit(LspStoreEvent::LanguageServerAdded(
 9004                server_id,
 9005                server_name,
 9006                server.worktree_id.map(WorktreeId::from_proto),
 9007            ));
 9008            cx.notify();
 9009        })?;
 9010        Ok(())
 9011    }
 9012
 9013    async fn handle_update_language_server(
 9014        lsp_store: Entity<Self>,
 9015        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9016        mut cx: AsyncApp,
 9017    ) -> Result<()> {
 9018        lsp_store.update(&mut cx, |lsp_store, cx| {
 9019            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9020
 9021            match envelope.payload.variant.context("invalid variant")? {
 9022                proto::update_language_server::Variant::WorkStart(payload) => {
 9023                    lsp_store.on_lsp_work_start(
 9024                        language_server_id,
 9025                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9026                            .context("invalid progress token value")?,
 9027                        LanguageServerProgress {
 9028                            title: payload.title,
 9029                            is_disk_based_diagnostics_progress: false,
 9030                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9031                            message: payload.message,
 9032                            percentage: payload.percentage.map(|p| p as usize),
 9033                            last_update_at: cx.background_executor().now(),
 9034                        },
 9035                        cx,
 9036                    );
 9037                }
 9038                proto::update_language_server::Variant::WorkProgress(payload) => {
 9039                    lsp_store.on_lsp_work_progress(
 9040                        language_server_id,
 9041                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9042                            .context("invalid progress token value")?,
 9043                        LanguageServerProgress {
 9044                            title: None,
 9045                            is_disk_based_diagnostics_progress: false,
 9046                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9047                            message: payload.message,
 9048                            percentage: payload.percentage.map(|p| p as usize),
 9049                            last_update_at: cx.background_executor().now(),
 9050                        },
 9051                        cx,
 9052                    );
 9053                }
 9054
 9055                proto::update_language_server::Variant::WorkEnd(payload) => {
 9056                    lsp_store.on_lsp_work_end(
 9057                        language_server_id,
 9058                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9059                            .context("invalid progress token value")?,
 9060                        cx,
 9061                    );
 9062                }
 9063
 9064                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9065                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9066                }
 9067
 9068                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9069                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9070                }
 9071
 9072                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9073                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9074                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9075                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9076                        language_server_id,
 9077                        name: envelope
 9078                            .payload
 9079                            .server_name
 9080                            .map(SharedString::new)
 9081                            .map(LanguageServerName),
 9082                        message: non_lsp,
 9083                    });
 9084                }
 9085            }
 9086
 9087            Ok(())
 9088        })?
 9089    }
 9090
 9091    async fn handle_language_server_log(
 9092        this: Entity<Self>,
 9093        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9094        mut cx: AsyncApp,
 9095    ) -> Result<()> {
 9096        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9097        let log_type = envelope
 9098            .payload
 9099            .log_type
 9100            .map(LanguageServerLogType::from_proto)
 9101            .context("invalid language server log type")?;
 9102
 9103        let message = envelope.payload.message;
 9104
 9105        this.update(&mut cx, |_, cx| {
 9106            cx.emit(LspStoreEvent::LanguageServerLog(
 9107                language_server_id,
 9108                log_type,
 9109                message,
 9110            ));
 9111        })
 9112    }
 9113
 9114    async fn handle_lsp_ext_cancel_flycheck(
 9115        lsp_store: Entity<Self>,
 9116        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9117        cx: AsyncApp,
 9118    ) -> Result<proto::Ack> {
 9119        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9120        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9121            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9122                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9123            } else {
 9124                None
 9125            }
 9126        })?;
 9127        if let Some(task) = task {
 9128            task.context("handling lsp ext cancel flycheck")?;
 9129        }
 9130
 9131        Ok(proto::Ack {})
 9132    }
 9133
 9134    async fn handle_lsp_ext_run_flycheck(
 9135        lsp_store: Entity<Self>,
 9136        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9137        mut cx: AsyncApp,
 9138    ) -> Result<proto::Ack> {
 9139        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9140        lsp_store.update(&mut cx, |lsp_store, cx| {
 9141            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9142                let text_document = if envelope.payload.current_file_only {
 9143                    let buffer_id = envelope
 9144                        .payload
 9145                        .buffer_id
 9146                        .map(|id| BufferId::new(id))
 9147                        .transpose()?;
 9148                    buffer_id
 9149                        .and_then(|buffer_id| {
 9150                            lsp_store
 9151                                .buffer_store()
 9152                                .read(cx)
 9153                                .get(buffer_id)
 9154                                .and_then(|buffer| {
 9155                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9156                                })
 9157                                .map(|path| make_text_document_identifier(&path))
 9158                        })
 9159                        .transpose()?
 9160                } else {
 9161                    None
 9162                };
 9163                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9164                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9165                )?;
 9166            }
 9167            anyhow::Ok(())
 9168        })??;
 9169
 9170        Ok(proto::Ack {})
 9171    }
 9172
 9173    async fn handle_lsp_ext_clear_flycheck(
 9174        lsp_store: Entity<Self>,
 9175        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9176        cx: AsyncApp,
 9177    ) -> Result<proto::Ack> {
 9178        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9179        lsp_store
 9180            .read_with(&cx, |lsp_store, _| {
 9181                if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9182                    Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9183                } else {
 9184                    None
 9185                }
 9186            })
 9187            .context("handling lsp ext clear flycheck")?;
 9188
 9189        Ok(proto::Ack {})
 9190    }
 9191
 9192    pub fn disk_based_diagnostics_started(
 9193        &mut self,
 9194        language_server_id: LanguageServerId,
 9195        cx: &mut Context<Self>,
 9196    ) {
 9197        if let Some(language_server_status) =
 9198            self.language_server_statuses.get_mut(&language_server_id)
 9199        {
 9200            language_server_status.has_pending_diagnostic_updates = true;
 9201        }
 9202
 9203        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9204        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9205            language_server_id,
 9206            name: self
 9207                .language_server_adapter_for_id(language_server_id)
 9208                .map(|adapter| adapter.name()),
 9209            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9210                Default::default(),
 9211            ),
 9212        })
 9213    }
 9214
 9215    pub fn disk_based_diagnostics_finished(
 9216        &mut self,
 9217        language_server_id: LanguageServerId,
 9218        cx: &mut Context<Self>,
 9219    ) {
 9220        if let Some(language_server_status) =
 9221            self.language_server_statuses.get_mut(&language_server_id)
 9222        {
 9223            language_server_status.has_pending_diagnostic_updates = false;
 9224        }
 9225
 9226        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9227        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9228            language_server_id,
 9229            name: self
 9230                .language_server_adapter_for_id(language_server_id)
 9231                .map(|adapter| adapter.name()),
 9232            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9233                Default::default(),
 9234            ),
 9235        })
 9236    }
 9237
 9238    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9239    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9240    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9241    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9242    // the language server might take some time to publish diagnostics.
 9243    fn simulate_disk_based_diagnostics_events_if_needed(
 9244        &mut self,
 9245        language_server_id: LanguageServerId,
 9246        cx: &mut Context<Self>,
 9247    ) {
 9248        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9249
 9250        let Some(LanguageServerState::Running {
 9251            simulate_disk_based_diagnostics_completion,
 9252            adapter,
 9253            ..
 9254        }) = self
 9255            .as_local_mut()
 9256            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9257        else {
 9258            return;
 9259        };
 9260
 9261        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9262            return;
 9263        }
 9264
 9265        let prev_task =
 9266            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9267                cx.background_executor()
 9268                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9269                    .await;
 9270
 9271                this.update(cx, |this, cx| {
 9272                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9273
 9274                    if let Some(LanguageServerState::Running {
 9275                        simulate_disk_based_diagnostics_completion,
 9276                        ..
 9277                    }) = this.as_local_mut().and_then(|local_store| {
 9278                        local_store.language_servers.get_mut(&language_server_id)
 9279                    }) {
 9280                        *simulate_disk_based_diagnostics_completion = None;
 9281                    }
 9282                })
 9283                .ok();
 9284            }));
 9285
 9286        if prev_task.is_none() {
 9287            self.disk_based_diagnostics_started(language_server_id, cx);
 9288        }
 9289    }
 9290
 9291    pub fn language_server_statuses(
 9292        &self,
 9293    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9294        self.language_server_statuses
 9295            .iter()
 9296            .map(|(key, value)| (*key, value))
 9297    }
 9298
 9299    pub(super) fn did_rename_entry(
 9300        &self,
 9301        worktree_id: WorktreeId,
 9302        old_path: &Path,
 9303        new_path: &Path,
 9304        is_dir: bool,
 9305    ) {
 9306        maybe!({
 9307            let local_store = self.as_local()?;
 9308
 9309            let old_uri = lsp::Uri::from_file_path(old_path)
 9310                .ok()
 9311                .map(|uri| uri.to_string())?;
 9312            let new_uri = lsp::Uri::from_file_path(new_path)
 9313                .ok()
 9314                .map(|uri| uri.to_string())?;
 9315
 9316            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9317                let Some(filter) = local_store
 9318                    .language_server_paths_watched_for_rename
 9319                    .get(&language_server.server_id())
 9320                else {
 9321                    continue;
 9322                };
 9323
 9324                if filter.should_send_did_rename(&old_uri, is_dir) {
 9325                    language_server
 9326                        .notify::<DidRenameFiles>(RenameFilesParams {
 9327                            files: vec![FileRename {
 9328                                old_uri: old_uri.clone(),
 9329                                new_uri: new_uri.clone(),
 9330                            }],
 9331                        })
 9332                        .ok();
 9333                }
 9334            }
 9335            Some(())
 9336        });
 9337    }
 9338
 9339    pub(super) fn will_rename_entry(
 9340        this: WeakEntity<Self>,
 9341        worktree_id: WorktreeId,
 9342        old_path: &Path,
 9343        new_path: &Path,
 9344        is_dir: bool,
 9345        cx: AsyncApp,
 9346    ) -> Task<ProjectTransaction> {
 9347        let old_uri = lsp::Uri::from_file_path(old_path)
 9348            .ok()
 9349            .map(|uri| uri.to_string());
 9350        let new_uri = lsp::Uri::from_file_path(new_path)
 9351            .ok()
 9352            .map(|uri| uri.to_string());
 9353        cx.spawn(async move |cx| {
 9354            let mut tasks = vec![];
 9355            this.update(cx, |this, cx| {
 9356                let local_store = this.as_local()?;
 9357                let old_uri = old_uri?;
 9358                let new_uri = new_uri?;
 9359                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9360                    let Some(filter) = local_store
 9361                        .language_server_paths_watched_for_rename
 9362                        .get(&language_server.server_id())
 9363                    else {
 9364                        continue;
 9365                    };
 9366
 9367                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9368                        let apply_edit = cx.spawn({
 9369                            let old_uri = old_uri.clone();
 9370                            let new_uri = new_uri.clone();
 9371                            let language_server = language_server.clone();
 9372                            async move |this, cx| {
 9373                                let edit = language_server
 9374                                    .request::<WillRenameFiles>(RenameFilesParams {
 9375                                        files: vec![FileRename { old_uri, new_uri }],
 9376                                    })
 9377                                    .await
 9378                                    .into_response()
 9379                                    .context("will rename files")
 9380                                    .log_err()
 9381                                    .flatten()?;
 9382
 9383                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9384                                    this.upgrade()?,
 9385                                    edit,
 9386                                    false,
 9387                                    language_server.clone(),
 9388                                    cx,
 9389                                )
 9390                                .await
 9391                                .ok()?;
 9392                                Some(transaction)
 9393                            }
 9394                        });
 9395                        tasks.push(apply_edit);
 9396                    }
 9397                }
 9398                Some(())
 9399            })
 9400            .ok()
 9401            .flatten();
 9402            let mut merged_transaction = ProjectTransaction::default();
 9403            for task in tasks {
 9404                // Await on tasks sequentially so that the order of application of edits is deterministic
 9405                // (at least with regards to the order of registration of language servers)
 9406                if let Some(transaction) = task.await {
 9407                    for (buffer, buffer_transaction) in transaction.0 {
 9408                        merged_transaction.0.insert(buffer, buffer_transaction);
 9409                    }
 9410                }
 9411            }
 9412            merged_transaction
 9413        })
 9414    }
 9415
 9416    fn lsp_notify_abs_paths_changed(
 9417        &mut self,
 9418        server_id: LanguageServerId,
 9419        changes: Vec<PathEvent>,
 9420    ) {
 9421        maybe!({
 9422            let server = self.language_server_for_id(server_id)?;
 9423            let changes = changes
 9424                .into_iter()
 9425                .filter_map(|event| {
 9426                    let typ = match event.kind? {
 9427                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9428                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9429                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9430                    };
 9431                    Some(lsp::FileEvent {
 9432                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9433                        typ,
 9434                    })
 9435                })
 9436                .collect::<Vec<_>>();
 9437            if !changes.is_empty() {
 9438                server
 9439                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9440                        lsp::DidChangeWatchedFilesParams { changes },
 9441                    )
 9442                    .ok();
 9443            }
 9444            Some(())
 9445        });
 9446    }
 9447
 9448    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9449        self.as_local()?.language_server_for_id(id)
 9450    }
 9451
 9452    fn on_lsp_progress(
 9453        &mut self,
 9454        progress_params: lsp::ProgressParams,
 9455        language_server_id: LanguageServerId,
 9456        disk_based_diagnostics_progress_token: Option<String>,
 9457        cx: &mut Context<Self>,
 9458    ) {
 9459        match progress_params.value {
 9460            lsp::ProgressParamsValue::WorkDone(progress) => {
 9461                self.handle_work_done_progress(
 9462                    progress,
 9463                    language_server_id,
 9464                    disk_based_diagnostics_progress_token,
 9465                    ProgressToken::from_lsp(progress_params.token),
 9466                    cx,
 9467                );
 9468            }
 9469            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9470                let identifier = match progress_params.token {
 9471                    lsp::NumberOrString::Number(_) => None,
 9472                    lsp::NumberOrString::String(token) => token
 9473                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9474                        .map(|(_, id)| id.to_owned()),
 9475                };
 9476                if let Some(LanguageServerState::Running {
 9477                    workspace_diagnostics_refresh_tasks,
 9478                    ..
 9479                }) = self
 9480                    .as_local_mut()
 9481                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9482                    && let Some(workspace_diagnostics) =
 9483                        workspace_diagnostics_refresh_tasks.get_mut(&identifier)
 9484                {
 9485                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9486                    self.apply_workspace_diagnostic_report(language_server_id, report, cx)
 9487                }
 9488            }
 9489        }
 9490    }
 9491
 9492    fn handle_work_done_progress(
 9493        &mut self,
 9494        progress: lsp::WorkDoneProgress,
 9495        language_server_id: LanguageServerId,
 9496        disk_based_diagnostics_progress_token: Option<String>,
 9497        token: ProgressToken,
 9498        cx: &mut Context<Self>,
 9499    ) {
 9500        let language_server_status =
 9501            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9502                status
 9503            } else {
 9504                return;
 9505            };
 9506
 9507        if !language_server_status.progress_tokens.contains(&token) {
 9508            return;
 9509        }
 9510
 9511        let is_disk_based_diagnostics_progress =
 9512            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9513                (&disk_based_diagnostics_progress_token, &token)
 9514            {
 9515                token.starts_with(disk_based_token)
 9516            } else {
 9517                false
 9518            };
 9519
 9520        match progress {
 9521            lsp::WorkDoneProgress::Begin(report) => {
 9522                if is_disk_based_diagnostics_progress {
 9523                    self.disk_based_diagnostics_started(language_server_id, cx);
 9524                }
 9525                self.on_lsp_work_start(
 9526                    language_server_id,
 9527                    token.clone(),
 9528                    LanguageServerProgress {
 9529                        title: Some(report.title),
 9530                        is_disk_based_diagnostics_progress,
 9531                        is_cancellable: report.cancellable.unwrap_or(false),
 9532                        message: report.message.clone(),
 9533                        percentage: report.percentage.map(|p| p as usize),
 9534                        last_update_at: cx.background_executor().now(),
 9535                    },
 9536                    cx,
 9537                );
 9538            }
 9539            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9540                language_server_id,
 9541                token,
 9542                LanguageServerProgress {
 9543                    title: None,
 9544                    is_disk_based_diagnostics_progress,
 9545                    is_cancellable: report.cancellable.unwrap_or(false),
 9546                    message: report.message,
 9547                    percentage: report.percentage.map(|p| p as usize),
 9548                    last_update_at: cx.background_executor().now(),
 9549                },
 9550                cx,
 9551            ),
 9552            lsp::WorkDoneProgress::End(_) => {
 9553                language_server_status.progress_tokens.remove(&token);
 9554                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9555                if is_disk_based_diagnostics_progress {
 9556                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9557                }
 9558            }
 9559        }
 9560    }
 9561
 9562    fn on_lsp_work_start(
 9563        &mut self,
 9564        language_server_id: LanguageServerId,
 9565        token: ProgressToken,
 9566        progress: LanguageServerProgress,
 9567        cx: &mut Context<Self>,
 9568    ) {
 9569        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9570            status.pending_work.insert(token.clone(), progress.clone());
 9571            cx.notify();
 9572        }
 9573        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9574            language_server_id,
 9575            name: self
 9576                .language_server_adapter_for_id(language_server_id)
 9577                .map(|adapter| adapter.name()),
 9578            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9579                token: Some(token.to_proto()),
 9580                title: progress.title,
 9581                message: progress.message,
 9582                percentage: progress.percentage.map(|p| p as u32),
 9583                is_cancellable: Some(progress.is_cancellable),
 9584            }),
 9585        })
 9586    }
 9587
 9588    fn on_lsp_work_progress(
 9589        &mut self,
 9590        language_server_id: LanguageServerId,
 9591        token: ProgressToken,
 9592        progress: LanguageServerProgress,
 9593        cx: &mut Context<Self>,
 9594    ) {
 9595        let mut did_update = false;
 9596        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9597            match status.pending_work.entry(token.clone()) {
 9598                btree_map::Entry::Vacant(entry) => {
 9599                    entry.insert(progress.clone());
 9600                    did_update = true;
 9601                }
 9602                btree_map::Entry::Occupied(mut entry) => {
 9603                    let entry = entry.get_mut();
 9604                    if (progress.last_update_at - entry.last_update_at)
 9605                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9606                    {
 9607                        entry.last_update_at = progress.last_update_at;
 9608                        if progress.message.is_some() {
 9609                            entry.message = progress.message.clone();
 9610                        }
 9611                        if progress.percentage.is_some() {
 9612                            entry.percentage = progress.percentage;
 9613                        }
 9614                        if progress.is_cancellable != entry.is_cancellable {
 9615                            entry.is_cancellable = progress.is_cancellable;
 9616                        }
 9617                        did_update = true;
 9618                    }
 9619                }
 9620            }
 9621        }
 9622
 9623        if did_update {
 9624            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9625                language_server_id,
 9626                name: self
 9627                    .language_server_adapter_for_id(language_server_id)
 9628                    .map(|adapter| adapter.name()),
 9629                message: proto::update_language_server::Variant::WorkProgress(
 9630                    proto::LspWorkProgress {
 9631                        token: Some(token.to_proto()),
 9632                        message: progress.message,
 9633                        percentage: progress.percentage.map(|p| p as u32),
 9634                        is_cancellable: Some(progress.is_cancellable),
 9635                    },
 9636                ),
 9637            })
 9638        }
 9639    }
 9640
 9641    fn on_lsp_work_end(
 9642        &mut self,
 9643        language_server_id: LanguageServerId,
 9644        token: ProgressToken,
 9645        cx: &mut Context<Self>,
 9646    ) {
 9647        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9648            if let Some(work) = status.pending_work.remove(&token)
 9649                && !work.is_disk_based_diagnostics_progress
 9650            {
 9651                cx.emit(LspStoreEvent::RefreshInlayHints {
 9652                    server_id: language_server_id,
 9653                    request_id: None,
 9654                });
 9655            }
 9656            cx.notify();
 9657        }
 9658
 9659        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9660            language_server_id,
 9661            name: self
 9662                .language_server_adapter_for_id(language_server_id)
 9663                .map(|adapter| adapter.name()),
 9664            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
 9665                token: Some(token.to_proto()),
 9666            }),
 9667        })
 9668    }
 9669
 9670    pub async fn handle_resolve_completion_documentation(
 9671        this: Entity<Self>,
 9672        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
 9673        mut cx: AsyncApp,
 9674    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
 9675        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
 9676
 9677        let completion = this
 9678            .read_with(&cx, |this, cx| {
 9679                let id = LanguageServerId(envelope.payload.language_server_id as usize);
 9680                let server = this
 9681                    .language_server_for_id(id)
 9682                    .with_context(|| format!("No language server {id}"))?;
 9683
 9684                anyhow::Ok(cx.background_spawn(async move {
 9685                    let can_resolve = server
 9686                        .capabilities()
 9687                        .completion_provider
 9688                        .as_ref()
 9689                        .and_then(|options| options.resolve_provider)
 9690                        .unwrap_or(false);
 9691                    if can_resolve {
 9692                        server
 9693                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
 9694                            .await
 9695                            .into_response()
 9696                            .context("resolve completion item")
 9697                    } else {
 9698                        anyhow::Ok(lsp_completion)
 9699                    }
 9700                }))
 9701            })??
 9702            .await?;
 9703
 9704        let mut documentation_is_markdown = false;
 9705        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
 9706        let documentation = match completion.documentation {
 9707            Some(lsp::Documentation::String(text)) => text,
 9708
 9709            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
 9710                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
 9711                value
 9712            }
 9713
 9714            _ => String::new(),
 9715        };
 9716
 9717        // If we have a new buffer_id, that means we're talking to a new client
 9718        // and want to check for new text_edits in the completion too.
 9719        let mut old_replace_start = None;
 9720        let mut old_replace_end = None;
 9721        let mut old_insert_start = None;
 9722        let mut old_insert_end = None;
 9723        let mut new_text = String::default();
 9724        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
 9725            let buffer_snapshot = this.update(&mut cx, |this, cx| {
 9726                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9727                anyhow::Ok(buffer.read(cx).snapshot())
 9728            })??;
 9729
 9730            if let Some(text_edit) = completion.text_edit.as_ref() {
 9731                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
 9732
 9733                if let Some(mut edit) = edit {
 9734                    LineEnding::normalize(&mut edit.new_text);
 9735
 9736                    new_text = edit.new_text;
 9737                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
 9738                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
 9739                    if let Some(insert_range) = edit.insert_range {
 9740                        old_insert_start = Some(serialize_anchor(&insert_range.start));
 9741                        old_insert_end = Some(serialize_anchor(&insert_range.end));
 9742                    }
 9743                }
 9744            }
 9745        }
 9746
 9747        Ok(proto::ResolveCompletionDocumentationResponse {
 9748            documentation,
 9749            documentation_is_markdown,
 9750            old_replace_start,
 9751            old_replace_end,
 9752            new_text,
 9753            lsp_completion,
 9754            old_insert_start,
 9755            old_insert_end,
 9756        })
 9757    }
 9758
 9759    async fn handle_on_type_formatting(
 9760        this: Entity<Self>,
 9761        envelope: TypedEnvelope<proto::OnTypeFormatting>,
 9762        mut cx: AsyncApp,
 9763    ) -> Result<proto::OnTypeFormattingResponse> {
 9764        let on_type_formatting = this.update(&mut cx, |this, cx| {
 9765            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9766            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9767            let position = envelope
 9768                .payload
 9769                .position
 9770                .and_then(deserialize_anchor)
 9771                .context("invalid position")?;
 9772            anyhow::Ok(this.apply_on_type_formatting(
 9773                buffer,
 9774                position,
 9775                envelope.payload.trigger.clone(),
 9776                cx,
 9777            ))
 9778        })??;
 9779
 9780        let transaction = on_type_formatting
 9781            .await?
 9782            .as_ref()
 9783            .map(language::proto::serialize_transaction);
 9784        Ok(proto::OnTypeFormattingResponse { transaction })
 9785    }
 9786
 9787    async fn handle_refresh_inlay_hints(
 9788        lsp_store: Entity<Self>,
 9789        envelope: TypedEnvelope<proto::RefreshInlayHints>,
 9790        mut cx: AsyncApp,
 9791    ) -> Result<proto::Ack> {
 9792        lsp_store.update(&mut cx, |_, cx| {
 9793            cx.emit(LspStoreEvent::RefreshInlayHints {
 9794                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
 9795                request_id: envelope.payload.request_id.map(|id| id as usize),
 9796            });
 9797        })?;
 9798        Ok(proto::Ack {})
 9799    }
 9800
 9801    async fn handle_pull_workspace_diagnostics(
 9802        lsp_store: Entity<Self>,
 9803        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
 9804        mut cx: AsyncApp,
 9805    ) -> Result<proto::Ack> {
 9806        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
 9807        lsp_store.update(&mut cx, |lsp_store, _| {
 9808            lsp_store.pull_workspace_diagnostics(server_id);
 9809        })?;
 9810        Ok(proto::Ack {})
 9811    }
 9812
 9813    async fn handle_get_color_presentation(
 9814        lsp_store: Entity<Self>,
 9815        envelope: TypedEnvelope<proto::GetColorPresentation>,
 9816        mut cx: AsyncApp,
 9817    ) -> Result<proto::GetColorPresentationResponse> {
 9818        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9819        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9820            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9821        })??;
 9822
 9823        let color = envelope
 9824            .payload
 9825            .color
 9826            .context("invalid color resolve request")?;
 9827        let start = color
 9828            .lsp_range_start
 9829            .context("invalid color resolve request")?;
 9830        let end = color
 9831            .lsp_range_end
 9832            .context("invalid color resolve request")?;
 9833
 9834        let color = DocumentColor {
 9835            lsp_range: lsp::Range {
 9836                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
 9837                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
 9838            },
 9839            color: lsp::Color {
 9840                red: color.red,
 9841                green: color.green,
 9842                blue: color.blue,
 9843                alpha: color.alpha,
 9844            },
 9845            resolved: false,
 9846            color_presentations: Vec::new(),
 9847        };
 9848        let resolved_color = lsp_store
 9849            .update(&mut cx, |lsp_store, cx| {
 9850                lsp_store.resolve_color_presentation(
 9851                    color,
 9852                    buffer.clone(),
 9853                    LanguageServerId(envelope.payload.server_id as usize),
 9854                    cx,
 9855                )
 9856            })?
 9857            .await
 9858            .context("resolving color presentation")?;
 9859
 9860        Ok(proto::GetColorPresentationResponse {
 9861            presentations: resolved_color
 9862                .color_presentations
 9863                .into_iter()
 9864                .map(|presentation| proto::ColorPresentation {
 9865                    label: presentation.label.to_string(),
 9866                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
 9867                    additional_text_edits: presentation
 9868                        .additional_text_edits
 9869                        .into_iter()
 9870                        .map(serialize_lsp_edit)
 9871                        .collect(),
 9872                })
 9873                .collect(),
 9874        })
 9875    }
 9876
 9877    async fn handle_resolve_inlay_hint(
 9878        lsp_store: Entity<Self>,
 9879        envelope: TypedEnvelope<proto::ResolveInlayHint>,
 9880        mut cx: AsyncApp,
 9881    ) -> Result<proto::ResolveInlayHintResponse> {
 9882        let proto_hint = envelope
 9883            .payload
 9884            .hint
 9885            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
 9886        let hint = InlayHints::proto_to_project_hint(proto_hint)
 9887            .context("resolved proto inlay hint conversion")?;
 9888        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9889            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9890            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9891        })??;
 9892        let response_hint = lsp_store
 9893            .update(&mut cx, |lsp_store, cx| {
 9894                lsp_store.resolve_inlay_hint(
 9895                    hint,
 9896                    buffer,
 9897                    LanguageServerId(envelope.payload.language_server_id as usize),
 9898                    cx,
 9899                )
 9900            })?
 9901            .await
 9902            .context("inlay hints fetch")?;
 9903        Ok(proto::ResolveInlayHintResponse {
 9904            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
 9905        })
 9906    }
 9907
 9908    async fn handle_refresh_code_lens(
 9909        this: Entity<Self>,
 9910        _: TypedEnvelope<proto::RefreshCodeLens>,
 9911        mut cx: AsyncApp,
 9912    ) -> Result<proto::Ack> {
 9913        this.update(&mut cx, |_, cx| {
 9914            cx.emit(LspStoreEvent::RefreshCodeLens);
 9915        })?;
 9916        Ok(proto::Ack {})
 9917    }
 9918
 9919    async fn handle_open_buffer_for_symbol(
 9920        this: Entity<Self>,
 9921        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
 9922        mut cx: AsyncApp,
 9923    ) -> Result<proto::OpenBufferForSymbolResponse> {
 9924        let peer_id = envelope.original_sender_id().unwrap_or_default();
 9925        let symbol = envelope.payload.symbol.context("invalid symbol")?;
 9926        let symbol = Self::deserialize_symbol(symbol)?;
 9927        this.read_with(&cx, |this, _| {
 9928            if let SymbolLocation::OutsideProject {
 9929                abs_path,
 9930                signature,
 9931            } = &symbol.path
 9932            {
 9933                let new_signature = this.symbol_signature(&abs_path);
 9934                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
 9935            }
 9936            Ok(())
 9937        })??;
 9938        let buffer = this
 9939            .update(&mut cx, |this, cx| {
 9940                this.open_buffer_for_symbol(
 9941                    &Symbol {
 9942                        language_server_name: symbol.language_server_name,
 9943                        source_worktree_id: symbol.source_worktree_id,
 9944                        source_language_server_id: symbol.source_language_server_id,
 9945                        path: symbol.path,
 9946                        name: symbol.name,
 9947                        kind: symbol.kind,
 9948                        range: symbol.range,
 9949                        label: CodeLabel::default(),
 9950                    },
 9951                    cx,
 9952                )
 9953            })?
 9954            .await?;
 9955
 9956        this.update(&mut cx, |this, cx| {
 9957            let is_private = buffer
 9958                .read(cx)
 9959                .file()
 9960                .map(|f| f.is_private())
 9961                .unwrap_or_default();
 9962            if is_private {
 9963                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
 9964            } else {
 9965                this.buffer_store
 9966                    .update(cx, |buffer_store, cx| {
 9967                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
 9968                    })
 9969                    .detach_and_log_err(cx);
 9970                let buffer_id = buffer.read(cx).remote_id().to_proto();
 9971                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
 9972            }
 9973        })?
 9974    }
 9975
 9976    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
 9977        let mut hasher = Sha256::new();
 9978        hasher.update(abs_path.to_string_lossy().as_bytes());
 9979        hasher.update(self.nonce.to_be_bytes());
 9980        hasher.finalize().as_slice().try_into().unwrap()
 9981    }
 9982
 9983    pub async fn handle_get_project_symbols(
 9984        this: Entity<Self>,
 9985        envelope: TypedEnvelope<proto::GetProjectSymbols>,
 9986        mut cx: AsyncApp,
 9987    ) -> Result<proto::GetProjectSymbolsResponse> {
 9988        let symbols = this
 9989            .update(&mut cx, |this, cx| {
 9990                this.symbols(&envelope.payload.query, cx)
 9991            })?
 9992            .await?;
 9993
 9994        Ok(proto::GetProjectSymbolsResponse {
 9995            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
 9996        })
 9997    }
 9998
 9999    pub async fn handle_restart_language_servers(
10000        this: Entity<Self>,
10001        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10002        mut cx: AsyncApp,
10003    ) -> Result<proto::Ack> {
10004        this.update(&mut cx, |lsp_store, cx| {
10005            let buffers =
10006                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10007            lsp_store.restart_language_servers_for_buffers(
10008                buffers,
10009                envelope
10010                    .payload
10011                    .only_servers
10012                    .into_iter()
10013                    .filter_map(|selector| {
10014                        Some(match selector.selector? {
10015                            proto::language_server_selector::Selector::ServerId(server_id) => {
10016                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10017                            }
10018                            proto::language_server_selector::Selector::Name(name) => {
10019                                LanguageServerSelector::Name(LanguageServerName(
10020                                    SharedString::from(name),
10021                                ))
10022                            }
10023                        })
10024                    })
10025                    .collect(),
10026                cx,
10027            );
10028        })?;
10029
10030        Ok(proto::Ack {})
10031    }
10032
10033    pub async fn handle_stop_language_servers(
10034        lsp_store: Entity<Self>,
10035        envelope: TypedEnvelope<proto::StopLanguageServers>,
10036        mut cx: AsyncApp,
10037    ) -> Result<proto::Ack> {
10038        lsp_store.update(&mut cx, |lsp_store, cx| {
10039            if envelope.payload.all
10040                && envelope.payload.also_servers.is_empty()
10041                && envelope.payload.buffer_ids.is_empty()
10042            {
10043                lsp_store.stop_all_language_servers(cx);
10044            } else {
10045                let buffers =
10046                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10047                lsp_store
10048                    .stop_language_servers_for_buffers(
10049                        buffers,
10050                        envelope
10051                            .payload
10052                            .also_servers
10053                            .into_iter()
10054                            .filter_map(|selector| {
10055                                Some(match selector.selector? {
10056                                    proto::language_server_selector::Selector::ServerId(
10057                                        server_id,
10058                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10059                                        server_id,
10060                                    )),
10061                                    proto::language_server_selector::Selector::Name(name) => {
10062                                        LanguageServerSelector::Name(LanguageServerName(
10063                                            SharedString::from(name),
10064                                        ))
10065                                    }
10066                                })
10067                            })
10068                            .collect(),
10069                        cx,
10070                    )
10071                    .detach_and_log_err(cx);
10072            }
10073        })?;
10074
10075        Ok(proto::Ack {})
10076    }
10077
10078    pub async fn handle_cancel_language_server_work(
10079        lsp_store: Entity<Self>,
10080        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10081        mut cx: AsyncApp,
10082    ) -> Result<proto::Ack> {
10083        lsp_store.update(&mut cx, |lsp_store, cx| {
10084            if let Some(work) = envelope.payload.work {
10085                match work {
10086                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10087                        let buffers =
10088                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10089                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10090                    }
10091                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10092                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10093                        let token = work
10094                            .token
10095                            .map(|token| {
10096                                ProgressToken::from_proto(token)
10097                                    .context("invalid work progress token")
10098                            })
10099                            .transpose()?;
10100                        lsp_store.cancel_language_server_work(server_id, token, cx);
10101                    }
10102                }
10103            }
10104            anyhow::Ok(())
10105        })??;
10106
10107        Ok(proto::Ack {})
10108    }
10109
10110    fn buffer_ids_to_buffers(
10111        &mut self,
10112        buffer_ids: impl Iterator<Item = u64>,
10113        cx: &mut Context<Self>,
10114    ) -> Vec<Entity<Buffer>> {
10115        buffer_ids
10116            .into_iter()
10117            .flat_map(|buffer_id| {
10118                self.buffer_store
10119                    .read(cx)
10120                    .get(BufferId::new(buffer_id).log_err()?)
10121            })
10122            .collect::<Vec<_>>()
10123    }
10124
10125    async fn handle_apply_additional_edits_for_completion(
10126        this: Entity<Self>,
10127        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10128        mut cx: AsyncApp,
10129    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10130        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10131            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10132            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10133            let completion = Self::deserialize_completion(
10134                envelope.payload.completion.context("invalid completion")?,
10135            )?;
10136            anyhow::Ok((buffer, completion))
10137        })??;
10138
10139        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10140            this.apply_additional_edits_for_completion(
10141                buffer,
10142                Rc::new(RefCell::new(Box::new([Completion {
10143                    replace_range: completion.replace_range,
10144                    new_text: completion.new_text,
10145                    source: completion.source,
10146                    documentation: None,
10147                    label: CodeLabel::default(),
10148                    insert_text_mode: None,
10149                    icon_path: None,
10150                    confirm: None,
10151                }]))),
10152                0,
10153                false,
10154                cx,
10155            )
10156        })?;
10157
10158        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10159            transaction: apply_additional_edits
10160                .await?
10161                .as_ref()
10162                .map(language::proto::serialize_transaction),
10163        })
10164    }
10165
10166    pub fn last_formatting_failure(&self) -> Option<&str> {
10167        self.last_formatting_failure.as_deref()
10168    }
10169
10170    pub fn reset_last_formatting_failure(&mut self) {
10171        self.last_formatting_failure = None;
10172    }
10173
10174    pub fn environment_for_buffer(
10175        &self,
10176        buffer: &Entity<Buffer>,
10177        cx: &mut Context<Self>,
10178    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10179        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10180            environment.update(cx, |env, cx| {
10181                env.buffer_environment(buffer, &self.worktree_store, cx)
10182            })
10183        } else {
10184            Task::ready(None).shared()
10185        }
10186    }
10187
10188    pub fn format(
10189        &mut self,
10190        buffers: HashSet<Entity<Buffer>>,
10191        target: LspFormatTarget,
10192        push_to_history: bool,
10193        trigger: FormatTrigger,
10194        cx: &mut Context<Self>,
10195    ) -> Task<anyhow::Result<ProjectTransaction>> {
10196        let logger = zlog::scoped!("format");
10197        if self.as_local().is_some() {
10198            zlog::trace!(logger => "Formatting locally");
10199            let logger = zlog::scoped!(logger => "local");
10200            let buffers = buffers
10201                .into_iter()
10202                .map(|buffer_handle| {
10203                    let buffer = buffer_handle.read(cx);
10204                    let buffer_abs_path = File::from_dyn(buffer.file())
10205                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10206
10207                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10208                })
10209                .collect::<Vec<_>>();
10210
10211            cx.spawn(async move |lsp_store, cx| {
10212                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10213
10214                for (handle, abs_path, id) in buffers {
10215                    let env = lsp_store
10216                        .update(cx, |lsp_store, cx| {
10217                            lsp_store.environment_for_buffer(&handle, cx)
10218                        })?
10219                        .await;
10220
10221                    let ranges = match &target {
10222                        LspFormatTarget::Buffers => None,
10223                        LspFormatTarget::Ranges(ranges) => {
10224                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10225                        }
10226                    };
10227
10228                    formattable_buffers.push(FormattableBuffer {
10229                        handle,
10230                        abs_path,
10231                        env,
10232                        ranges,
10233                    });
10234                }
10235                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10236
10237                let format_timer = zlog::time!(logger => "Formatting buffers");
10238                let result = LocalLspStore::format_locally(
10239                    lsp_store.clone(),
10240                    formattable_buffers,
10241                    push_to_history,
10242                    trigger,
10243                    logger,
10244                    cx,
10245                )
10246                .await;
10247                format_timer.end();
10248
10249                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10250
10251                lsp_store.update(cx, |lsp_store, _| {
10252                    lsp_store.update_last_formatting_failure(&result);
10253                })?;
10254
10255                result
10256            })
10257        } else if let Some((client, project_id)) = self.upstream_client() {
10258            zlog::trace!(logger => "Formatting remotely");
10259            let logger = zlog::scoped!(logger => "remote");
10260            // Don't support formatting ranges via remote
10261            match target {
10262                LspFormatTarget::Buffers => {}
10263                LspFormatTarget::Ranges(_) => {
10264                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10265                    return Task::ready(Ok(ProjectTransaction::default()));
10266                }
10267            }
10268
10269            let buffer_store = self.buffer_store();
10270            cx.spawn(async move |lsp_store, cx| {
10271                zlog::trace!(logger => "Sending remote format request");
10272                let request_timer = zlog::time!(logger => "remote format request");
10273                let result = client
10274                    .request(proto::FormatBuffers {
10275                        project_id,
10276                        trigger: trigger as i32,
10277                        buffer_ids: buffers
10278                            .iter()
10279                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10280                            .collect::<Result<_>>()?,
10281                    })
10282                    .await
10283                    .and_then(|result| result.transaction.context("missing transaction"));
10284                request_timer.end();
10285
10286                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10287
10288                lsp_store.update(cx, |lsp_store, _| {
10289                    lsp_store.update_last_formatting_failure(&result);
10290                })?;
10291
10292                let transaction_response = result?;
10293                let _timer = zlog::time!(logger => "deserializing project transaction");
10294                buffer_store
10295                    .update(cx, |buffer_store, cx| {
10296                        buffer_store.deserialize_project_transaction(
10297                            transaction_response,
10298                            push_to_history,
10299                            cx,
10300                        )
10301                    })?
10302                    .await
10303            })
10304        } else {
10305            zlog::trace!(logger => "Not formatting");
10306            Task::ready(Ok(ProjectTransaction::default()))
10307        }
10308    }
10309
10310    async fn handle_format_buffers(
10311        this: Entity<Self>,
10312        envelope: TypedEnvelope<proto::FormatBuffers>,
10313        mut cx: AsyncApp,
10314    ) -> Result<proto::FormatBuffersResponse> {
10315        let sender_id = envelope.original_sender_id().unwrap_or_default();
10316        let format = this.update(&mut cx, |this, cx| {
10317            let mut buffers = HashSet::default();
10318            for buffer_id in &envelope.payload.buffer_ids {
10319                let buffer_id = BufferId::new(*buffer_id)?;
10320                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10321            }
10322            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10323            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10324        })??;
10325
10326        let project_transaction = format.await?;
10327        let project_transaction = this.update(&mut cx, |this, cx| {
10328            this.buffer_store.update(cx, |buffer_store, cx| {
10329                buffer_store.serialize_project_transaction_for_peer(
10330                    project_transaction,
10331                    sender_id,
10332                    cx,
10333                )
10334            })
10335        })?;
10336        Ok(proto::FormatBuffersResponse {
10337            transaction: Some(project_transaction),
10338        })
10339    }
10340
10341    async fn handle_apply_code_action_kind(
10342        this: Entity<Self>,
10343        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10344        mut cx: AsyncApp,
10345    ) -> Result<proto::ApplyCodeActionKindResponse> {
10346        let sender_id = envelope.original_sender_id().unwrap_or_default();
10347        let format = this.update(&mut cx, |this, cx| {
10348            let mut buffers = HashSet::default();
10349            for buffer_id in &envelope.payload.buffer_ids {
10350                let buffer_id = BufferId::new(*buffer_id)?;
10351                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10352            }
10353            let kind = match envelope.payload.kind.as_str() {
10354                "" => CodeActionKind::EMPTY,
10355                "quickfix" => CodeActionKind::QUICKFIX,
10356                "refactor" => CodeActionKind::REFACTOR,
10357                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10358                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10359                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10360                "source" => CodeActionKind::SOURCE,
10361                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10362                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10363                _ => anyhow::bail!(
10364                    "Invalid code action kind {}",
10365                    envelope.payload.kind.as_str()
10366                ),
10367            };
10368            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10369        })??;
10370
10371        let project_transaction = format.await?;
10372        let project_transaction = this.update(&mut cx, |this, cx| {
10373            this.buffer_store.update(cx, |buffer_store, cx| {
10374                buffer_store.serialize_project_transaction_for_peer(
10375                    project_transaction,
10376                    sender_id,
10377                    cx,
10378                )
10379            })
10380        })?;
10381        Ok(proto::ApplyCodeActionKindResponse {
10382            transaction: Some(project_transaction),
10383        })
10384    }
10385
10386    async fn shutdown_language_server(
10387        server_state: Option<LanguageServerState>,
10388        name: LanguageServerName,
10389        cx: &mut AsyncApp,
10390    ) {
10391        let server = match server_state {
10392            Some(LanguageServerState::Starting { startup, .. }) => {
10393                let mut timer = cx
10394                    .background_executor()
10395                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10396                    .fuse();
10397
10398                select! {
10399                    server = startup.fuse() => server,
10400                    () = timer => {
10401                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10402                        None
10403                    },
10404                }
10405            }
10406
10407            Some(LanguageServerState::Running { server, .. }) => Some(server),
10408
10409            None => None,
10410        };
10411
10412        if let Some(server) = server
10413            && let Some(shutdown) = server.shutdown()
10414        {
10415            shutdown.await;
10416        }
10417    }
10418
10419    // Returns a list of all of the worktrees which no longer have a language server and the root path
10420    // for the stopped server
10421    fn stop_local_language_server(
10422        &mut self,
10423        server_id: LanguageServerId,
10424        cx: &mut Context<Self>,
10425    ) -> Task<()> {
10426        let local = match &mut self.mode {
10427            LspStoreMode::Local(local) => local,
10428            _ => {
10429                return Task::ready(());
10430            }
10431        };
10432
10433        // Remove this server ID from all entries in the given worktree.
10434        local
10435            .language_server_ids
10436            .retain(|_, state| state.id != server_id);
10437        self.buffer_store.update(cx, |buffer_store, cx| {
10438            for buffer in buffer_store.buffers() {
10439                buffer.update(cx, |buffer, cx| {
10440                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10441                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10442                });
10443            }
10444        });
10445
10446        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10447            summaries.retain(|path, summaries_by_server_id| {
10448                if summaries_by_server_id.remove(&server_id).is_some() {
10449                    if let Some((client, project_id)) = self.downstream_client.clone() {
10450                        client
10451                            .send(proto::UpdateDiagnosticSummary {
10452                                project_id,
10453                                worktree_id: worktree_id.to_proto(),
10454                                summary: Some(proto::DiagnosticSummary {
10455                                    path: path.as_ref().to_proto(),
10456                                    language_server_id: server_id.0 as u64,
10457                                    error_count: 0,
10458                                    warning_count: 0,
10459                                }),
10460                                more_summaries: Vec::new(),
10461                            })
10462                            .log_err();
10463                    }
10464                    !summaries_by_server_id.is_empty()
10465                } else {
10466                    true
10467                }
10468            });
10469        }
10470
10471        let local = self.as_local_mut().unwrap();
10472        for diagnostics in local.diagnostics.values_mut() {
10473            diagnostics.retain(|_, diagnostics_by_server_id| {
10474                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10475                    diagnostics_by_server_id.remove(ix);
10476                    !diagnostics_by_server_id.is_empty()
10477                } else {
10478                    true
10479                }
10480            });
10481        }
10482        local.language_server_watched_paths.remove(&server_id);
10483
10484        let server_state = local.language_servers.remove(&server_id);
10485        self.cleanup_lsp_data(server_id);
10486        let name = self
10487            .language_server_statuses
10488            .remove(&server_id)
10489            .map(|status| status.name)
10490            .or_else(|| {
10491                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10492                    Some(adapter.name())
10493                } else {
10494                    None
10495                }
10496            });
10497
10498        if let Some(name) = name {
10499            log::info!("stopping language server {name}");
10500            self.languages
10501                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10502            cx.notify();
10503
10504            return cx.spawn(async move |lsp_store, cx| {
10505                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10506                lsp_store
10507                    .update(cx, |lsp_store, cx| {
10508                        lsp_store
10509                            .languages
10510                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10511                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10512                        cx.notify();
10513                    })
10514                    .ok();
10515            });
10516        }
10517
10518        if server_state.is_some() {
10519            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10520        }
10521        Task::ready(())
10522    }
10523
10524    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10525        if let Some((client, project_id)) = self.upstream_client() {
10526            let request = client.request(proto::StopLanguageServers {
10527                project_id,
10528                buffer_ids: Vec::new(),
10529                also_servers: Vec::new(),
10530                all: true,
10531            });
10532            cx.background_spawn(request).detach_and_log_err(cx);
10533        } else {
10534            let Some(local) = self.as_local_mut() else {
10535                return;
10536            };
10537            let language_servers_to_stop = local
10538                .language_server_ids
10539                .values()
10540                .map(|state| state.id)
10541                .collect();
10542            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10543            let tasks = language_servers_to_stop
10544                .into_iter()
10545                .map(|server| self.stop_local_language_server(server, cx))
10546                .collect::<Vec<_>>();
10547            cx.background_spawn(async move {
10548                futures::future::join_all(tasks).await;
10549            })
10550            .detach();
10551        }
10552    }
10553
10554    pub fn restart_language_servers_for_buffers(
10555        &mut self,
10556        buffers: Vec<Entity<Buffer>>,
10557        only_restart_servers: HashSet<LanguageServerSelector>,
10558        cx: &mut Context<Self>,
10559    ) {
10560        if let Some((client, project_id)) = self.upstream_client() {
10561            let request = client.request(proto::RestartLanguageServers {
10562                project_id,
10563                buffer_ids: buffers
10564                    .into_iter()
10565                    .map(|b| b.read(cx).remote_id().to_proto())
10566                    .collect(),
10567                only_servers: only_restart_servers
10568                    .into_iter()
10569                    .map(|selector| {
10570                        let selector = match selector {
10571                            LanguageServerSelector::Id(language_server_id) => {
10572                                proto::language_server_selector::Selector::ServerId(
10573                                    language_server_id.to_proto(),
10574                                )
10575                            }
10576                            LanguageServerSelector::Name(language_server_name) => {
10577                                proto::language_server_selector::Selector::Name(
10578                                    language_server_name.to_string(),
10579                                )
10580                            }
10581                        };
10582                        proto::LanguageServerSelector {
10583                            selector: Some(selector),
10584                        }
10585                    })
10586                    .collect(),
10587                all: false,
10588            });
10589            cx.background_spawn(request).detach_and_log_err(cx);
10590        } else {
10591            let stop_task = if only_restart_servers.is_empty() {
10592                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10593            } else {
10594                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10595            };
10596            cx.spawn(async move |lsp_store, cx| {
10597                stop_task.await;
10598                lsp_store
10599                    .update(cx, |lsp_store, cx| {
10600                        for buffer in buffers {
10601                            lsp_store.register_buffer_with_language_servers(
10602                                &buffer,
10603                                only_restart_servers.clone(),
10604                                true,
10605                                cx,
10606                            );
10607                        }
10608                    })
10609                    .ok()
10610            })
10611            .detach();
10612        }
10613    }
10614
10615    pub fn stop_language_servers_for_buffers(
10616        &mut self,
10617        buffers: Vec<Entity<Buffer>>,
10618        also_stop_servers: HashSet<LanguageServerSelector>,
10619        cx: &mut Context<Self>,
10620    ) -> Task<Result<()>> {
10621        if let Some((client, project_id)) = self.upstream_client() {
10622            let request = client.request(proto::StopLanguageServers {
10623                project_id,
10624                buffer_ids: buffers
10625                    .into_iter()
10626                    .map(|b| b.read(cx).remote_id().to_proto())
10627                    .collect(),
10628                also_servers: also_stop_servers
10629                    .into_iter()
10630                    .map(|selector| {
10631                        let selector = match selector {
10632                            LanguageServerSelector::Id(language_server_id) => {
10633                                proto::language_server_selector::Selector::ServerId(
10634                                    language_server_id.to_proto(),
10635                                )
10636                            }
10637                            LanguageServerSelector::Name(language_server_name) => {
10638                                proto::language_server_selector::Selector::Name(
10639                                    language_server_name.to_string(),
10640                                )
10641                            }
10642                        };
10643                        proto::LanguageServerSelector {
10644                            selector: Some(selector),
10645                        }
10646                    })
10647                    .collect(),
10648                all: false,
10649            });
10650            cx.background_spawn(async move {
10651                let _ = request.await?;
10652                Ok(())
10653            })
10654        } else {
10655            let task =
10656                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10657            cx.background_spawn(async move {
10658                task.await;
10659                Ok(())
10660            })
10661        }
10662    }
10663
10664    fn stop_local_language_servers_for_buffers(
10665        &mut self,
10666        buffers: &[Entity<Buffer>],
10667        also_stop_servers: HashSet<LanguageServerSelector>,
10668        cx: &mut Context<Self>,
10669    ) -> Task<()> {
10670        let Some(local) = self.as_local_mut() else {
10671            return Task::ready(());
10672        };
10673        let mut language_server_names_to_stop = BTreeSet::default();
10674        let mut language_servers_to_stop = also_stop_servers
10675            .into_iter()
10676            .flat_map(|selector| match selector {
10677                LanguageServerSelector::Id(id) => Some(id),
10678                LanguageServerSelector::Name(name) => {
10679                    language_server_names_to_stop.insert(name);
10680                    None
10681                }
10682            })
10683            .collect::<BTreeSet<_>>();
10684
10685        let mut covered_worktrees = HashSet::default();
10686        for buffer in buffers {
10687            buffer.update(cx, |buffer, cx| {
10688                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
10689                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
10690                    && covered_worktrees.insert(worktree_id)
10691                {
10692                    language_server_names_to_stop.retain(|name| {
10693                        let old_ids_count = language_servers_to_stop.len();
10694                        let all_language_servers_with_this_name = local
10695                            .language_server_ids
10696                            .iter()
10697                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
10698                        language_servers_to_stop.extend(all_language_servers_with_this_name);
10699                        old_ids_count == language_servers_to_stop.len()
10700                    });
10701                }
10702            });
10703        }
10704        for name in language_server_names_to_stop {
10705            language_servers_to_stop.extend(
10706                local
10707                    .language_server_ids
10708                    .iter()
10709                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
10710            );
10711        }
10712
10713        local.lsp_tree.remove_nodes(&language_servers_to_stop);
10714        let tasks = language_servers_to_stop
10715            .into_iter()
10716            .map(|server| self.stop_local_language_server(server, cx))
10717            .collect::<Vec<_>>();
10718
10719        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
10720    }
10721
10722    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
10723        let (worktree, relative_path) =
10724            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
10725
10726        let project_path = ProjectPath {
10727            worktree_id: worktree.read(cx).id(),
10728            path: relative_path,
10729        };
10730
10731        Some(
10732            self.buffer_store()
10733                .read(cx)
10734                .get_by_path(&project_path)?
10735                .read(cx),
10736        )
10737    }
10738
10739    #[cfg(any(test, feature = "test-support"))]
10740    pub fn update_diagnostics(
10741        &mut self,
10742        server_id: LanguageServerId,
10743        diagnostics: lsp::PublishDiagnosticsParams,
10744        result_id: Option<String>,
10745        source_kind: DiagnosticSourceKind,
10746        disk_based_sources: &[String],
10747        cx: &mut Context<Self>,
10748    ) -> Result<()> {
10749        self.merge_lsp_diagnostics(
10750            source_kind,
10751            vec![DocumentDiagnosticsUpdate {
10752                diagnostics,
10753                result_id,
10754                server_id,
10755                disk_based_sources: Cow::Borrowed(disk_based_sources),
10756            }],
10757            |_, _, _| false,
10758            cx,
10759        )
10760    }
10761
10762    pub fn merge_lsp_diagnostics(
10763        &mut self,
10764        source_kind: DiagnosticSourceKind,
10765        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
10766        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
10767        cx: &mut Context<Self>,
10768    ) -> Result<()> {
10769        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
10770        let updates = lsp_diagnostics
10771            .into_iter()
10772            .filter_map(|update| {
10773                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
10774                Some(DocumentDiagnosticsUpdate {
10775                    diagnostics: self.lsp_to_document_diagnostics(
10776                        abs_path,
10777                        source_kind,
10778                        update.server_id,
10779                        update.diagnostics,
10780                        &update.disk_based_sources,
10781                    ),
10782                    result_id: update.result_id,
10783                    server_id: update.server_id,
10784                    disk_based_sources: update.disk_based_sources,
10785                })
10786            })
10787            .collect();
10788        self.merge_diagnostic_entries(updates, merge, cx)?;
10789        Ok(())
10790    }
10791
10792    fn lsp_to_document_diagnostics(
10793        &mut self,
10794        document_abs_path: PathBuf,
10795        source_kind: DiagnosticSourceKind,
10796        server_id: LanguageServerId,
10797        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
10798        disk_based_sources: &[String],
10799    ) -> DocumentDiagnostics {
10800        let mut diagnostics = Vec::default();
10801        let mut primary_diagnostic_group_ids = HashMap::default();
10802        let mut sources_by_group_id = HashMap::default();
10803        let mut supporting_diagnostics = HashMap::default();
10804
10805        let adapter = self.language_server_adapter_for_id(server_id);
10806
10807        // Ensure that primary diagnostics are always the most severe
10808        lsp_diagnostics
10809            .diagnostics
10810            .sort_by_key(|item| item.severity);
10811
10812        for diagnostic in &lsp_diagnostics.diagnostics {
10813            let source = diagnostic.source.as_ref();
10814            let range = range_from_lsp(diagnostic.range);
10815            let is_supporting = diagnostic
10816                .related_information
10817                .as_ref()
10818                .is_some_and(|infos| {
10819                    infos.iter().any(|info| {
10820                        primary_diagnostic_group_ids.contains_key(&(
10821                            source,
10822                            diagnostic.code.clone(),
10823                            range_from_lsp(info.location.range),
10824                        ))
10825                    })
10826                });
10827
10828            let is_unnecessary = diagnostic
10829                .tags
10830                .as_ref()
10831                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
10832
10833            let underline = self
10834                .language_server_adapter_for_id(server_id)
10835                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
10836
10837            if is_supporting {
10838                supporting_diagnostics.insert(
10839                    (source, diagnostic.code.clone(), range),
10840                    (diagnostic.severity, is_unnecessary),
10841                );
10842            } else {
10843                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
10844                let is_disk_based =
10845                    source.is_some_and(|source| disk_based_sources.contains(source));
10846
10847                sources_by_group_id.insert(group_id, source);
10848                primary_diagnostic_group_ids
10849                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
10850
10851                diagnostics.push(DiagnosticEntry {
10852                    range,
10853                    diagnostic: Diagnostic {
10854                        source: diagnostic.source.clone(),
10855                        source_kind,
10856                        code: diagnostic.code.clone(),
10857                        code_description: diagnostic
10858                            .code_description
10859                            .as_ref()
10860                            .and_then(|d| d.href.clone()),
10861                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
10862                        markdown: adapter.as_ref().and_then(|adapter| {
10863                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
10864                        }),
10865                        message: diagnostic.message.trim().to_string(),
10866                        group_id,
10867                        is_primary: true,
10868                        is_disk_based,
10869                        is_unnecessary,
10870                        underline,
10871                        data: diagnostic.data.clone(),
10872                    },
10873                });
10874                if let Some(infos) = &diagnostic.related_information {
10875                    for info in infos {
10876                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
10877                            let range = range_from_lsp(info.location.range);
10878                            diagnostics.push(DiagnosticEntry {
10879                                range,
10880                                diagnostic: Diagnostic {
10881                                    source: diagnostic.source.clone(),
10882                                    source_kind,
10883                                    code: diagnostic.code.clone(),
10884                                    code_description: diagnostic
10885                                        .code_description
10886                                        .as_ref()
10887                                        .and_then(|d| d.href.clone()),
10888                                    severity: DiagnosticSeverity::INFORMATION,
10889                                    markdown: adapter.as_ref().and_then(|adapter| {
10890                                        adapter.diagnostic_message_to_markdown(&info.message)
10891                                    }),
10892                                    message: info.message.trim().to_string(),
10893                                    group_id,
10894                                    is_primary: false,
10895                                    is_disk_based,
10896                                    is_unnecessary: false,
10897                                    underline,
10898                                    data: diagnostic.data.clone(),
10899                                },
10900                            });
10901                        }
10902                    }
10903                }
10904            }
10905        }
10906
10907        for entry in &mut diagnostics {
10908            let diagnostic = &mut entry.diagnostic;
10909            if !diagnostic.is_primary {
10910                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
10911                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
10912                    source,
10913                    diagnostic.code.clone(),
10914                    entry.range.clone(),
10915                )) {
10916                    if let Some(severity) = severity {
10917                        diagnostic.severity = severity;
10918                    }
10919                    diagnostic.is_unnecessary = is_unnecessary;
10920                }
10921            }
10922        }
10923
10924        DocumentDiagnostics {
10925            diagnostics,
10926            document_abs_path,
10927            version: lsp_diagnostics.version,
10928        }
10929    }
10930
10931    fn insert_newly_running_language_server(
10932        &mut self,
10933        adapter: Arc<CachedLspAdapter>,
10934        language_server: Arc<LanguageServer>,
10935        server_id: LanguageServerId,
10936        key: LanguageServerSeed,
10937        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
10938        cx: &mut Context<Self>,
10939    ) {
10940        let Some(local) = self.as_local_mut() else {
10941            return;
10942        };
10943        // If the language server for this key doesn't match the server id, don't store the
10944        // server. Which will cause it to be dropped, killing the process
10945        if local
10946            .language_server_ids
10947            .get(&key)
10948            .map(|state| state.id != server_id)
10949            .unwrap_or(false)
10950        {
10951            return;
10952        }
10953
10954        // Update language_servers collection with Running variant of LanguageServerState
10955        // indicating that the server is up and running and ready
10956        let workspace_folders = workspace_folders.lock().clone();
10957        language_server.set_workspace_folders(workspace_folders);
10958
10959        let workspace_diagnostics_refresh_tasks = language_server
10960            .capabilities()
10961            .diagnostic_provider
10962            .and_then(|provider| {
10963                local
10964                    .language_server_dynamic_registrations
10965                    .entry(server_id)
10966                    .or_default()
10967                    .diagnostics
10968                    .entry(None)
10969                    .or_insert(provider.clone());
10970                let workspace_refresher =
10971                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
10972
10973                Some((None, workspace_refresher))
10974            })
10975            .into_iter()
10976            .collect();
10977        local.language_servers.insert(
10978            server_id,
10979            LanguageServerState::Running {
10980                workspace_diagnostics_refresh_tasks,
10981                adapter: adapter.clone(),
10982                server: language_server.clone(),
10983                simulate_disk_based_diagnostics_completion: None,
10984            },
10985        );
10986        local
10987            .languages
10988            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
10989        if let Some(file_ops_caps) = language_server
10990            .capabilities()
10991            .workspace
10992            .as_ref()
10993            .and_then(|ws| ws.file_operations.as_ref())
10994        {
10995            let did_rename_caps = file_ops_caps.did_rename.as_ref();
10996            let will_rename_caps = file_ops_caps.will_rename.as_ref();
10997            if did_rename_caps.or(will_rename_caps).is_some() {
10998                let watcher = RenamePathsWatchedForServer::default()
10999                    .with_did_rename_patterns(did_rename_caps)
11000                    .with_will_rename_patterns(will_rename_caps);
11001                local
11002                    .language_server_paths_watched_for_rename
11003                    .insert(server_id, watcher);
11004            }
11005        }
11006
11007        self.language_server_statuses.insert(
11008            server_id,
11009            LanguageServerStatus {
11010                name: language_server.name(),
11011                pending_work: Default::default(),
11012                has_pending_diagnostic_updates: false,
11013                progress_tokens: Default::default(),
11014                worktree: Some(key.worktree_id),
11015            },
11016        );
11017
11018        cx.emit(LspStoreEvent::LanguageServerAdded(
11019            server_id,
11020            language_server.name(),
11021            Some(key.worktree_id),
11022        ));
11023
11024        let server_capabilities = language_server.capabilities();
11025        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11026            downstream_client
11027                .send(proto::StartLanguageServer {
11028                    project_id: *project_id,
11029                    server: Some(proto::LanguageServer {
11030                        id: server_id.to_proto(),
11031                        name: language_server.name().to_string(),
11032                        worktree_id: Some(key.worktree_id.to_proto()),
11033                    }),
11034                    capabilities: serde_json::to_string(&server_capabilities)
11035                        .expect("serializing server LSP capabilities"),
11036                })
11037                .log_err();
11038        }
11039        self.lsp_server_capabilities
11040            .insert(server_id, server_capabilities);
11041
11042        // Tell the language server about every open buffer in the worktree that matches the language.
11043        // Also check for buffers in worktrees that reused this server
11044        let mut worktrees_using_server = vec![key.worktree_id];
11045        if let Some(local) = self.as_local() {
11046            // Find all worktrees that have this server in their language server tree
11047            for (worktree_id, servers) in &local.lsp_tree.instances {
11048                if *worktree_id != key.worktree_id {
11049                    for server_map in servers.roots.values() {
11050                        if server_map
11051                            .values()
11052                            .any(|(node, _)| node.id() == Some(server_id))
11053                        {
11054                            worktrees_using_server.push(*worktree_id);
11055                        }
11056                    }
11057                }
11058            }
11059        }
11060
11061        let mut buffer_paths_registered = Vec::new();
11062        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11063            let mut lsp_adapters = HashMap::default();
11064            for buffer_handle in buffer_store.buffers() {
11065                let buffer = buffer_handle.read(cx);
11066                let file = match File::from_dyn(buffer.file()) {
11067                    Some(file) => file,
11068                    None => continue,
11069                };
11070                let language = match buffer.language() {
11071                    Some(language) => language,
11072                    None => continue,
11073                };
11074
11075                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11076                    || !lsp_adapters
11077                        .entry(language.name())
11078                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11079                        .iter()
11080                        .any(|a| a.name == key.name)
11081                {
11082                    continue;
11083                }
11084                // didOpen
11085                let file = match file.as_local() {
11086                    Some(file) => file,
11087                    None => continue,
11088                };
11089
11090                let local = self.as_local_mut().unwrap();
11091
11092                let buffer_id = buffer.remote_id();
11093                if local.registered_buffers.contains_key(&buffer_id) {
11094                    let versions = local
11095                        .buffer_snapshots
11096                        .entry(buffer_id)
11097                        .or_default()
11098                        .entry(server_id)
11099                        .and_modify(|_| {
11100                            assert!(
11101                            false,
11102                            "There should not be an existing snapshot for a newly inserted buffer"
11103                        )
11104                        })
11105                        .or_insert_with(|| {
11106                            vec![LspBufferSnapshot {
11107                                version: 0,
11108                                snapshot: buffer.text_snapshot(),
11109                            }]
11110                        });
11111
11112                    let snapshot = versions.last().unwrap();
11113                    let version = snapshot.version;
11114                    let initial_snapshot = &snapshot.snapshot;
11115                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11116                    language_server.register_buffer(
11117                        uri,
11118                        adapter.language_id(&language.name()),
11119                        version,
11120                        initial_snapshot.text(),
11121                    );
11122                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11123                    local
11124                        .buffers_opened_in_servers
11125                        .entry(buffer_id)
11126                        .or_default()
11127                        .insert(server_id);
11128                }
11129                buffer_handle.update(cx, |buffer, cx| {
11130                    buffer.set_completion_triggers(
11131                        server_id,
11132                        language_server
11133                            .capabilities()
11134                            .completion_provider
11135                            .as_ref()
11136                            .and_then(|provider| {
11137                                provider
11138                                    .trigger_characters
11139                                    .as_ref()
11140                                    .map(|characters| characters.iter().cloned().collect())
11141                            })
11142                            .unwrap_or_default(),
11143                        cx,
11144                    )
11145                });
11146            }
11147        });
11148
11149        for (buffer_id, abs_path) in buffer_paths_registered {
11150            cx.emit(LspStoreEvent::LanguageServerUpdate {
11151                language_server_id: server_id,
11152                name: Some(adapter.name()),
11153                message: proto::update_language_server::Variant::RegisteredForBuffer(
11154                    proto::RegisteredForBuffer {
11155                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11156                        buffer_id: buffer_id.to_proto(),
11157                    },
11158                ),
11159            });
11160        }
11161
11162        cx.notify();
11163    }
11164
11165    pub fn language_servers_running_disk_based_diagnostics(
11166        &self,
11167    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11168        self.language_server_statuses
11169            .iter()
11170            .filter_map(|(id, status)| {
11171                if status.has_pending_diagnostic_updates {
11172                    Some(*id)
11173                } else {
11174                    None
11175                }
11176            })
11177    }
11178
11179    pub(crate) fn cancel_language_server_work_for_buffers(
11180        &mut self,
11181        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11182        cx: &mut Context<Self>,
11183    ) {
11184        if let Some((client, project_id)) = self.upstream_client() {
11185            let request = client.request(proto::CancelLanguageServerWork {
11186                project_id,
11187                work: Some(proto::cancel_language_server_work::Work::Buffers(
11188                    proto::cancel_language_server_work::Buffers {
11189                        buffer_ids: buffers
11190                            .into_iter()
11191                            .map(|b| b.read(cx).remote_id().to_proto())
11192                            .collect(),
11193                    },
11194                )),
11195            });
11196            cx.background_spawn(request).detach_and_log_err(cx);
11197        } else if let Some(local) = self.as_local() {
11198            let servers = buffers
11199                .into_iter()
11200                .flat_map(|buffer| {
11201                    buffer.update(cx, |buffer, cx| {
11202                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11203                    })
11204                })
11205                .collect::<HashSet<_>>();
11206            for server_id in servers {
11207                self.cancel_language_server_work(server_id, None, cx);
11208            }
11209        }
11210    }
11211
11212    pub(crate) fn cancel_language_server_work(
11213        &mut self,
11214        server_id: LanguageServerId,
11215        token_to_cancel: Option<ProgressToken>,
11216        cx: &mut Context<Self>,
11217    ) {
11218        if let Some(local) = self.as_local() {
11219            let status = self.language_server_statuses.get(&server_id);
11220            let server = local.language_servers.get(&server_id);
11221            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11222            {
11223                for (token, progress) in &status.pending_work {
11224                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11225                        && token != token_to_cancel
11226                    {
11227                        continue;
11228                    }
11229                    if progress.is_cancellable {
11230                        server
11231                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11232                                WorkDoneProgressCancelParams {
11233                                    token: token.to_lsp(),
11234                                },
11235                            )
11236                            .ok();
11237                    }
11238                }
11239            }
11240        } else if let Some((client, project_id)) = self.upstream_client() {
11241            let request = client.request(proto::CancelLanguageServerWork {
11242                project_id,
11243                work: Some(
11244                    proto::cancel_language_server_work::Work::LanguageServerWork(
11245                        proto::cancel_language_server_work::LanguageServerWork {
11246                            language_server_id: server_id.to_proto(),
11247                            token: token_to_cancel.map(|token| token.to_proto()),
11248                        },
11249                    ),
11250                ),
11251            });
11252            cx.background_spawn(request).detach_and_log_err(cx);
11253        }
11254    }
11255
11256    fn register_supplementary_language_server(
11257        &mut self,
11258        id: LanguageServerId,
11259        name: LanguageServerName,
11260        server: Arc<LanguageServer>,
11261        cx: &mut Context<Self>,
11262    ) {
11263        if let Some(local) = self.as_local_mut() {
11264            local
11265                .supplementary_language_servers
11266                .insert(id, (name.clone(), server));
11267            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11268        }
11269    }
11270
11271    fn unregister_supplementary_language_server(
11272        &mut self,
11273        id: LanguageServerId,
11274        cx: &mut Context<Self>,
11275    ) {
11276        if let Some(local) = self.as_local_mut() {
11277            local.supplementary_language_servers.remove(&id);
11278            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11279        }
11280    }
11281
11282    pub(crate) fn supplementary_language_servers(
11283        &self,
11284    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11285        self.as_local().into_iter().flat_map(|local| {
11286            local
11287                .supplementary_language_servers
11288                .iter()
11289                .map(|(id, (name, _))| (*id, name.clone()))
11290        })
11291    }
11292
11293    pub fn language_server_adapter_for_id(
11294        &self,
11295        id: LanguageServerId,
11296    ) -> Option<Arc<CachedLspAdapter>> {
11297        self.as_local()
11298            .and_then(|local| local.language_servers.get(&id))
11299            .and_then(|language_server_state| match language_server_state {
11300                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11301                _ => None,
11302            })
11303    }
11304
11305    pub(super) fn update_local_worktree_language_servers(
11306        &mut self,
11307        worktree_handle: &Entity<Worktree>,
11308        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11309        cx: &mut Context<Self>,
11310    ) {
11311        if changes.is_empty() {
11312            return;
11313        }
11314
11315        let Some(local) = self.as_local() else { return };
11316
11317        local.prettier_store.update(cx, |prettier_store, cx| {
11318            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11319        });
11320
11321        let worktree_id = worktree_handle.read(cx).id();
11322        let mut language_server_ids = local
11323            .language_server_ids
11324            .iter()
11325            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11326            .collect::<Vec<_>>();
11327        language_server_ids.sort();
11328        language_server_ids.dedup();
11329
11330        // let abs_path = worktree_handle.read(cx).abs_path();
11331        for server_id in &language_server_ids {
11332            if let Some(LanguageServerState::Running { server, .. }) =
11333                local.language_servers.get(server_id)
11334                && let Some(watched_paths) = local
11335                    .language_server_watched_paths
11336                    .get(server_id)
11337                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11338            {
11339                let params = lsp::DidChangeWatchedFilesParams {
11340                    changes: changes
11341                        .iter()
11342                        .filter_map(|(path, _, change)| {
11343                            if !watched_paths.is_match(path.as_std_path()) {
11344                                return None;
11345                            }
11346                            let typ = match change {
11347                                PathChange::Loaded => return None,
11348                                PathChange::Added => lsp::FileChangeType::CREATED,
11349                                PathChange::Removed => lsp::FileChangeType::DELETED,
11350                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11351                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11352                            };
11353                            let uri = lsp::Uri::from_file_path(
11354                                worktree_handle.read(cx).absolutize(&path),
11355                            )
11356                            .ok()?;
11357                            Some(lsp::FileEvent { uri, typ })
11358                        })
11359                        .collect(),
11360                };
11361                if !params.changes.is_empty() {
11362                    server
11363                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11364                        .ok();
11365                }
11366            }
11367        }
11368        for (path, _, _) in changes {
11369            if let Some(file_name) = path.file_name()
11370                && local.watched_manifest_filenames.contains(file_name)
11371            {
11372                self.request_workspace_config_refresh();
11373                break;
11374            }
11375        }
11376    }
11377
11378    pub fn wait_for_remote_buffer(
11379        &mut self,
11380        id: BufferId,
11381        cx: &mut Context<Self>,
11382    ) -> Task<Result<Entity<Buffer>>> {
11383        self.buffer_store.update(cx, |buffer_store, cx| {
11384            buffer_store.wait_for_remote_buffer(id, cx)
11385        })
11386    }
11387
11388    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11389        let mut result = proto::Symbol {
11390            language_server_name: symbol.language_server_name.0.to_string(),
11391            source_worktree_id: symbol.source_worktree_id.to_proto(),
11392            language_server_id: symbol.source_language_server_id.to_proto(),
11393            name: symbol.name.clone(),
11394            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11395            start: Some(proto::PointUtf16 {
11396                row: symbol.range.start.0.row,
11397                column: symbol.range.start.0.column,
11398            }),
11399            end: Some(proto::PointUtf16 {
11400                row: symbol.range.end.0.row,
11401                column: symbol.range.end.0.column,
11402            }),
11403            worktree_id: Default::default(),
11404            path: Default::default(),
11405            signature: Default::default(),
11406        };
11407        match &symbol.path {
11408            SymbolLocation::InProject(path) => {
11409                result.worktree_id = path.worktree_id.to_proto();
11410                result.path = path.path.to_proto();
11411            }
11412            SymbolLocation::OutsideProject {
11413                abs_path,
11414                signature,
11415            } => {
11416                result.path = abs_path.to_string_lossy().into_owned();
11417                result.signature = signature.to_vec();
11418            }
11419        }
11420        result
11421    }
11422
11423    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11424        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11425        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11426        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11427
11428        let path = if serialized_symbol.signature.is_empty() {
11429            SymbolLocation::InProject(ProjectPath {
11430                worktree_id,
11431                path: RelPath::from_proto(&serialized_symbol.path)
11432                    .context("invalid symbol path")?,
11433            })
11434        } else {
11435            SymbolLocation::OutsideProject {
11436                abs_path: Path::new(&serialized_symbol.path).into(),
11437                signature: serialized_symbol
11438                    .signature
11439                    .try_into()
11440                    .map_err(|_| anyhow!("invalid signature"))?,
11441            }
11442        };
11443
11444        let start = serialized_symbol.start.context("invalid start")?;
11445        let end = serialized_symbol.end.context("invalid end")?;
11446        Ok(CoreSymbol {
11447            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11448            source_worktree_id,
11449            source_language_server_id: LanguageServerId::from_proto(
11450                serialized_symbol.language_server_id,
11451            ),
11452            path,
11453            name: serialized_symbol.name,
11454            range: Unclipped(PointUtf16::new(start.row, start.column))
11455                ..Unclipped(PointUtf16::new(end.row, end.column)),
11456            kind,
11457        })
11458    }
11459
11460    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11461        let mut serialized_completion = proto::Completion {
11462            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11463            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11464            new_text: completion.new_text.clone(),
11465            ..proto::Completion::default()
11466        };
11467        match &completion.source {
11468            CompletionSource::Lsp {
11469                insert_range,
11470                server_id,
11471                lsp_completion,
11472                lsp_defaults,
11473                resolved,
11474            } => {
11475                let (old_insert_start, old_insert_end) = insert_range
11476                    .as_ref()
11477                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11478                    .unzip();
11479
11480                serialized_completion.old_insert_start = old_insert_start;
11481                serialized_completion.old_insert_end = old_insert_end;
11482                serialized_completion.source = proto::completion::Source::Lsp as i32;
11483                serialized_completion.server_id = server_id.0 as u64;
11484                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11485                serialized_completion.lsp_defaults = lsp_defaults
11486                    .as_deref()
11487                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11488                serialized_completion.resolved = *resolved;
11489            }
11490            CompletionSource::BufferWord {
11491                word_range,
11492                resolved,
11493            } => {
11494                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11495                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11496                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11497                serialized_completion.resolved = *resolved;
11498            }
11499            CompletionSource::Custom => {
11500                serialized_completion.source = proto::completion::Source::Custom as i32;
11501                serialized_completion.resolved = true;
11502            }
11503            CompletionSource::Dap { sort_text } => {
11504                serialized_completion.source = proto::completion::Source::Dap as i32;
11505                serialized_completion.sort_text = Some(sort_text.clone());
11506            }
11507        }
11508
11509        serialized_completion
11510    }
11511
11512    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11513        let old_replace_start = completion
11514            .old_replace_start
11515            .and_then(deserialize_anchor)
11516            .context("invalid old start")?;
11517        let old_replace_end = completion
11518            .old_replace_end
11519            .and_then(deserialize_anchor)
11520            .context("invalid old end")?;
11521        let insert_range = {
11522            match completion.old_insert_start.zip(completion.old_insert_end) {
11523                Some((start, end)) => {
11524                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11525                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11526                    Some(start..end)
11527                }
11528                None => None,
11529            }
11530        };
11531        Ok(CoreCompletion {
11532            replace_range: old_replace_start..old_replace_end,
11533            new_text: completion.new_text,
11534            source: match proto::completion::Source::from_i32(completion.source) {
11535                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11536                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11537                    insert_range,
11538                    server_id: LanguageServerId::from_proto(completion.server_id),
11539                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11540                    lsp_defaults: completion
11541                        .lsp_defaults
11542                        .as_deref()
11543                        .map(serde_json::from_slice)
11544                        .transpose()?,
11545                    resolved: completion.resolved,
11546                },
11547                Some(proto::completion::Source::BufferWord) => {
11548                    let word_range = completion
11549                        .buffer_word_start
11550                        .and_then(deserialize_anchor)
11551                        .context("invalid buffer word start")?
11552                        ..completion
11553                            .buffer_word_end
11554                            .and_then(deserialize_anchor)
11555                            .context("invalid buffer word end")?;
11556                    CompletionSource::BufferWord {
11557                        word_range,
11558                        resolved: completion.resolved,
11559                    }
11560                }
11561                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11562                    sort_text: completion
11563                        .sort_text
11564                        .context("expected sort text to exist")?,
11565                },
11566                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11567            },
11568        })
11569    }
11570
11571    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11572        let (kind, lsp_action) = match &action.lsp_action {
11573            LspAction::Action(code_action) => (
11574                proto::code_action::Kind::Action as i32,
11575                serde_json::to_vec(code_action).unwrap(),
11576            ),
11577            LspAction::Command(command) => (
11578                proto::code_action::Kind::Command as i32,
11579                serde_json::to_vec(command).unwrap(),
11580            ),
11581            LspAction::CodeLens(code_lens) => (
11582                proto::code_action::Kind::CodeLens as i32,
11583                serde_json::to_vec(code_lens).unwrap(),
11584            ),
11585        };
11586
11587        proto::CodeAction {
11588            server_id: action.server_id.0 as u64,
11589            start: Some(serialize_anchor(&action.range.start)),
11590            end: Some(serialize_anchor(&action.range.end)),
11591            lsp_action,
11592            kind,
11593            resolved: action.resolved,
11594        }
11595    }
11596
11597    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11598        let start = action
11599            .start
11600            .and_then(deserialize_anchor)
11601            .context("invalid start")?;
11602        let end = action
11603            .end
11604            .and_then(deserialize_anchor)
11605            .context("invalid end")?;
11606        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11607            Some(proto::code_action::Kind::Action) => {
11608                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11609            }
11610            Some(proto::code_action::Kind::Command) => {
11611                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11612            }
11613            Some(proto::code_action::Kind::CodeLens) => {
11614                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11615            }
11616            None => anyhow::bail!("Unknown action kind {}", action.kind),
11617        };
11618        Ok(CodeAction {
11619            server_id: LanguageServerId(action.server_id as usize),
11620            range: start..end,
11621            resolved: action.resolved,
11622            lsp_action,
11623        })
11624    }
11625
11626    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11627        match &formatting_result {
11628            Ok(_) => self.last_formatting_failure = None,
11629            Err(error) => {
11630                let error_string = format!("{error:#}");
11631                log::error!("Formatting failed: {error_string}");
11632                self.last_formatting_failure
11633                    .replace(error_string.lines().join(" "));
11634            }
11635        }
11636    }
11637
11638    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11639        self.lsp_server_capabilities.remove(&for_server);
11640        for lsp_data in self.lsp_data.values_mut() {
11641            lsp_data.remove_server_data(for_server);
11642        }
11643        if let Some(local) = self.as_local_mut() {
11644            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11645            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11646                buffer_servers.remove(&for_server);
11647            }
11648        }
11649    }
11650
11651    pub fn result_id(
11652        &self,
11653        server_id: LanguageServerId,
11654        buffer_id: BufferId,
11655        cx: &App,
11656    ) -> Option<String> {
11657        let abs_path = self
11658            .buffer_store
11659            .read(cx)
11660            .get(buffer_id)
11661            .and_then(|b| File::from_dyn(b.read(cx).file()))
11662            .map(|f| f.abs_path(cx))?;
11663        self.as_local()?
11664            .buffer_pull_diagnostics_result_ids
11665            .get(&server_id)?
11666            .get(&abs_path)?
11667            .clone()
11668    }
11669
11670    pub fn all_result_ids(&self, server_id: LanguageServerId) -> HashMap<PathBuf, String> {
11671        let Some(local) = self.as_local() else {
11672            return HashMap::default();
11673        };
11674        local
11675            .buffer_pull_diagnostics_result_ids
11676            .get(&server_id)
11677            .into_iter()
11678            .flatten()
11679            .filter_map(|(abs_path, result_id)| Some((abs_path.clone(), result_id.clone()?)))
11680            .collect()
11681    }
11682
11683    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
11684        if let Some(LanguageServerState::Running {
11685            workspace_diagnostics_refresh_tasks,
11686            ..
11687        }) = self
11688            .as_local_mut()
11689            .and_then(|local| local.language_servers.get_mut(&server_id))
11690        {
11691            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
11692                diagnostics.refresh_tx.try_send(()).ok();
11693            }
11694        }
11695    }
11696
11697    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
11698        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
11699            return;
11700        };
11701        let Some(local) = self.as_local_mut() else {
11702            return;
11703        };
11704
11705        for server_id in buffer.update(cx, |buffer, cx| {
11706            local.language_server_ids_for_buffer(buffer, cx)
11707        }) {
11708            if let Some(LanguageServerState::Running {
11709                workspace_diagnostics_refresh_tasks,
11710                ..
11711            }) = local.language_servers.get_mut(&server_id)
11712            {
11713                for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
11714                    diagnostics.refresh_tx.try_send(()).ok();
11715                }
11716            }
11717        }
11718    }
11719
11720    fn apply_workspace_diagnostic_report(
11721        &mut self,
11722        server_id: LanguageServerId,
11723        report: lsp::WorkspaceDiagnosticReportResult,
11724        cx: &mut Context<Self>,
11725    ) {
11726        let workspace_diagnostics =
11727            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(report, server_id);
11728        let mut unchanged_buffers = HashSet::default();
11729        let mut changed_buffers = HashSet::default();
11730        let workspace_diagnostics_updates = workspace_diagnostics
11731            .into_iter()
11732            .filter_map(
11733                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
11734                    LspPullDiagnostics::Response {
11735                        server_id,
11736                        uri,
11737                        diagnostics,
11738                    } => Some((server_id, uri, diagnostics, workspace_diagnostics.version)),
11739                    LspPullDiagnostics::Default => None,
11740                },
11741            )
11742            .fold(
11743                HashMap::default(),
11744                |mut acc, (server_id, uri, diagnostics, version)| {
11745                    let (result_id, diagnostics) = match diagnostics {
11746                        PulledDiagnostics::Unchanged { result_id } => {
11747                            unchanged_buffers.insert(uri.clone());
11748                            (Some(result_id), Vec::new())
11749                        }
11750                        PulledDiagnostics::Changed {
11751                            result_id,
11752                            diagnostics,
11753                        } => {
11754                            changed_buffers.insert(uri.clone());
11755                            (result_id, diagnostics)
11756                        }
11757                    };
11758                    let disk_based_sources = Cow::Owned(
11759                        self.language_server_adapter_for_id(server_id)
11760                            .as_ref()
11761                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
11762                            .unwrap_or(&[])
11763                            .to_vec(),
11764                    );
11765                    acc.entry(server_id)
11766                        .or_insert_with(Vec::new)
11767                        .push(DocumentDiagnosticsUpdate {
11768                            server_id,
11769                            diagnostics: lsp::PublishDiagnosticsParams {
11770                                uri,
11771                                diagnostics,
11772                                version,
11773                            },
11774                            result_id,
11775                            disk_based_sources,
11776                        });
11777                    acc
11778                },
11779            );
11780
11781        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
11782            self.merge_lsp_diagnostics(
11783                DiagnosticSourceKind::Pulled,
11784                diagnostic_updates,
11785                |buffer, old_diagnostic, cx| {
11786                    File::from_dyn(buffer.file())
11787                        .and_then(|file| {
11788                            let abs_path = file.as_local()?.abs_path(cx);
11789                            lsp::Uri::from_file_path(abs_path).ok()
11790                        })
11791                        .is_none_or(|buffer_uri| {
11792                            unchanged_buffers.contains(&buffer_uri)
11793                                || match old_diagnostic.source_kind {
11794                                    DiagnosticSourceKind::Pulled => {
11795                                        !changed_buffers.contains(&buffer_uri)
11796                                    }
11797                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
11798                                        true
11799                                    }
11800                                }
11801                        })
11802                },
11803                cx,
11804            )
11805            .log_err();
11806        }
11807    }
11808
11809    fn register_server_capabilities(
11810        &mut self,
11811        server_id: LanguageServerId,
11812        params: lsp::RegistrationParams,
11813        cx: &mut Context<Self>,
11814    ) -> anyhow::Result<()> {
11815        let server = self
11816            .language_server_for_id(server_id)
11817            .with_context(|| format!("no server {server_id} found"))?;
11818        for reg in params.registrations {
11819            match reg.method.as_str() {
11820                "workspace/didChangeWatchedFiles" => {
11821                    if let Some(options) = reg.register_options {
11822                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11823                            let caps = serde_json::from_value(options)?;
11824                            local_lsp_store
11825                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
11826                            true
11827                        } else {
11828                            false
11829                        };
11830                        if notify {
11831                            notify_server_capabilities_updated(&server, cx);
11832                        }
11833                    }
11834                }
11835                "workspace/didChangeConfiguration" => {
11836                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11837                }
11838                "workspace/didChangeWorkspaceFolders" => {
11839                    // In this case register options is an empty object, we can ignore it
11840                    let caps = lsp::WorkspaceFoldersServerCapabilities {
11841                        supported: Some(true),
11842                        change_notifications: Some(OneOf::Right(reg.id)),
11843                    };
11844                    server.update_capabilities(|capabilities| {
11845                        capabilities
11846                            .workspace
11847                            .get_or_insert_default()
11848                            .workspace_folders = Some(caps);
11849                    });
11850                    notify_server_capabilities_updated(&server, cx);
11851                }
11852                "workspace/symbol" => {
11853                    let options = parse_register_capabilities(reg)?;
11854                    server.update_capabilities(|capabilities| {
11855                        capabilities.workspace_symbol_provider = Some(options);
11856                    });
11857                    notify_server_capabilities_updated(&server, cx);
11858                }
11859                "workspace/fileOperations" => {
11860                    if let Some(options) = reg.register_options {
11861                        let caps = serde_json::from_value(options)?;
11862                        server.update_capabilities(|capabilities| {
11863                            capabilities
11864                                .workspace
11865                                .get_or_insert_default()
11866                                .file_operations = Some(caps);
11867                        });
11868                        notify_server_capabilities_updated(&server, cx);
11869                    }
11870                }
11871                "workspace/executeCommand" => {
11872                    if let Some(options) = reg.register_options {
11873                        let options = serde_json::from_value(options)?;
11874                        server.update_capabilities(|capabilities| {
11875                            capabilities.execute_command_provider = Some(options);
11876                        });
11877                        notify_server_capabilities_updated(&server, cx);
11878                    }
11879                }
11880                "textDocument/rangeFormatting" => {
11881                    let options = parse_register_capabilities(reg)?;
11882                    server.update_capabilities(|capabilities| {
11883                        capabilities.document_range_formatting_provider = Some(options);
11884                    });
11885                    notify_server_capabilities_updated(&server, cx);
11886                }
11887                "textDocument/onTypeFormatting" => {
11888                    if let Some(options) = reg
11889                        .register_options
11890                        .map(serde_json::from_value)
11891                        .transpose()?
11892                    {
11893                        server.update_capabilities(|capabilities| {
11894                            capabilities.document_on_type_formatting_provider = Some(options);
11895                        });
11896                        notify_server_capabilities_updated(&server, cx);
11897                    }
11898                }
11899                "textDocument/formatting" => {
11900                    let options = parse_register_capabilities(reg)?;
11901                    server.update_capabilities(|capabilities| {
11902                        capabilities.document_formatting_provider = Some(options);
11903                    });
11904                    notify_server_capabilities_updated(&server, cx);
11905                }
11906                "textDocument/rename" => {
11907                    let options = parse_register_capabilities(reg)?;
11908                    server.update_capabilities(|capabilities| {
11909                        capabilities.rename_provider = Some(options);
11910                    });
11911                    notify_server_capabilities_updated(&server, cx);
11912                }
11913                "textDocument/inlayHint" => {
11914                    let options = parse_register_capabilities(reg)?;
11915                    server.update_capabilities(|capabilities| {
11916                        capabilities.inlay_hint_provider = Some(options);
11917                    });
11918                    notify_server_capabilities_updated(&server, cx);
11919                }
11920                "textDocument/documentSymbol" => {
11921                    let options = parse_register_capabilities(reg)?;
11922                    server.update_capabilities(|capabilities| {
11923                        capabilities.document_symbol_provider = Some(options);
11924                    });
11925                    notify_server_capabilities_updated(&server, cx);
11926                }
11927                "textDocument/codeAction" => {
11928                    let options = parse_register_capabilities(reg)?;
11929                    let provider = match options {
11930                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
11931                        OneOf::Right(caps) => caps,
11932                    };
11933                    server.update_capabilities(|capabilities| {
11934                        capabilities.code_action_provider = Some(provider);
11935                    });
11936                    notify_server_capabilities_updated(&server, cx);
11937                }
11938                "textDocument/definition" => {
11939                    let options = parse_register_capabilities(reg)?;
11940                    server.update_capabilities(|capabilities| {
11941                        capabilities.definition_provider = Some(options);
11942                    });
11943                    notify_server_capabilities_updated(&server, cx);
11944                }
11945                "textDocument/completion" => {
11946                    if let Some(caps) = reg
11947                        .register_options
11948                        .map(serde_json::from_value::<CompletionOptions>)
11949                        .transpose()?
11950                    {
11951                        server.update_capabilities(|capabilities| {
11952                            capabilities.completion_provider = Some(caps.clone());
11953                        });
11954
11955                        if let Some(local) = self.as_local() {
11956                            let mut buffers_with_language_server = Vec::new();
11957                            for handle in self.buffer_store.read(cx).buffers() {
11958                                let buffer_id = handle.read(cx).remote_id();
11959                                if local
11960                                    .buffers_opened_in_servers
11961                                    .get(&buffer_id)
11962                                    .filter(|s| s.contains(&server_id))
11963                                    .is_some()
11964                                {
11965                                    buffers_with_language_server.push(handle);
11966                                }
11967                            }
11968                            let triggers = caps
11969                                .trigger_characters
11970                                .unwrap_or_default()
11971                                .into_iter()
11972                                .collect::<BTreeSet<_>>();
11973                            for handle in buffers_with_language_server {
11974                                let triggers = triggers.clone();
11975                                let _ = handle.update(cx, move |buffer, cx| {
11976                                    buffer.set_completion_triggers(server_id, triggers, cx);
11977                                });
11978                            }
11979                        }
11980                        notify_server_capabilities_updated(&server, cx);
11981                    }
11982                }
11983                "textDocument/hover" => {
11984                    let options = parse_register_capabilities(reg)?;
11985                    let provider = match options {
11986                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
11987                        OneOf::Right(caps) => caps,
11988                    };
11989                    server.update_capabilities(|capabilities| {
11990                        capabilities.hover_provider = Some(provider);
11991                    });
11992                    notify_server_capabilities_updated(&server, cx);
11993                }
11994                "textDocument/signatureHelp" => {
11995                    if let Some(caps) = reg
11996                        .register_options
11997                        .map(serde_json::from_value)
11998                        .transpose()?
11999                    {
12000                        server.update_capabilities(|capabilities| {
12001                            capabilities.signature_help_provider = Some(caps);
12002                        });
12003                        notify_server_capabilities_updated(&server, cx);
12004                    }
12005                }
12006                "textDocument/didChange" => {
12007                    if let Some(sync_kind) = reg
12008                        .register_options
12009                        .and_then(|opts| opts.get("syncKind").cloned())
12010                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12011                        .transpose()?
12012                    {
12013                        server.update_capabilities(|capabilities| {
12014                            let mut sync_options =
12015                                Self::take_text_document_sync_options(capabilities);
12016                            sync_options.change = Some(sync_kind);
12017                            capabilities.text_document_sync =
12018                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12019                        });
12020                        notify_server_capabilities_updated(&server, cx);
12021                    }
12022                }
12023                "textDocument/didSave" => {
12024                    if let Some(include_text) = reg
12025                        .register_options
12026                        .map(|opts| {
12027                            let transpose = opts
12028                                .get("includeText")
12029                                .cloned()
12030                                .map(serde_json::from_value::<Option<bool>>)
12031                                .transpose();
12032                            match transpose {
12033                                Ok(value) => Ok(value.flatten()),
12034                                Err(e) => Err(e),
12035                            }
12036                        })
12037                        .transpose()?
12038                    {
12039                        server.update_capabilities(|capabilities| {
12040                            let mut sync_options =
12041                                Self::take_text_document_sync_options(capabilities);
12042                            sync_options.save =
12043                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12044                                    include_text,
12045                                }));
12046                            capabilities.text_document_sync =
12047                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12048                        });
12049                        notify_server_capabilities_updated(&server, cx);
12050                    }
12051                }
12052                "textDocument/codeLens" => {
12053                    if let Some(caps) = reg
12054                        .register_options
12055                        .map(serde_json::from_value)
12056                        .transpose()?
12057                    {
12058                        server.update_capabilities(|capabilities| {
12059                            capabilities.code_lens_provider = Some(caps);
12060                        });
12061                        notify_server_capabilities_updated(&server, cx);
12062                    }
12063                }
12064                "textDocument/diagnostic" => {
12065                    if let Some(caps) = reg
12066                        .register_options
12067                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12068                        .transpose()?
12069                    {
12070                        let local = self
12071                            .as_local_mut()
12072                            .context("Expected LSP Store to be local")?;
12073                        let state = local
12074                            .language_servers
12075                            .get_mut(&server_id)
12076                            .context("Could not obtain Language Servers state")?;
12077                        local
12078                            .language_server_dynamic_registrations
12079                            .entry(server_id)
12080                            .or_default()
12081                            .diagnostics
12082                            .insert(Some(reg.id.clone()), caps.clone());
12083
12084                        if let LanguageServerState::Running {
12085                            workspace_diagnostics_refresh_tasks,
12086                            ..
12087                        } = state
12088                            && let Some(task) = lsp_workspace_diagnostics_refresh(
12089                                Some(reg.id.clone()),
12090                                caps.clone(),
12091                                server.clone(),
12092                                cx,
12093                            )
12094                        {
12095                            workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12096                        }
12097
12098                        let mut did_update_caps = false;
12099                        server.update_capabilities(|capabilities| {
12100                            if capabilities.diagnostic_provider.as_ref().is_none_or(
12101                                |current_caps| {
12102                                    let supports_workspace_diagnostics =
12103                                        |capabilities: &DiagnosticServerCapabilities| {
12104                                            match capabilities {
12105                                            DiagnosticServerCapabilities::Options(
12106                                                diagnostic_options,
12107                                            ) => diagnostic_options.workspace_diagnostics,
12108                                            DiagnosticServerCapabilities::RegistrationOptions(
12109                                                diagnostic_registration_options,
12110                                            ) => {
12111                                                diagnostic_registration_options
12112                                                    .diagnostic_options
12113                                                    .workspace_diagnostics
12114                                            }
12115                                        }
12116                                        };
12117                                    // We don't actually care about capabilities.diagnostic_provider, but it IS relevant for the remote peer
12118                                    // to know that there's at least one provider. Otherwise, it will never ask us to issue documentdiagnostic calls on their behalf,
12119                                    // as it'll think that they're not supported.
12120                                    // If we did not support any workspace diagnostics up to this point but now do, let's update.
12121                                    !supports_workspace_diagnostics(current_caps)
12122                                        & supports_workspace_diagnostics(&caps)
12123                                },
12124                            ) {
12125                                did_update_caps = true;
12126                                capabilities.diagnostic_provider = Some(caps);
12127                            }
12128                        });
12129                        if did_update_caps {
12130                            notify_server_capabilities_updated(&server, cx);
12131                        }
12132                    }
12133                }
12134                "textDocument/documentColor" => {
12135                    let options = parse_register_capabilities(reg)?;
12136                    let provider = match options {
12137                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12138                        OneOf::Right(caps) => caps,
12139                    };
12140                    server.update_capabilities(|capabilities| {
12141                        capabilities.color_provider = Some(provider);
12142                    });
12143                    notify_server_capabilities_updated(&server, cx);
12144                }
12145                _ => log::warn!("unhandled capability registration: {reg:?}"),
12146            }
12147        }
12148
12149        Ok(())
12150    }
12151
12152    fn unregister_server_capabilities(
12153        &mut self,
12154        server_id: LanguageServerId,
12155        params: lsp::UnregistrationParams,
12156        cx: &mut Context<Self>,
12157    ) -> anyhow::Result<()> {
12158        let server = self
12159            .language_server_for_id(server_id)
12160            .with_context(|| format!("no server {server_id} found"))?;
12161        for unreg in params.unregisterations.iter() {
12162            match unreg.method.as_str() {
12163                "workspace/didChangeWatchedFiles" => {
12164                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12165                        local_lsp_store
12166                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12167                        true
12168                    } else {
12169                        false
12170                    };
12171                    if notify {
12172                        notify_server_capabilities_updated(&server, cx);
12173                    }
12174                }
12175                "workspace/didChangeConfiguration" => {
12176                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12177                }
12178                "workspace/didChangeWorkspaceFolders" => {
12179                    server.update_capabilities(|capabilities| {
12180                        capabilities
12181                            .workspace
12182                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12183                                workspace_folders: None,
12184                                file_operations: None,
12185                            })
12186                            .workspace_folders = None;
12187                    });
12188                    notify_server_capabilities_updated(&server, cx);
12189                }
12190                "workspace/symbol" => {
12191                    server.update_capabilities(|capabilities| {
12192                        capabilities.workspace_symbol_provider = None
12193                    });
12194                    notify_server_capabilities_updated(&server, cx);
12195                }
12196                "workspace/fileOperations" => {
12197                    server.update_capabilities(|capabilities| {
12198                        capabilities
12199                            .workspace
12200                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12201                                workspace_folders: None,
12202                                file_operations: None,
12203                            })
12204                            .file_operations = None;
12205                    });
12206                    notify_server_capabilities_updated(&server, cx);
12207                }
12208                "workspace/executeCommand" => {
12209                    server.update_capabilities(|capabilities| {
12210                        capabilities.execute_command_provider = None;
12211                    });
12212                    notify_server_capabilities_updated(&server, cx);
12213                }
12214                "textDocument/rangeFormatting" => {
12215                    server.update_capabilities(|capabilities| {
12216                        capabilities.document_range_formatting_provider = None
12217                    });
12218                    notify_server_capabilities_updated(&server, cx);
12219                }
12220                "textDocument/onTypeFormatting" => {
12221                    server.update_capabilities(|capabilities| {
12222                        capabilities.document_on_type_formatting_provider = None;
12223                    });
12224                    notify_server_capabilities_updated(&server, cx);
12225                }
12226                "textDocument/formatting" => {
12227                    server.update_capabilities(|capabilities| {
12228                        capabilities.document_formatting_provider = None;
12229                    });
12230                    notify_server_capabilities_updated(&server, cx);
12231                }
12232                "textDocument/rename" => {
12233                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12234                    notify_server_capabilities_updated(&server, cx);
12235                }
12236                "textDocument/codeAction" => {
12237                    server.update_capabilities(|capabilities| {
12238                        capabilities.code_action_provider = None;
12239                    });
12240                    notify_server_capabilities_updated(&server, cx);
12241                }
12242                "textDocument/definition" => {
12243                    server.update_capabilities(|capabilities| {
12244                        capabilities.definition_provider = None;
12245                    });
12246                    notify_server_capabilities_updated(&server, cx);
12247                }
12248                "textDocument/completion" => {
12249                    server.update_capabilities(|capabilities| {
12250                        capabilities.completion_provider = None;
12251                    });
12252                    notify_server_capabilities_updated(&server, cx);
12253                }
12254                "textDocument/hover" => {
12255                    server.update_capabilities(|capabilities| {
12256                        capabilities.hover_provider = None;
12257                    });
12258                    notify_server_capabilities_updated(&server, cx);
12259                }
12260                "textDocument/signatureHelp" => {
12261                    server.update_capabilities(|capabilities| {
12262                        capabilities.signature_help_provider = None;
12263                    });
12264                    notify_server_capabilities_updated(&server, cx);
12265                }
12266                "textDocument/didChange" => {
12267                    server.update_capabilities(|capabilities| {
12268                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12269                        sync_options.change = None;
12270                        capabilities.text_document_sync =
12271                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12272                    });
12273                    notify_server_capabilities_updated(&server, cx);
12274                }
12275                "textDocument/didSave" => {
12276                    server.update_capabilities(|capabilities| {
12277                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12278                        sync_options.save = None;
12279                        capabilities.text_document_sync =
12280                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12281                    });
12282                    notify_server_capabilities_updated(&server, cx);
12283                }
12284                "textDocument/codeLens" => {
12285                    server.update_capabilities(|capabilities| {
12286                        capabilities.code_lens_provider = None;
12287                    });
12288                    notify_server_capabilities_updated(&server, cx);
12289                }
12290                "textDocument/diagnostic" => {
12291                    let local = self
12292                        .as_local_mut()
12293                        .context("Expected LSP Store to be local")?;
12294
12295                    let state = local
12296                        .language_servers
12297                        .get_mut(&server_id)
12298                        .context("Could not obtain Language Servers state")?;
12299                    let options = local
12300                        .language_server_dynamic_registrations
12301                        .get_mut(&server_id)
12302                        .with_context(|| {
12303                            format!("Expected dynamic registration to exist for server {server_id}")
12304                        })?.diagnostics
12305                        .remove(&Some(unreg.id.clone()))
12306                        .with_context(|| format!(
12307                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12308                            unreg.id)
12309                        )?;
12310
12311                    let mut has_any_diagnostic_providers_still = true;
12312                    if let Some(identifier) = diagnostic_identifier(&options)
12313                        && let LanguageServerState::Running {
12314                            workspace_diagnostics_refresh_tasks,
12315                            ..
12316                        } = state
12317                    {
12318                        workspace_diagnostics_refresh_tasks.remove(&identifier);
12319                        has_any_diagnostic_providers_still =
12320                            !workspace_diagnostics_refresh_tasks.is_empty();
12321                    }
12322
12323                    if !has_any_diagnostic_providers_still {
12324                        server.update_capabilities(|capabilities| {
12325                            debug_assert!(capabilities.diagnostic_provider.is_some());
12326                            capabilities.diagnostic_provider = None;
12327                        });
12328                    }
12329
12330                    notify_server_capabilities_updated(&server, cx);
12331                }
12332                "textDocument/documentColor" => {
12333                    server.update_capabilities(|capabilities| {
12334                        capabilities.color_provider = None;
12335                    });
12336                    notify_server_capabilities_updated(&server, cx);
12337                }
12338                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12339            }
12340        }
12341
12342        Ok(())
12343    }
12344
12345    async fn deduplicate_range_based_lsp_requests<T>(
12346        lsp_store: &Entity<Self>,
12347        server_id: Option<LanguageServerId>,
12348        lsp_request_id: LspRequestId,
12349        proto_request: &T::ProtoRequest,
12350        range: Range<Anchor>,
12351        cx: &mut AsyncApp,
12352    ) -> Result<()>
12353    where
12354        T: LspCommand,
12355        T::ProtoRequest: proto::LspRequestMessage,
12356    {
12357        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12358        let version = deserialize_version(proto_request.buffer_version());
12359        let buffer = lsp_store.update(cx, |this, cx| {
12360            this.buffer_store.read(cx).get_existing(buffer_id)
12361        })??;
12362        buffer
12363            .update(cx, |buffer, _| buffer.wait_for_version(version))?
12364            .await?;
12365        lsp_store.update(cx, |lsp_store, cx| {
12366            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12367            let chunks_queried_for = lsp_data
12368                .inlay_hints
12369                .applicable_chunks(&[range])
12370                .collect::<Vec<_>>();
12371            match chunks_queried_for.as_slice() {
12372                &[chunk] => {
12373                    let key = LspKey {
12374                        request_type: TypeId::of::<T>(),
12375                        server_queried: server_id,
12376                    };
12377                    let previous_request = lsp_data
12378                        .chunk_lsp_requests
12379                        .entry(key)
12380                        .or_default()
12381                        .insert(chunk, lsp_request_id);
12382                    if let Some((previous_request, running_requests)) =
12383                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12384                    {
12385                        running_requests.remove(&previous_request);
12386                    }
12387                }
12388                _ambiguous_chunks => {
12389                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12390                    // there, a buffer version-based check will be performed and outdated requests discarded.
12391                }
12392            }
12393            anyhow::Ok(())
12394        })??;
12395
12396        Ok(())
12397    }
12398
12399    async fn query_lsp_locally<T>(
12400        lsp_store: Entity<Self>,
12401        for_server_id: Option<LanguageServerId>,
12402        sender_id: proto::PeerId,
12403        lsp_request_id: LspRequestId,
12404        proto_request: T::ProtoRequest,
12405        position: Option<Anchor>,
12406        cx: &mut AsyncApp,
12407    ) -> Result<()>
12408    where
12409        T: LspCommand + Clone,
12410        T::ProtoRequest: proto::LspRequestMessage,
12411        <T::ProtoRequest as proto::RequestMessage>::Response:
12412            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12413    {
12414        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12415        let version = deserialize_version(proto_request.buffer_version());
12416        let buffer = lsp_store.update(cx, |this, cx| {
12417            this.buffer_store.read(cx).get_existing(buffer_id)
12418        })??;
12419        buffer
12420            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))?
12421            .await?;
12422        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version())?;
12423        let request =
12424            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12425        let key = LspKey {
12426            request_type: TypeId::of::<T>(),
12427            server_queried: for_server_id,
12428        };
12429        lsp_store.update(cx, |lsp_store, cx| {
12430            let request_task = match for_server_id {
12431                Some(server_id) => {
12432                    let server_task = lsp_store.request_lsp(
12433                        buffer.clone(),
12434                        LanguageServerToQuery::Other(server_id),
12435                        request.clone(),
12436                        cx,
12437                    );
12438                    cx.background_spawn(async move {
12439                        let mut responses = Vec::new();
12440                        match server_task.await {
12441                            Ok(response) => responses.push((server_id, response)),
12442                            Err(e) => log::error!(
12443                                "Error handling response for request {request:?}: {e:#}"
12444                            ),
12445                        }
12446                        responses
12447                    })
12448                }
12449                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12450            };
12451            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12452            if T::ProtoRequest::stop_previous_requests() {
12453                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12454                    lsp_requests.clear();
12455                }
12456            }
12457            lsp_data.lsp_requests.entry(key).or_default().insert(
12458                lsp_request_id,
12459                cx.spawn(async move |lsp_store, cx| {
12460                    let response = request_task.await;
12461                    lsp_store
12462                        .update(cx, |lsp_store, cx| {
12463                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12464                            {
12465                                let response = response
12466                                    .into_iter()
12467                                    .map(|(server_id, response)| {
12468                                        (
12469                                            server_id.to_proto(),
12470                                            T::response_to_proto(
12471                                                response,
12472                                                lsp_store,
12473                                                sender_id,
12474                                                &buffer_version,
12475                                                cx,
12476                                            )
12477                                            .into(),
12478                                        )
12479                                    })
12480                                    .collect::<HashMap<_, _>>();
12481                                match client.send_lsp_response::<T::ProtoRequest>(
12482                                    project_id,
12483                                    lsp_request_id,
12484                                    response,
12485                                ) {
12486                                    Ok(()) => {}
12487                                    Err(e) => {
12488                                        log::error!("Failed to send LSP response: {e:#}",)
12489                                    }
12490                                }
12491                            }
12492                        })
12493                        .ok();
12494                }),
12495            );
12496        })?;
12497        Ok(())
12498    }
12499
12500    fn take_text_document_sync_options(
12501        capabilities: &mut lsp::ServerCapabilities,
12502    ) -> lsp::TextDocumentSyncOptions {
12503        match capabilities.text_document_sync.take() {
12504            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12505            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12506                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12507                sync_options.change = Some(sync_kind);
12508                sync_options
12509            }
12510            None => lsp::TextDocumentSyncOptions::default(),
12511        }
12512    }
12513
12514    #[cfg(any(test, feature = "test-support"))]
12515    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
12516        Some(
12517            self.lsp_data
12518                .get_mut(&buffer_id)?
12519                .code_lens
12520                .take()?
12521                .update
12522                .take()?
12523                .1,
12524        )
12525    }
12526
12527    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
12528        self.downstream_client.clone()
12529    }
12530
12531    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
12532        self.worktree_store.clone()
12533    }
12534
12535    /// Gets what's stored in the LSP data for the given buffer.
12536    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
12537        self.lsp_data.get_mut(&buffer_id)
12538    }
12539
12540    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
12541    /// new [`BufferLspData`] will be created to replace the previous state.
12542    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
12543        let (buffer_id, buffer_version) =
12544            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
12545        let lsp_data = self
12546            .lsp_data
12547            .entry(buffer_id)
12548            .or_insert_with(|| BufferLspData::new(buffer, cx));
12549        if buffer_version.changed_since(&lsp_data.buffer_version) {
12550            *lsp_data = BufferLspData::new(buffer, cx);
12551        }
12552        lsp_data
12553    }
12554}
12555
12556// Registration with registerOptions as null, should fallback to true.
12557// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
12558fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
12559    reg: lsp::Registration,
12560) -> Result<OneOf<bool, T>> {
12561    Ok(match reg.register_options {
12562        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
12563        None => OneOf::Left(true),
12564    })
12565}
12566
12567fn subscribe_to_binary_statuses(
12568    languages: &Arc<LanguageRegistry>,
12569    cx: &mut Context<'_, LspStore>,
12570) -> Task<()> {
12571    let mut server_statuses = languages.language_server_binary_statuses();
12572    cx.spawn(async move |lsp_store, cx| {
12573        while let Some((server_name, binary_status)) = server_statuses.next().await {
12574            if lsp_store
12575                .update(cx, |_, cx| {
12576                    let mut message = None;
12577                    let binary_status = match binary_status {
12578                        BinaryStatus::None => proto::ServerBinaryStatus::None,
12579                        BinaryStatus::CheckingForUpdate => {
12580                            proto::ServerBinaryStatus::CheckingForUpdate
12581                        }
12582                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
12583                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
12584                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
12585                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
12586                        BinaryStatus::Failed { error } => {
12587                            message = Some(error);
12588                            proto::ServerBinaryStatus::Failed
12589                        }
12590                    };
12591                    cx.emit(LspStoreEvent::LanguageServerUpdate {
12592                        // Binary updates are about the binary that might not have any language server id at that point.
12593                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
12594                        language_server_id: LanguageServerId(0),
12595                        name: Some(server_name),
12596                        message: proto::update_language_server::Variant::StatusUpdate(
12597                            proto::StatusUpdate {
12598                                message,
12599                                status: Some(proto::status_update::Status::Binary(
12600                                    binary_status as i32,
12601                                )),
12602                            },
12603                        ),
12604                    });
12605                })
12606                .is_err()
12607            {
12608                break;
12609            }
12610        }
12611    })
12612}
12613
12614fn lsp_workspace_diagnostics_refresh(
12615    registration_id: Option<String>,
12616    options: DiagnosticServerCapabilities,
12617    server: Arc<LanguageServer>,
12618    cx: &mut Context<'_, LspStore>,
12619) -> Option<WorkspaceRefreshTask> {
12620    let identifier = diagnostic_identifier(&options)?;
12621
12622    let (progress_tx, mut progress_rx) = mpsc::channel(1);
12623    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
12624    refresh_tx.try_send(()).ok();
12625
12626    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
12627        let mut attempts = 0;
12628        let max_attempts = 50;
12629        let mut requests = 0;
12630
12631        loop {
12632            let Some(()) = refresh_rx.recv().await else {
12633                return;
12634            };
12635
12636            'request: loop {
12637                requests += 1;
12638                if attempts > max_attempts {
12639                    log::error!(
12640                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
12641                    );
12642                    return;
12643                }
12644                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
12645                cx.background_executor()
12646                    .timer(Duration::from_millis(backoff_millis))
12647                    .await;
12648                attempts += 1;
12649
12650                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
12651                    lsp_store
12652                        .all_result_ids(server.server_id())
12653                        .into_iter()
12654                        .filter_map(|(abs_path, result_id)| {
12655                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
12656                            Some(lsp::PreviousResultId {
12657                                uri,
12658                                value: result_id,
12659                            })
12660                        })
12661                        .collect()
12662                }) else {
12663                    return;
12664                };
12665
12666                let token = if let Some(identifier) = &registration_id {
12667                    format!(
12668                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{identifier}",
12669                        server.server_id(),
12670                    )
12671                } else {
12672                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
12673                };
12674
12675                progress_rx.try_recv().ok();
12676                let timer =
12677                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
12678                let progress = pin!(progress_rx.recv().fuse());
12679                let response_result = server
12680                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
12681                        lsp::WorkspaceDiagnosticParams {
12682                            previous_result_ids,
12683                            identifier: identifier.clone(),
12684                            work_done_progress_params: Default::default(),
12685                            partial_result_params: lsp::PartialResultParams {
12686                                partial_result_token: Some(lsp::ProgressToken::String(token)),
12687                            },
12688                        },
12689                        select(timer, progress).then(|either| match either {
12690                            Either::Left((message, ..)) => ready(message).left_future(),
12691                            Either::Right(..) => pending::<String>().right_future(),
12692                        }),
12693                    )
12694                    .await;
12695
12696                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
12697                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
12698                match response_result {
12699                    ConnectionResult::Timeout => {
12700                        log::error!("Timeout during workspace diagnostics pull");
12701                        continue 'request;
12702                    }
12703                    ConnectionResult::ConnectionReset => {
12704                        log::error!("Server closed a workspace diagnostics pull request");
12705                        continue 'request;
12706                    }
12707                    ConnectionResult::Result(Err(e)) => {
12708                        log::error!("Error during workspace diagnostics pull: {e:#}");
12709                        break 'request;
12710                    }
12711                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
12712                        attempts = 0;
12713                        if lsp_store
12714                            .update(cx, |lsp_store, cx| {
12715                                lsp_store.apply_workspace_diagnostic_report(
12716                                    server.server_id(),
12717                                    pulled_diagnostics,
12718                                    cx,
12719                                )
12720                            })
12721                            .is_err()
12722                        {
12723                            return;
12724                        }
12725                        break 'request;
12726                    }
12727                }
12728            }
12729        }
12730    });
12731
12732    Some(WorkspaceRefreshTask {
12733        refresh_tx,
12734        progress_tx,
12735        task: workspace_query_language_server,
12736    })
12737}
12738
12739fn diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<Option<String>> {
12740    match &options {
12741        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
12742            if !diagnostic_options.workspace_diagnostics {
12743                return None;
12744            }
12745            Some(diagnostic_options.identifier.clone())
12746        }
12747        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
12748            let diagnostic_options = &registration_options.diagnostic_options;
12749            if !diagnostic_options.workspace_diagnostics {
12750                return None;
12751            }
12752            Some(diagnostic_options.identifier.clone())
12753        }
12754    }
12755}
12756
12757fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
12758    let CompletionSource::BufferWord {
12759        word_range,
12760        resolved,
12761    } = &mut completion.source
12762    else {
12763        return;
12764    };
12765    if *resolved {
12766        return;
12767    }
12768
12769    if completion.new_text
12770        != snapshot
12771            .text_for_range(word_range.clone())
12772            .collect::<String>()
12773    {
12774        return;
12775    }
12776
12777    let mut offset = 0;
12778    for chunk in snapshot.chunks(word_range.clone(), true) {
12779        let end_offset = offset + chunk.text.len();
12780        if let Some(highlight_id) = chunk.syntax_highlight_id {
12781            completion
12782                .label
12783                .runs
12784                .push((offset..end_offset, highlight_id));
12785        }
12786        offset = end_offset;
12787    }
12788    *resolved = true;
12789}
12790
12791impl EventEmitter<LspStoreEvent> for LspStore {}
12792
12793fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
12794    hover
12795        .contents
12796        .retain(|hover_block| !hover_block.text.trim().is_empty());
12797    if hover.contents.is_empty() {
12798        None
12799    } else {
12800        Some(hover)
12801    }
12802}
12803
12804async fn populate_labels_for_completions(
12805    new_completions: Vec<CoreCompletion>,
12806    language: Option<Arc<Language>>,
12807    lsp_adapter: Option<Arc<CachedLspAdapter>>,
12808) -> Vec<Completion> {
12809    let lsp_completions = new_completions
12810        .iter()
12811        .filter_map(|new_completion| {
12812            new_completion
12813                .source
12814                .lsp_completion(true)
12815                .map(|lsp_completion| lsp_completion.into_owned())
12816        })
12817        .collect::<Vec<_>>();
12818
12819    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
12820        lsp_adapter
12821            .labels_for_completions(&lsp_completions, language)
12822            .await
12823            .log_err()
12824            .unwrap_or_default()
12825    } else {
12826        Vec::new()
12827    }
12828    .into_iter()
12829    .fuse();
12830
12831    let mut completions = Vec::new();
12832    for completion in new_completions {
12833        match completion.source.lsp_completion(true) {
12834            Some(lsp_completion) => {
12835                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
12836
12837                let mut label = labels.next().flatten().unwrap_or_else(|| {
12838                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
12839                });
12840                ensure_uniform_list_compatible_label(&mut label);
12841                completions.push(Completion {
12842                    label,
12843                    documentation,
12844                    replace_range: completion.replace_range,
12845                    new_text: completion.new_text,
12846                    insert_text_mode: lsp_completion.insert_text_mode,
12847                    source: completion.source,
12848                    icon_path: None,
12849                    confirm: None,
12850                });
12851            }
12852            None => {
12853                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
12854                ensure_uniform_list_compatible_label(&mut label);
12855                completions.push(Completion {
12856                    label,
12857                    documentation: None,
12858                    replace_range: completion.replace_range,
12859                    new_text: completion.new_text,
12860                    source: completion.source,
12861                    insert_text_mode: None,
12862                    icon_path: None,
12863                    confirm: None,
12864                });
12865            }
12866        }
12867    }
12868    completions
12869}
12870
12871#[derive(Debug)]
12872pub enum LanguageServerToQuery {
12873    /// Query language servers in order of users preference, up until one capable of handling the request is found.
12874    FirstCapable,
12875    /// Query a specific language server.
12876    Other(LanguageServerId),
12877}
12878
12879#[derive(Default)]
12880struct RenamePathsWatchedForServer {
12881    did_rename: Vec<RenameActionPredicate>,
12882    will_rename: Vec<RenameActionPredicate>,
12883}
12884
12885impl RenamePathsWatchedForServer {
12886    fn with_did_rename_patterns(
12887        mut self,
12888        did_rename: Option<&FileOperationRegistrationOptions>,
12889    ) -> Self {
12890        if let Some(did_rename) = did_rename {
12891            self.did_rename = did_rename
12892                .filters
12893                .iter()
12894                .filter_map(|filter| filter.try_into().log_err())
12895                .collect();
12896        }
12897        self
12898    }
12899    fn with_will_rename_patterns(
12900        mut self,
12901        will_rename: Option<&FileOperationRegistrationOptions>,
12902    ) -> Self {
12903        if let Some(will_rename) = will_rename {
12904            self.will_rename = will_rename
12905                .filters
12906                .iter()
12907                .filter_map(|filter| filter.try_into().log_err())
12908                .collect();
12909        }
12910        self
12911    }
12912
12913    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
12914        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
12915    }
12916    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
12917        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
12918    }
12919}
12920
12921impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
12922    type Error = globset::Error;
12923    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
12924        Ok(Self {
12925            kind: ops.pattern.matches.clone(),
12926            glob: GlobBuilder::new(&ops.pattern.glob)
12927                .case_insensitive(
12928                    ops.pattern
12929                        .options
12930                        .as_ref()
12931                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
12932                )
12933                .build()?
12934                .compile_matcher(),
12935        })
12936    }
12937}
12938struct RenameActionPredicate {
12939    glob: GlobMatcher,
12940    kind: Option<FileOperationPatternKind>,
12941}
12942
12943impl RenameActionPredicate {
12944    // Returns true if language server should be notified
12945    fn eval(&self, path: &str, is_dir: bool) -> bool {
12946        self.kind.as_ref().is_none_or(|kind| {
12947            let expected_kind = if is_dir {
12948                FileOperationPatternKind::Folder
12949            } else {
12950                FileOperationPatternKind::File
12951            };
12952            kind == &expected_kind
12953        }) && self.glob.is_match(path)
12954    }
12955}
12956
12957#[derive(Default)]
12958struct LanguageServerWatchedPaths {
12959    worktree_paths: HashMap<WorktreeId, GlobSet>,
12960    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
12961}
12962
12963#[derive(Default)]
12964struct LanguageServerWatchedPathsBuilder {
12965    worktree_paths: HashMap<WorktreeId, GlobSet>,
12966    abs_paths: HashMap<Arc<Path>, GlobSet>,
12967}
12968
12969impl LanguageServerWatchedPathsBuilder {
12970    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
12971        self.worktree_paths.insert(worktree_id, glob_set);
12972    }
12973    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
12974        self.abs_paths.insert(path, glob_set);
12975    }
12976    fn build(
12977        self,
12978        fs: Arc<dyn Fs>,
12979        language_server_id: LanguageServerId,
12980        cx: &mut Context<LspStore>,
12981    ) -> LanguageServerWatchedPaths {
12982        let lsp_store = cx.weak_entity();
12983
12984        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
12985        let abs_paths = self
12986            .abs_paths
12987            .into_iter()
12988            .map(|(abs_path, globset)| {
12989                let task = cx.spawn({
12990                    let abs_path = abs_path.clone();
12991                    let fs = fs.clone();
12992
12993                    let lsp_store = lsp_store.clone();
12994                    async move |_, cx| {
12995                        maybe!(async move {
12996                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
12997                            while let Some(update) = push_updates.0.next().await {
12998                                let action = lsp_store
12999                                    .update(cx, |this, _| {
13000                                        let Some(local) = this.as_local() else {
13001                                            return ControlFlow::Break(());
13002                                        };
13003                                        let Some(watcher) = local
13004                                            .language_server_watched_paths
13005                                            .get(&language_server_id)
13006                                        else {
13007                                            return ControlFlow::Break(());
13008                                        };
13009                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13010                                            "Watched abs path is not registered with a watcher",
13011                                        );
13012                                        let matching_entries = update
13013                                            .into_iter()
13014                                            .filter(|event| globs.is_match(&event.path))
13015                                            .collect::<Vec<_>>();
13016                                        this.lsp_notify_abs_paths_changed(
13017                                            language_server_id,
13018                                            matching_entries,
13019                                        );
13020                                        ControlFlow::Continue(())
13021                                    })
13022                                    .ok()?;
13023
13024                                if action.is_break() {
13025                                    break;
13026                                }
13027                            }
13028                            Some(())
13029                        })
13030                        .await;
13031                    }
13032                });
13033                (abs_path, (globset, task))
13034            })
13035            .collect();
13036        LanguageServerWatchedPaths {
13037            worktree_paths: self.worktree_paths,
13038            abs_paths,
13039        }
13040    }
13041}
13042
13043struct LspBufferSnapshot {
13044    version: i32,
13045    snapshot: TextBufferSnapshot,
13046}
13047
13048/// A prompt requested by LSP server.
13049#[derive(Clone, Debug)]
13050pub struct LanguageServerPromptRequest {
13051    pub level: PromptLevel,
13052    pub message: String,
13053    pub actions: Vec<MessageActionItem>,
13054    pub lsp_name: String,
13055    pub(crate) response_channel: Sender<MessageActionItem>,
13056}
13057
13058impl LanguageServerPromptRequest {
13059    pub async fn respond(self, index: usize) -> Option<()> {
13060        if let Some(response) = self.actions.into_iter().nth(index) {
13061            self.response_channel.send(response).await.ok()
13062        } else {
13063            None
13064        }
13065    }
13066}
13067impl PartialEq for LanguageServerPromptRequest {
13068    fn eq(&self, other: &Self) -> bool {
13069        self.message == other.message && self.actions == other.actions
13070    }
13071}
13072
13073#[derive(Clone, Debug, PartialEq)]
13074pub enum LanguageServerLogType {
13075    Log(MessageType),
13076    Trace { verbose_info: Option<String> },
13077    Rpc { received: bool },
13078}
13079
13080impl LanguageServerLogType {
13081    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13082        match self {
13083            Self::Log(log_type) => {
13084                use proto::log_message::LogLevel;
13085                let level = match *log_type {
13086                    MessageType::ERROR => LogLevel::Error,
13087                    MessageType::WARNING => LogLevel::Warning,
13088                    MessageType::INFO => LogLevel::Info,
13089                    MessageType::LOG => LogLevel::Log,
13090                    other => {
13091                        log::warn!("Unknown lsp log message type: {other:?}");
13092                        LogLevel::Log
13093                    }
13094                };
13095                proto::language_server_log::LogType::Log(proto::LogMessage {
13096                    level: level as i32,
13097                })
13098            }
13099            Self::Trace { verbose_info } => {
13100                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13101                    verbose_info: verbose_info.to_owned(),
13102                })
13103            }
13104            Self::Rpc { received } => {
13105                let kind = if *received {
13106                    proto::rpc_message::Kind::Received
13107                } else {
13108                    proto::rpc_message::Kind::Sent
13109                };
13110                let kind = kind as i32;
13111                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13112            }
13113        }
13114    }
13115
13116    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13117        use proto::log_message::LogLevel;
13118        use proto::rpc_message;
13119        match log_type {
13120            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13121                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13122                    LogLevel::Error => MessageType::ERROR,
13123                    LogLevel::Warning => MessageType::WARNING,
13124                    LogLevel::Info => MessageType::INFO,
13125                    LogLevel::Log => MessageType::LOG,
13126                },
13127            ),
13128            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13129                verbose_info: trace_message.verbose_info,
13130            },
13131            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13132                received: match rpc_message::Kind::from_i32(message.kind)
13133                    .unwrap_or(rpc_message::Kind::Received)
13134                {
13135                    rpc_message::Kind::Received => true,
13136                    rpc_message::Kind::Sent => false,
13137                },
13138            },
13139        }
13140    }
13141}
13142
13143pub struct WorkspaceRefreshTask {
13144    refresh_tx: mpsc::Sender<()>,
13145    progress_tx: mpsc::Sender<()>,
13146    #[allow(dead_code)]
13147    task: Task<()>,
13148}
13149
13150pub enum LanguageServerState {
13151    Starting {
13152        startup: Task<Option<Arc<LanguageServer>>>,
13153        /// List of language servers that will be added to the workspace once it's initialization completes.
13154        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13155    },
13156
13157    Running {
13158        adapter: Arc<CachedLspAdapter>,
13159        server: Arc<LanguageServer>,
13160        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13161        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13162    },
13163}
13164
13165impl LanguageServerState {
13166    fn add_workspace_folder(&self, uri: Uri) {
13167        match self {
13168            LanguageServerState::Starting {
13169                pending_workspace_folders,
13170                ..
13171            } => {
13172                pending_workspace_folders.lock().insert(uri);
13173            }
13174            LanguageServerState::Running { server, .. } => {
13175                server.add_workspace_folder(uri);
13176            }
13177        }
13178    }
13179    fn _remove_workspace_folder(&self, uri: Uri) {
13180        match self {
13181            LanguageServerState::Starting {
13182                pending_workspace_folders,
13183                ..
13184            } => {
13185                pending_workspace_folders.lock().remove(&uri);
13186            }
13187            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13188        }
13189    }
13190}
13191
13192impl std::fmt::Debug for LanguageServerState {
13193    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13194        match self {
13195            LanguageServerState::Starting { .. } => {
13196                f.debug_struct("LanguageServerState::Starting").finish()
13197            }
13198            LanguageServerState::Running { .. } => {
13199                f.debug_struct("LanguageServerState::Running").finish()
13200            }
13201        }
13202    }
13203}
13204
13205#[derive(Clone, Debug, Serialize)]
13206pub struct LanguageServerProgress {
13207    pub is_disk_based_diagnostics_progress: bool,
13208    pub is_cancellable: bool,
13209    pub title: Option<String>,
13210    pub message: Option<String>,
13211    pub percentage: Option<usize>,
13212    #[serde(skip_serializing)]
13213    pub last_update_at: Instant,
13214}
13215
13216#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13217pub struct DiagnosticSummary {
13218    pub error_count: usize,
13219    pub warning_count: usize,
13220}
13221
13222impl DiagnosticSummary {
13223    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13224        let mut this = Self {
13225            error_count: 0,
13226            warning_count: 0,
13227        };
13228
13229        for entry in diagnostics {
13230            if entry.diagnostic.is_primary {
13231                match entry.diagnostic.severity {
13232                    DiagnosticSeverity::ERROR => this.error_count += 1,
13233                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13234                    _ => {}
13235                }
13236            }
13237        }
13238
13239        this
13240    }
13241
13242    pub fn is_empty(&self) -> bool {
13243        self.error_count == 0 && self.warning_count == 0
13244    }
13245
13246    pub fn to_proto(
13247        self,
13248        language_server_id: LanguageServerId,
13249        path: &RelPath,
13250    ) -> proto::DiagnosticSummary {
13251        proto::DiagnosticSummary {
13252            path: path.to_proto(),
13253            language_server_id: language_server_id.0 as u64,
13254            error_count: self.error_count as u32,
13255            warning_count: self.warning_count as u32,
13256        }
13257    }
13258}
13259
13260#[derive(Clone, Debug)]
13261pub enum CompletionDocumentation {
13262    /// There is no documentation for this completion.
13263    Undocumented,
13264    /// A single line of documentation.
13265    SingleLine(SharedString),
13266    /// Multiple lines of plain text documentation.
13267    MultiLinePlainText(SharedString),
13268    /// Markdown documentation.
13269    MultiLineMarkdown(SharedString),
13270    /// Both single line and multiple lines of plain text documentation.
13271    SingleLineAndMultiLinePlainText {
13272        single_line: SharedString,
13273        plain_text: Option<SharedString>,
13274    },
13275}
13276
13277impl CompletionDocumentation {
13278    #[cfg(any(test, feature = "test-support"))]
13279    pub fn text(&self) -> SharedString {
13280        match self {
13281            CompletionDocumentation::Undocumented => "".into(),
13282            CompletionDocumentation::SingleLine(s) => s.clone(),
13283            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13284            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13285            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13286                single_line.clone()
13287            }
13288        }
13289    }
13290}
13291
13292impl From<lsp::Documentation> for CompletionDocumentation {
13293    fn from(docs: lsp::Documentation) -> Self {
13294        match docs {
13295            lsp::Documentation::String(text) => {
13296                if text.lines().count() <= 1 {
13297                    CompletionDocumentation::SingleLine(text.into())
13298                } else {
13299                    CompletionDocumentation::MultiLinePlainText(text.into())
13300                }
13301            }
13302
13303            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13304                lsp::MarkupKind::PlainText => {
13305                    if value.lines().count() <= 1 {
13306                        CompletionDocumentation::SingleLine(value.into())
13307                    } else {
13308                        CompletionDocumentation::MultiLinePlainText(value.into())
13309                    }
13310                }
13311
13312                lsp::MarkupKind::Markdown => {
13313                    CompletionDocumentation::MultiLineMarkdown(value.into())
13314                }
13315            },
13316        }
13317    }
13318}
13319
13320pub enum ResolvedHint {
13321    Resolved(InlayHint),
13322    Resolving(Shared<Task<()>>),
13323}
13324
13325fn glob_literal_prefix(glob: &Path) -> PathBuf {
13326    glob.components()
13327        .take_while(|component| match component {
13328            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13329            _ => true,
13330        })
13331        .collect()
13332}
13333
13334pub struct SshLspAdapter {
13335    name: LanguageServerName,
13336    binary: LanguageServerBinary,
13337    initialization_options: Option<String>,
13338    code_action_kinds: Option<Vec<CodeActionKind>>,
13339}
13340
13341impl SshLspAdapter {
13342    pub fn new(
13343        name: LanguageServerName,
13344        binary: LanguageServerBinary,
13345        initialization_options: Option<String>,
13346        code_action_kinds: Option<String>,
13347    ) -> Self {
13348        Self {
13349            name,
13350            binary,
13351            initialization_options,
13352            code_action_kinds: code_action_kinds
13353                .as_ref()
13354                .and_then(|c| serde_json::from_str(c).ok()),
13355        }
13356    }
13357}
13358
13359impl LspInstaller for SshLspAdapter {
13360    type BinaryVersion = ();
13361    async fn check_if_user_installed(
13362        &self,
13363        _: &dyn LspAdapterDelegate,
13364        _: Option<Toolchain>,
13365        _: &AsyncApp,
13366    ) -> Option<LanguageServerBinary> {
13367        Some(self.binary.clone())
13368    }
13369
13370    async fn cached_server_binary(
13371        &self,
13372        _: PathBuf,
13373        _: &dyn LspAdapterDelegate,
13374    ) -> Option<LanguageServerBinary> {
13375        None
13376    }
13377
13378    async fn fetch_latest_server_version(
13379        &self,
13380        _: &dyn LspAdapterDelegate,
13381        _: bool,
13382        _: &mut AsyncApp,
13383    ) -> Result<()> {
13384        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13385    }
13386
13387    async fn fetch_server_binary(
13388        &self,
13389        _: (),
13390        _: PathBuf,
13391        _: &dyn LspAdapterDelegate,
13392    ) -> Result<LanguageServerBinary> {
13393        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13394    }
13395}
13396
13397#[async_trait(?Send)]
13398impl LspAdapter for SshLspAdapter {
13399    fn name(&self) -> LanguageServerName {
13400        self.name.clone()
13401    }
13402
13403    async fn initialization_options(
13404        self: Arc<Self>,
13405        _: &Arc<dyn LspAdapterDelegate>,
13406    ) -> Result<Option<serde_json::Value>> {
13407        let Some(options) = &self.initialization_options else {
13408            return Ok(None);
13409        };
13410        let result = serde_json::from_str(options)?;
13411        Ok(result)
13412    }
13413
13414    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13415        self.code_action_kinds.clone()
13416    }
13417}
13418
13419pub fn language_server_settings<'a>(
13420    delegate: &'a dyn LspAdapterDelegate,
13421    language: &LanguageServerName,
13422    cx: &'a App,
13423) -> Option<&'a LspSettings> {
13424    language_server_settings_for(
13425        SettingsLocation {
13426            worktree_id: delegate.worktree_id(),
13427            path: RelPath::empty(),
13428        },
13429        language,
13430        cx,
13431    )
13432}
13433
13434pub(crate) fn language_server_settings_for<'a>(
13435    location: SettingsLocation<'a>,
13436    language: &LanguageServerName,
13437    cx: &'a App,
13438) -> Option<&'a LspSettings> {
13439    ProjectSettings::get(Some(location), cx).lsp.get(language)
13440}
13441
13442pub struct LocalLspAdapterDelegate {
13443    lsp_store: WeakEntity<LspStore>,
13444    worktree: worktree::Snapshot,
13445    fs: Arc<dyn Fs>,
13446    http_client: Arc<dyn HttpClient>,
13447    language_registry: Arc<LanguageRegistry>,
13448    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13449}
13450
13451impl LocalLspAdapterDelegate {
13452    pub fn new(
13453        language_registry: Arc<LanguageRegistry>,
13454        environment: &Entity<ProjectEnvironment>,
13455        lsp_store: WeakEntity<LspStore>,
13456        worktree: &Entity<Worktree>,
13457        http_client: Arc<dyn HttpClient>,
13458        fs: Arc<dyn Fs>,
13459        cx: &mut App,
13460    ) -> Arc<Self> {
13461        let load_shell_env_task =
13462            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
13463
13464        Arc::new(Self {
13465            lsp_store,
13466            worktree: worktree.read(cx).snapshot(),
13467            fs,
13468            http_client,
13469            language_registry,
13470            load_shell_env_task,
13471        })
13472    }
13473
13474    fn from_local_lsp(
13475        local: &LocalLspStore,
13476        worktree: &Entity<Worktree>,
13477        cx: &mut App,
13478    ) -> Arc<Self> {
13479        Self::new(
13480            local.languages.clone(),
13481            &local.environment,
13482            local.weak.clone(),
13483            worktree,
13484            local.http_client.clone(),
13485            local.fs.clone(),
13486            cx,
13487        )
13488    }
13489}
13490
13491#[async_trait]
13492impl LspAdapterDelegate for LocalLspAdapterDelegate {
13493    fn show_notification(&self, message: &str, cx: &mut App) {
13494        self.lsp_store
13495            .update(cx, |_, cx| {
13496                cx.emit(LspStoreEvent::Notification(message.to_owned()))
13497            })
13498            .ok();
13499    }
13500
13501    fn http_client(&self) -> Arc<dyn HttpClient> {
13502        self.http_client.clone()
13503    }
13504
13505    fn worktree_id(&self) -> WorktreeId {
13506        self.worktree.id()
13507    }
13508
13509    fn worktree_root_path(&self) -> &Path {
13510        self.worktree.abs_path().as_ref()
13511    }
13512
13513    async fn shell_env(&self) -> HashMap<String, String> {
13514        let task = self.load_shell_env_task.clone();
13515        task.await.unwrap_or_default()
13516    }
13517
13518    async fn npm_package_installed_version(
13519        &self,
13520        package_name: &str,
13521    ) -> Result<Option<(PathBuf, String)>> {
13522        let local_package_directory = self.worktree_root_path();
13523        let node_modules_directory = local_package_directory.join("node_modules");
13524
13525        if let Some(version) =
13526            read_package_installed_version(node_modules_directory.clone(), package_name).await?
13527        {
13528            return Ok(Some((node_modules_directory, version)));
13529        }
13530        let Some(npm) = self.which("npm".as_ref()).await else {
13531            log::warn!(
13532                "Failed to find npm executable for {:?}",
13533                local_package_directory
13534            );
13535            return Ok(None);
13536        };
13537
13538        let env = self.shell_env().await;
13539        let output = util::command::new_smol_command(&npm)
13540            .args(["root", "-g"])
13541            .envs(env)
13542            .current_dir(local_package_directory)
13543            .output()
13544            .await?;
13545        let global_node_modules =
13546            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
13547
13548        if let Some(version) =
13549            read_package_installed_version(global_node_modules.clone(), package_name).await?
13550        {
13551            return Ok(Some((global_node_modules, version)));
13552        }
13553        return Ok(None);
13554    }
13555
13556    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
13557        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
13558        if self.fs.is_file(&worktree_abs_path).await {
13559            worktree_abs_path.pop();
13560        }
13561
13562        let env = self.shell_env().await;
13563
13564        let shell_path = env.get("PATH").cloned();
13565
13566        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
13567    }
13568
13569    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
13570        let mut working_dir = self.worktree_root_path().to_path_buf();
13571        if self.fs.is_file(&working_dir).await {
13572            working_dir.pop();
13573        }
13574        let output = util::command::new_smol_command(&command.path)
13575            .args(command.arguments)
13576            .envs(command.env.clone().unwrap_or_default())
13577            .current_dir(working_dir)
13578            .output()
13579            .await?;
13580
13581        anyhow::ensure!(
13582            output.status.success(),
13583            "{}, stdout: {:?}, stderr: {:?}",
13584            output.status,
13585            String::from_utf8_lossy(&output.stdout),
13586            String::from_utf8_lossy(&output.stderr)
13587        );
13588        Ok(())
13589    }
13590
13591    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
13592        self.language_registry
13593            .update_lsp_binary_status(server_name, status);
13594    }
13595
13596    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
13597        self.language_registry
13598            .all_lsp_adapters()
13599            .into_iter()
13600            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
13601            .collect()
13602    }
13603
13604    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
13605        let dir = self.language_registry.language_server_download_dir(name)?;
13606
13607        if !dir.exists() {
13608            smol::fs::create_dir_all(&dir)
13609                .await
13610                .context("failed to create container directory")
13611                .log_err()?;
13612        }
13613
13614        Some(dir)
13615    }
13616
13617    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
13618        let entry = self
13619            .worktree
13620            .entry_for_path(path)
13621            .with_context(|| format!("no worktree entry for path {path:?}"))?;
13622        let abs_path = self.worktree.absolutize(&entry.path);
13623        self.fs.load(&abs_path).await
13624    }
13625}
13626
13627async fn populate_labels_for_symbols(
13628    symbols: Vec<CoreSymbol>,
13629    language_registry: &Arc<LanguageRegistry>,
13630    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13631    output: &mut Vec<Symbol>,
13632) {
13633    #[allow(clippy::mutable_key_type)]
13634    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
13635
13636    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
13637    for symbol in symbols {
13638        let Some(file_name) = symbol.path.file_name() else {
13639            continue;
13640        };
13641        let language = language_registry
13642            .load_language_for_file_path(Path::new(file_name))
13643            .await
13644            .ok()
13645            .or_else(|| {
13646                unknown_paths.insert(file_name.into());
13647                None
13648            });
13649        symbols_by_language
13650            .entry(language)
13651            .or_default()
13652            .push(symbol);
13653    }
13654
13655    for unknown_path in unknown_paths {
13656        log::info!("no language found for symbol in file {unknown_path:?}");
13657    }
13658
13659    let mut label_params = Vec::new();
13660    for (language, mut symbols) in symbols_by_language {
13661        label_params.clear();
13662        label_params.extend(
13663            symbols
13664                .iter_mut()
13665                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
13666        );
13667
13668        let mut labels = Vec::new();
13669        if let Some(language) = language {
13670            let lsp_adapter = lsp_adapter.clone().or_else(|| {
13671                language_registry
13672                    .lsp_adapters(&language.name())
13673                    .first()
13674                    .cloned()
13675            });
13676            if let Some(lsp_adapter) = lsp_adapter {
13677                labels = lsp_adapter
13678                    .labels_for_symbols(&label_params, &language)
13679                    .await
13680                    .log_err()
13681                    .unwrap_or_default();
13682            }
13683        }
13684
13685        for ((symbol, (name, _)), label) in symbols
13686            .into_iter()
13687            .zip(label_params.drain(..))
13688            .zip(labels.into_iter().chain(iter::repeat(None)))
13689        {
13690            output.push(Symbol {
13691                language_server_name: symbol.language_server_name,
13692                source_worktree_id: symbol.source_worktree_id,
13693                source_language_server_id: symbol.source_language_server_id,
13694                path: symbol.path,
13695                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
13696                name,
13697                kind: symbol.kind,
13698                range: symbol.range,
13699            });
13700        }
13701    }
13702}
13703
13704fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
13705    match server.capabilities().text_document_sync.as_ref()? {
13706        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
13707            // Server wants didSave but didn't specify includeText.
13708            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
13709            // Server doesn't want didSave at all.
13710            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
13711            // Server provided SaveOptions.
13712            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
13713                Some(save_options.include_text.unwrap_or(false))
13714            }
13715        },
13716        // We do not have any save info. Kind affects didChange only.
13717        lsp::TextDocumentSyncCapability::Kind(_) => None,
13718    }
13719}
13720
13721/// Completion items are displayed in a `UniformList`.
13722/// Usually, those items are single-line strings, but in LSP responses,
13723/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
13724/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
13725/// 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,
13726/// breaking the completions menu presentation.
13727///
13728/// 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.
13729fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
13730    let mut new_text = String::with_capacity(label.text.len());
13731    let mut offset_map = vec![0; label.text.len() + 1];
13732    let mut last_char_was_space = false;
13733    let mut new_idx = 0;
13734    let chars = label.text.char_indices().fuse();
13735    let mut newlines_removed = false;
13736
13737    for (idx, c) in chars {
13738        offset_map[idx] = new_idx;
13739
13740        match c {
13741            '\n' if last_char_was_space => {
13742                newlines_removed = true;
13743            }
13744            '\t' | ' ' if last_char_was_space => {}
13745            '\n' if !last_char_was_space => {
13746                new_text.push(' ');
13747                new_idx += 1;
13748                last_char_was_space = true;
13749                newlines_removed = true;
13750            }
13751            ' ' | '\t' => {
13752                new_text.push(' ');
13753                new_idx += 1;
13754                last_char_was_space = true;
13755            }
13756            _ => {
13757                new_text.push(c);
13758                new_idx += c.len_utf8();
13759                last_char_was_space = false;
13760            }
13761        }
13762    }
13763    offset_map[label.text.len()] = new_idx;
13764
13765    // Only modify the label if newlines were removed.
13766    if !newlines_removed {
13767        return;
13768    }
13769
13770    let last_index = new_idx;
13771    let mut run_ranges_errors = Vec::new();
13772    label.runs.retain_mut(|(range, _)| {
13773        match offset_map.get(range.start) {
13774            Some(&start) => range.start = start,
13775            None => {
13776                run_ranges_errors.push(range.clone());
13777                return false;
13778            }
13779        }
13780
13781        match offset_map.get(range.end) {
13782            Some(&end) => range.end = end,
13783            None => {
13784                run_ranges_errors.push(range.clone());
13785                range.end = last_index;
13786            }
13787        }
13788        true
13789    });
13790    if !run_ranges_errors.is_empty() {
13791        log::error!(
13792            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
13793            label.text
13794        );
13795    }
13796
13797    let mut wrong_filter_range = None;
13798    if label.filter_range == (0..label.text.len()) {
13799        label.filter_range = 0..new_text.len();
13800    } else {
13801        let mut original_filter_range = Some(label.filter_range.clone());
13802        match offset_map.get(label.filter_range.start) {
13803            Some(&start) => label.filter_range.start = start,
13804            None => {
13805                wrong_filter_range = original_filter_range.take();
13806                label.filter_range.start = last_index;
13807            }
13808        }
13809
13810        match offset_map.get(label.filter_range.end) {
13811            Some(&end) => label.filter_range.end = end,
13812            None => {
13813                wrong_filter_range = original_filter_range.take();
13814                label.filter_range.end = last_index;
13815            }
13816        }
13817    }
13818    if let Some(wrong_filter_range) = wrong_filter_range {
13819        log::error!(
13820            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
13821            label.text
13822        );
13823    }
13824
13825    label.text = new_text;
13826}
13827
13828#[cfg(test)]
13829mod tests {
13830    use language::HighlightId;
13831
13832    use super::*;
13833
13834    #[test]
13835    fn test_glob_literal_prefix() {
13836        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
13837        assert_eq!(
13838            glob_literal_prefix(Path::new("node_modules/**/*.js")),
13839            Path::new("node_modules")
13840        );
13841        assert_eq!(
13842            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13843            Path::new("foo")
13844        );
13845        assert_eq!(
13846            glob_literal_prefix(Path::new("foo/bar/baz.js")),
13847            Path::new("foo/bar/baz.js")
13848        );
13849
13850        #[cfg(target_os = "windows")]
13851        {
13852            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
13853            assert_eq!(
13854                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
13855                Path::new("node_modules")
13856            );
13857            assert_eq!(
13858                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13859                Path::new("foo")
13860            );
13861            assert_eq!(
13862                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
13863                Path::new("foo/bar/baz.js")
13864            );
13865        }
13866    }
13867
13868    #[test]
13869    fn test_multi_len_chars_normalization() {
13870        let mut label = CodeLabel::new(
13871            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
13872            0..6,
13873            vec![(0..6, HighlightId(1))],
13874        );
13875        ensure_uniform_list_compatible_label(&mut label);
13876        assert_eq!(
13877            label,
13878            CodeLabel::new(
13879                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
13880                0..6,
13881                vec![(0..6, HighlightId(1))],
13882            )
13883        );
13884    }
13885}