lsp_store.rs

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