1//! LSP store provides unified access to the language server protocol.
    2//! The consumers of LSP store can interact with language servers without knowing exactly which language server they're interacting with.
    3//!
    4//! # Local/Remote LSP Stores
    5//! This module is split up into three distinct parts:
    6//! - [`LocalLspStore`], which is ran on the host machine (either project host or SSH host), that manages the lifecycle of language servers.
    7//! - [`RemoteLspStore`], which is ran on the remote machine (project guests) which is mostly about passing through the requests via RPC.
    8//!   The remote stores don't really care about which language server they're running against - they don't usually get to decide which language server is going to responsible for handling their request.
    9//! - [`LspStore`], which unifies the two under one consistent interface for interacting with language servers.
   10//!
   11//! Most of the interesting work happens at the local layer, as bulk of the complexity is with managing the lifecycle of language servers. The actual implementation of the LSP protocol is handled by [`lsp`] crate.
   12pub mod clangd_ext;
   13pub mod json_language_server_ext;
   14pub mod log_store;
   15pub mod lsp_ext_command;
   16pub mod rust_analyzer_ext;
   17pub mod vue_language_server_ext;
   18
   19mod inlay_hint_cache;
   20
   21use self::inlay_hint_cache::BufferInlayHints;
   22use crate::{
   23    CodeAction, ColorPresentation, Completion, CompletionDisplayOptions, CompletionResponse,
   24    CompletionSource, CoreCompletion, DocumentColor, Hover, InlayHint, InlayId, LocationLink,
   25    LspAction, LspPullDiagnostics, ManifestProvidersStore, Project, ProjectItem, ProjectPath,
   26    ProjectTransaction, PulledDiagnostics, ResolveState, Symbol,
   27    buffer_store::{BufferStore, BufferStoreEvent},
   28    environment::ProjectEnvironment,
   29    lsp_command::{self, *},
   30    lsp_store::{
   31        self,
   32        inlay_hint_cache::BufferChunk,
   33        log_store::{GlobalLogStore, LanguageServerKind},
   34    },
   35    manifest_tree::{
   36        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   37        ManifestTree,
   38    },
   39    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   40    project_settings::{LspSettings, ProjectSettings},
   41    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   42    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   43    yarn::YarnPathStore,
   44};
   45use anyhow::{Context as _, Result, anyhow};
   46use async_trait::async_trait;
   47use client::{TypedEnvelope, proto};
   48use clock::Global;
   49use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   50use futures::{
   51    AsyncWriteExt, Future, FutureExt, StreamExt,
   52    future::{Either, Shared, join_all, pending, select},
   53    select, select_biased,
   54    stream::FuturesUnordered,
   55};
   56use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   57use gpui::{
   58    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString, Task,
   59    WeakEntity,
   60};
   61use http_client::HttpClient;
   62use itertools::Itertools as _;
   63use language::{
   64    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, CodeLabel, Diagnostic,
   65    DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language, LanguageName,
   66    LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller, ManifestDelegate,
   67    ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Toolchain,
   68    Transaction, Unclipped,
   69    language_settings::{FormatOnSave, Formatter, LanguageSettings, language_settings},
   70    point_to_lsp,
   71    proto::{
   72        deserialize_anchor, deserialize_lsp_edit, deserialize_version, serialize_anchor,
   73        serialize_lsp_edit, serialize_version,
   74    },
   75    range_from_lsp, range_to_lsp,
   76};
   77use lsp::{
   78    AdapterServerCapabilities, CodeActionKind, CompletionContext, DiagnosticServerCapabilities,
   79    DiagnosticSeverity, DiagnosticTag, DidChangeWatchedFilesRegistrationOptions, Edit,
   80    FileOperationFilter, FileOperationPatternKind, FileOperationRegistrationOptions, FileRename,
   81    FileSystemWatcher, LSP_REQUEST_TIMEOUT, LanguageServer, LanguageServerBinary,
   82    LanguageServerBinaryOptions, LanguageServerId, LanguageServerName, LanguageServerSelector,
   83    LspRequestFuture, MessageActionItem, MessageType, OneOf, RenameFilesParams, SymbolKind,
   84    TextDocumentSyncSaveOptions, TextEdit, Uri, WillRenameFiles, WorkDoneProgressCancelParams,
   85    WorkspaceFolder, notification::DidRenameFiles,
   86};
   87use node_runtime::read_package_installed_version;
   88use parking_lot::Mutex;
   89use postage::{mpsc, sink::Sink, stream::Stream, watch};
   90use rand::prelude::*;
   91use rpc::{
   92    AnyProtoClient, ErrorCode, ErrorExt as _,
   93    proto::{LspRequestId, LspRequestMessage as _},
   94};
   95use serde::Serialize;
   96use settings::{Settings, SettingsLocation, SettingsStore};
   97use sha2::{Digest, Sha256};
   98use smol::channel::Sender;
   99use snippet::Snippet;
  100use std::{
  101    any::TypeId,
  102    borrow::Cow,
  103    cell::RefCell,
  104    cmp::{Ordering, Reverse},
  105    convert::TryInto,
  106    ffi::OsStr,
  107    future::ready,
  108    iter, mem,
  109    ops::{ControlFlow, Range},
  110    path::{self, Path, PathBuf},
  111    pin::pin,
  112    rc::Rc,
  113    sync::{
  114        Arc,
  115        atomic::{self, AtomicUsize},
  116    },
  117    time::{Duration, Instant},
  118};
  119use sum_tree::Dimensions;
  120use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, Point, ToPoint as _};
  121
  122use util::{
  123    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  124    paths::{PathStyle, SanitizedPath},
  125    post_inc,
  126    rel_path::RelPath,
  127};
  128
  129pub use fs::*;
  130pub use language::Location;
  131pub use lsp_store::inlay_hint_cache::{CacheInlayHints, InvalidationStrategy};
  132#[cfg(any(test, feature = "test-support"))]
  133pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  134pub use worktree::{
  135    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  136    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  137};
  138
  139const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  140pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  141const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  142
  143#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  144pub enum ProgressToken {
  145    Number(i32),
  146    String(SharedString),
  147}
  148
  149impl std::fmt::Display for ProgressToken {
  150    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  151        match self {
  152            Self::Number(number) => write!(f, "{number}"),
  153            Self::String(string) => write!(f, "{string}"),
  154        }
  155    }
  156}
  157
  158impl ProgressToken {
  159    fn from_lsp(value: lsp::NumberOrString) -> Self {
  160        match value {
  161            lsp::NumberOrString::Number(number) => Self::Number(number),
  162            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  163        }
  164    }
  165
  166    fn to_lsp(&self) -> lsp::NumberOrString {
  167        match self {
  168            Self::Number(number) => lsp::NumberOrString::Number(*number),
  169            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  170        }
  171    }
  172
  173    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  174        Some(match value.value? {
  175            proto::progress_token::Value::Number(number) => Self::Number(number),
  176            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  177        })
  178    }
  179
  180    fn to_proto(&self) -> proto::ProgressToken {
  181        proto::ProgressToken {
  182            value: Some(match self {
  183                Self::Number(number) => proto::progress_token::Value::Number(*number),
  184                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  185            }),
  186        }
  187    }
  188}
  189
  190#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  191pub enum FormatTrigger {
  192    Save,
  193    Manual,
  194}
  195
  196pub enum LspFormatTarget {
  197    Buffers,
  198    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  199}
  200
  201pub type OpenLspBufferHandle = Entity<Entity<Buffer>>;
  202
  203impl FormatTrigger {
  204    fn from_proto(value: i32) -> FormatTrigger {
  205        match value {
  206            0 => FormatTrigger::Save,
  207            1 => FormatTrigger::Manual,
  208            _ => FormatTrigger::Save,
  209        }
  210    }
  211}
  212
  213#[derive(Clone)]
  214struct UnifiedLanguageServer {
  215    id: LanguageServerId,
  216    project_roots: HashSet<Arc<RelPath>>,
  217}
  218
  219#[derive(Clone, Hash, PartialEq, Eq)]
  220struct LanguageServerSeed {
  221    worktree_id: WorktreeId,
  222    name: LanguageServerName,
  223    toolchain: Option<Toolchain>,
  224    settings: Arc<LspSettings>,
  225}
  226
  227#[derive(Debug)]
  228pub struct DocumentDiagnosticsUpdate<'a, D> {
  229    pub diagnostics: D,
  230    pub result_id: Option<String>,
  231    pub server_id: LanguageServerId,
  232    pub disk_based_sources: Cow<'a, [String]>,
  233}
  234
  235pub struct DocumentDiagnostics {
  236    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  237    document_abs_path: PathBuf,
  238    version: Option<i32>,
  239}
  240
  241#[derive(Default)]
  242struct DynamicRegistrations {
  243    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  244    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  245}
  246
  247pub struct LocalLspStore {
  248    weak: WeakEntity<LspStore>,
  249    worktree_store: Entity<WorktreeStore>,
  250    toolchain_store: Entity<LocalToolchainStore>,
  251    http_client: Arc<dyn HttpClient>,
  252    environment: Entity<ProjectEnvironment>,
  253    fs: Arc<dyn Fs>,
  254    languages: Arc<LanguageRegistry>,
  255    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  256    yarn: Entity<YarnPathStore>,
  257    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  258    buffers_being_formatted: HashSet<BufferId>,
  259    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  260    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  261    watched_manifest_filenames: HashSet<ManifestName>,
  262    language_server_paths_watched_for_rename:
  263        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  264    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  265    supplementary_language_servers:
  266        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  267    prettier_store: Entity<PrettierStore>,
  268    next_diagnostic_group_id: usize,
  269    diagnostics: HashMap<
  270        WorktreeId,
  271        HashMap<
  272            Arc<RelPath>,
  273            Vec<(
  274                LanguageServerId,
  275                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  276            )>,
  277        >,
  278    >,
  279    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  280    _subscription: gpui::Subscription,
  281    lsp_tree: LanguageServerTree,
  282    registered_buffers: HashMap<BufferId, usize>,
  283    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  284    buffer_pull_diagnostics_result_ids: HashMap<LanguageServerId, HashMap<PathBuf, Option<String>>>,
  285}
  286
  287impl LocalLspStore {
  288    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  289    pub fn running_language_server_for_id(
  290        &self,
  291        id: LanguageServerId,
  292    ) -> Option<&Arc<LanguageServer>> {
  293        let language_server_state = self.language_servers.get(&id)?;
  294
  295        match language_server_state {
  296            LanguageServerState::Running { server, .. } => Some(server),
  297            LanguageServerState::Starting { .. } => None,
  298        }
  299    }
  300
  301    fn get_or_insert_language_server(
  302        &mut self,
  303        worktree_handle: &Entity<Worktree>,
  304        delegate: Arc<LocalLspAdapterDelegate>,
  305        disposition: &Arc<LaunchDisposition>,
  306        language_name: &LanguageName,
  307        cx: &mut App,
  308    ) -> LanguageServerId {
  309        let key = LanguageServerSeed {
  310            worktree_id: worktree_handle.read(cx).id(),
  311            name: disposition.server_name.clone(),
  312            settings: disposition.settings.clone(),
  313            toolchain: disposition.toolchain.clone(),
  314        };
  315        if let Some(state) = self.language_server_ids.get_mut(&key) {
  316            state.project_roots.insert(disposition.path.path.clone());
  317            state.id
  318        } else {
  319            let adapter = self
  320                .languages
  321                .lsp_adapters(language_name)
  322                .into_iter()
  323                .find(|adapter| adapter.name() == disposition.server_name)
  324                .expect("To find LSP adapter");
  325            let new_language_server_id = self.start_language_server(
  326                worktree_handle,
  327                delegate,
  328                adapter,
  329                disposition.settings.clone(),
  330                key.clone(),
  331                cx,
  332            );
  333            if let Some(state) = self.language_server_ids.get_mut(&key) {
  334                state.project_roots.insert(disposition.path.path.clone());
  335            } else {
  336                debug_assert!(
  337                    false,
  338                    "Expected `start_language_server` to ensure that `key` exists in a map"
  339                );
  340            }
  341            new_language_server_id
  342        }
  343    }
  344
  345    fn start_language_server(
  346        &mut self,
  347        worktree_handle: &Entity<Worktree>,
  348        delegate: Arc<LocalLspAdapterDelegate>,
  349        adapter: Arc<CachedLspAdapter>,
  350        settings: Arc<LspSettings>,
  351        key: LanguageServerSeed,
  352        cx: &mut App,
  353    ) -> LanguageServerId {
  354        let worktree = worktree_handle.read(cx);
  355
  356        let root_path = worktree.abs_path();
  357        let toolchain = key.toolchain.clone();
  358        let override_options = settings.initialization_options.clone();
  359
  360        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  361
  362        let server_id = self.languages.next_language_server_id();
  363        log::trace!(
  364            "attempting to start language server {:?}, path: {root_path:?}, id: {server_id}",
  365            adapter.name.0
  366        );
  367
  368        let binary = self.get_language_server_binary(
  369            adapter.clone(),
  370            settings,
  371            toolchain.clone(),
  372            delegate.clone(),
  373            true,
  374            cx,
  375        );
  376        let pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>> = Default::default();
  377
  378        let pending_server = cx.spawn({
  379            let adapter = adapter.clone();
  380            let server_name = adapter.name.clone();
  381            let stderr_capture = stderr_capture.clone();
  382            #[cfg(any(test, feature = "test-support"))]
  383            let lsp_store = self.weak.clone();
  384            let pending_workspace_folders = pending_workspace_folders.clone();
  385            async move |cx| {
  386                let binary = binary.await?;
  387                #[cfg(any(test, feature = "test-support"))]
  388                if let Some(server) = lsp_store
  389                    .update(&mut cx.clone(), |this, cx| {
  390                        this.languages.create_fake_language_server(
  391                            server_id,
  392                            &server_name,
  393                            binary.clone(),
  394                            &mut cx.to_async(),
  395                        )
  396                    })
  397                    .ok()
  398                    .flatten()
  399                {
  400                    return Ok(server);
  401                }
  402
  403                let code_action_kinds = adapter.code_action_kinds();
  404                lsp::LanguageServer::new(
  405                    stderr_capture,
  406                    server_id,
  407                    server_name,
  408                    binary,
  409                    &root_path,
  410                    code_action_kinds,
  411                    Some(pending_workspace_folders),
  412                    cx,
  413                )
  414            }
  415        });
  416
  417        let startup = {
  418            let server_name = adapter.name.0.clone();
  419            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  420            let key = key.clone();
  421            let adapter = adapter.clone();
  422            let lsp_store = self.weak.clone();
  423            let pending_workspace_folders = pending_workspace_folders.clone();
  424
  425            let pull_diagnostics = ProjectSettings::get_global(cx)
  426                .diagnostics
  427                .lsp_pull_diagnostics
  428                .enabled;
  429            cx.spawn(async move |cx| {
  430                let result = async {
  431                    let language_server = pending_server.await?;
  432
  433                    let workspace_config = Self::workspace_configuration_for_adapter(
  434                        adapter.adapter.clone(),
  435                        &delegate,
  436                        toolchain,
  437                        cx,
  438                    )
  439                    .await?;
  440
  441                    let mut initialization_options = Self::initialization_options_for_adapter(
  442                        adapter.adapter.clone(),
  443                        &delegate,
  444                    )
  445                    .await?;
  446
  447                    match (&mut initialization_options, override_options) {
  448                        (Some(initialization_options), Some(override_options)) => {
  449                            merge_json_value_into(override_options, initialization_options);
  450                        }
  451                        (None, override_options) => initialization_options = override_options,
  452                        _ => {}
  453                    }
  454
  455                    let initialization_params = cx.update(|cx| {
  456                        let mut params =
  457                            language_server.default_initialize_params(pull_diagnostics, cx);
  458                        params.initialization_options = initialization_options;
  459                        adapter.adapter.prepare_initialize_params(params, cx)
  460                    })??;
  461
  462                    Self::setup_lsp_messages(
  463                        lsp_store.clone(),
  464                        &language_server,
  465                        delegate.clone(),
  466                        adapter.clone(),
  467                    );
  468
  469                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  470                        settings: workspace_config,
  471                    };
  472                    let language_server = cx
  473                        .update(|cx| {
  474                            language_server.initialize(
  475                                initialization_params,
  476                                Arc::new(did_change_configuration_params.clone()),
  477                                cx,
  478                            )
  479                        })?
  480                        .await
  481                        .inspect_err(|_| {
  482                            if let Some(lsp_store) = lsp_store.upgrade() {
  483                                lsp_store
  484                                    .update(cx, |lsp_store, cx| {
  485                                        lsp_store.cleanup_lsp_data(server_id);
  486                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  487                                    })
  488                                    .ok();
  489                            }
  490                        })?;
  491
  492                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  493                        did_change_configuration_params,
  494                    )?;
  495
  496                    anyhow::Ok(language_server)
  497                }
  498                .await;
  499
  500                match result {
  501                    Ok(server) => {
  502                        lsp_store
  503                            .update(cx, |lsp_store, cx| {
  504                                lsp_store.insert_newly_running_language_server(
  505                                    adapter,
  506                                    server.clone(),
  507                                    server_id,
  508                                    key,
  509                                    pending_workspace_folders,
  510                                    cx,
  511                                );
  512                            })
  513                            .ok();
  514                        stderr_capture.lock().take();
  515                        Some(server)
  516                    }
  517
  518                    Err(err) => {
  519                        let log = stderr_capture.lock().take().unwrap_or_default();
  520                        delegate.update_status(
  521                            adapter.name(),
  522                            BinaryStatus::Failed {
  523                                error: if log.is_empty() {
  524                                    format!("{err:#}")
  525                                } else {
  526                                    format!("{err:#}\n-- stderr --\n{log}")
  527                                },
  528                            },
  529                        );
  530                        log::error!("Failed to start language server {server_name:?}: {err:?}");
  531                        if !log.is_empty() {
  532                            log::error!("server stderr: {log}");
  533                        }
  534                        None
  535                    }
  536                }
  537            })
  538        };
  539        let state = LanguageServerState::Starting {
  540            startup,
  541            pending_workspace_folders,
  542        };
  543
  544        self.languages
  545            .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  546
  547        self.language_servers.insert(server_id, state);
  548        self.language_server_ids
  549            .entry(key)
  550            .or_insert(UnifiedLanguageServer {
  551                id: server_id,
  552                project_roots: Default::default(),
  553            });
  554        server_id
  555    }
  556
  557    fn get_language_server_binary(
  558        &self,
  559        adapter: Arc<CachedLspAdapter>,
  560        settings: Arc<LspSettings>,
  561        toolchain: Option<Toolchain>,
  562        delegate: Arc<dyn LspAdapterDelegate>,
  563        allow_binary_download: bool,
  564        cx: &mut App,
  565    ) -> Task<Result<LanguageServerBinary>> {
  566        if let Some(settings) = settings.binary.as_ref()
  567            && settings.path.is_some()
  568        {
  569            let settings = settings.clone();
  570
  571            return cx.background_spawn(async move {
  572                let mut env = delegate.shell_env().await;
  573                env.extend(settings.env.unwrap_or_default());
  574
  575                Ok(LanguageServerBinary {
  576                    path: PathBuf::from(&settings.path.unwrap()),
  577                    env: Some(env),
  578                    arguments: settings
  579                        .arguments
  580                        .unwrap_or_default()
  581                        .iter()
  582                        .map(Into::into)
  583                        .collect(),
  584                })
  585            });
  586        }
  587        let lsp_binary_options = LanguageServerBinaryOptions {
  588            allow_path_lookup: !settings
  589                .binary
  590                .as_ref()
  591                .and_then(|b| b.ignore_system_version)
  592                .unwrap_or_default(),
  593            allow_binary_download,
  594            pre_release: settings
  595                .fetch
  596                .as_ref()
  597                .and_then(|f| f.pre_release)
  598                .unwrap_or(false),
  599        };
  600
  601        cx.spawn(async move |cx| {
  602            let binary_result = adapter
  603                .clone()
  604                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  605                .await;
  606
  607            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  608
  609            let mut binary = binary_result?;
  610            let mut shell_env = delegate.shell_env().await;
  611
  612            shell_env.extend(binary.env.unwrap_or_default());
  613
  614            if let Some(settings) = settings.binary.as_ref() {
  615                if let Some(arguments) = &settings.arguments {
  616                    binary.arguments = arguments.iter().map(Into::into).collect();
  617                }
  618                if let Some(env) = &settings.env {
  619                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  620                }
  621            }
  622
  623            binary.env = Some(shell_env);
  624            Ok(binary)
  625        })
  626    }
  627
  628    fn setup_lsp_messages(
  629        lsp_store: WeakEntity<LspStore>,
  630        language_server: &LanguageServer,
  631        delegate: Arc<dyn LspAdapterDelegate>,
  632        adapter: Arc<CachedLspAdapter>,
  633    ) {
  634        let name = language_server.name();
  635        let server_id = language_server.server_id();
  636        language_server
  637            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  638                let adapter = adapter.clone();
  639                let this = lsp_store.clone();
  640                move |mut params, cx| {
  641                    let adapter = adapter.clone();
  642                    if let Some(this) = this.upgrade() {
  643                        this.update(cx, |this, cx| {
  644                            {
  645                                let buffer = params
  646                                    .uri
  647                                    .to_file_path()
  648                                    .map(|file_path| this.get_buffer(&file_path, cx))
  649                                    .ok()
  650                                    .flatten();
  651                                adapter.process_diagnostics(&mut params, server_id, buffer);
  652                            }
  653
  654                            this.merge_lsp_diagnostics(
  655                                DiagnosticSourceKind::Pushed,
  656                                vec![DocumentDiagnosticsUpdate {
  657                                    server_id,
  658                                    diagnostics: params,
  659                                    result_id: None,
  660                                    disk_based_sources: Cow::Borrowed(
  661                                        &adapter.disk_based_diagnostic_sources,
  662                                    ),
  663                                }],
  664                                |_, diagnostic, cx| match diagnostic.source_kind {
  665                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  666                                        adapter.retain_old_diagnostic(diagnostic, cx)
  667                                    }
  668                                    DiagnosticSourceKind::Pulled => true,
  669                                },
  670                                cx,
  671                            )
  672                            .log_err();
  673                        })
  674                        .ok();
  675                    }
  676                }
  677            })
  678            .detach();
  679        language_server
  680            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  681                let adapter = adapter.adapter.clone();
  682                let delegate = delegate.clone();
  683                let this = lsp_store.clone();
  684                move |params, cx| {
  685                    let adapter = adapter.clone();
  686                    let delegate = delegate.clone();
  687                    let this = this.clone();
  688                    let mut cx = cx.clone();
  689                    async move {
  690                        let toolchain_for_id = this
  691                            .update(&mut cx, |this, _| {
  692                                this.as_local()?.language_server_ids.iter().find_map(
  693                                    |(seed, value)| {
  694                                        (value.id == server_id).then(|| seed.toolchain.clone())
  695                                    },
  696                                )
  697                            })?
  698                            .context("Expected the LSP store to be in a local mode")?;
  699                        let workspace_config = Self::workspace_configuration_for_adapter(
  700                            adapter.clone(),
  701                            &delegate,
  702                            toolchain_for_id,
  703                            &mut cx,
  704                        )
  705                        .await?;
  706
  707                        Ok(params
  708                            .items
  709                            .into_iter()
  710                            .map(|item| {
  711                                if let Some(section) = &item.section {
  712                                    workspace_config
  713                                        .get(section)
  714                                        .cloned()
  715                                        .unwrap_or(serde_json::Value::Null)
  716                                } else {
  717                                    workspace_config.clone()
  718                                }
  719                            })
  720                            .collect())
  721                    }
  722                }
  723            })
  724            .detach();
  725
  726        language_server
  727            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  728                let this = lsp_store.clone();
  729                move |_, cx| {
  730                    let this = this.clone();
  731                    let cx = cx.clone();
  732                    async move {
  733                        let Some(server) =
  734                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  735                        else {
  736                            return Ok(None);
  737                        };
  738                        let root = server.workspace_folders();
  739                        Ok(Some(
  740                            root.into_iter()
  741                                .map(|uri| WorkspaceFolder {
  742                                    uri,
  743                                    name: Default::default(),
  744                                })
  745                                .collect(),
  746                        ))
  747                    }
  748                }
  749            })
  750            .detach();
  751        // Even though we don't have handling for these requests, respond to them to
  752        // avoid stalling any language server like `gopls` which waits for a response
  753        // to these requests when initializing.
  754        language_server
  755            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  756                let this = lsp_store.clone();
  757                move |params, cx| {
  758                    let this = this.clone();
  759                    let mut cx = cx.clone();
  760                    async move {
  761                        this.update(&mut cx, |this, _| {
  762                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  763                            {
  764                                status
  765                                    .progress_tokens
  766                                    .insert(ProgressToken::from_lsp(params.token));
  767                            }
  768                        })?;
  769
  770                        Ok(())
  771                    }
  772                }
  773            })
  774            .detach();
  775
  776        language_server
  777            .on_request::<lsp::request::RegisterCapability, _, _>({
  778                let lsp_store = lsp_store.clone();
  779                move |params, cx| {
  780                    let lsp_store = lsp_store.clone();
  781                    let mut cx = cx.clone();
  782                    async move {
  783                        lsp_store
  784                            .update(&mut cx, |lsp_store, cx| {
  785                                if lsp_store.as_local().is_some() {
  786                                    match lsp_store
  787                                        .register_server_capabilities(server_id, params, cx)
  788                                    {
  789                                        Ok(()) => {}
  790                                        Err(e) => {
  791                                            log::error!(
  792                                                "Failed to register server capabilities: {e:#}"
  793                                            );
  794                                        }
  795                                    };
  796                                }
  797                            })
  798                            .ok();
  799                        Ok(())
  800                    }
  801                }
  802            })
  803            .detach();
  804
  805        language_server
  806            .on_request::<lsp::request::UnregisterCapability, _, _>({
  807                let lsp_store = lsp_store.clone();
  808                move |params, cx| {
  809                    let lsp_store = lsp_store.clone();
  810                    let mut cx = cx.clone();
  811                    async move {
  812                        lsp_store
  813                            .update(&mut cx, |lsp_store, cx| {
  814                                if lsp_store.as_local().is_some() {
  815                                    match lsp_store
  816                                        .unregister_server_capabilities(server_id, params, cx)
  817                                    {
  818                                        Ok(()) => {}
  819                                        Err(e) => {
  820                                            log::error!(
  821                                                "Failed to unregister server capabilities: {e:#}"
  822                                            );
  823                                        }
  824                                    }
  825                                }
  826                            })
  827                            .ok();
  828                        Ok(())
  829                    }
  830                }
  831            })
  832            .detach();
  833
  834        language_server
  835            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  836                let this = lsp_store.clone();
  837                move |params, cx| {
  838                    let mut cx = cx.clone();
  839                    let this = this.clone();
  840                    async move {
  841                        LocalLspStore::on_lsp_workspace_edit(
  842                            this.clone(),
  843                            params,
  844                            server_id,
  845                            &mut cx,
  846                        )
  847                        .await
  848                    }
  849                }
  850            })
  851            .detach();
  852
  853        language_server
  854            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  855                let lsp_store = lsp_store.clone();
  856                move |(), cx| {
  857                    let this = lsp_store.clone();
  858                    let mut cx = cx.clone();
  859                    async move {
  860                        this.update(&mut cx, |lsp_store, cx| {
  861                            cx.emit(LspStoreEvent::RefreshInlayHints(server_id));
  862                            lsp_store
  863                                .downstream_client
  864                                .as_ref()
  865                                .map(|(client, project_id)| {
  866                                    client.send(proto::RefreshInlayHints {
  867                                        project_id: *project_id,
  868                                        server_id: server_id.to_proto(),
  869                                    })
  870                                })
  871                        })?
  872                        .transpose()?;
  873                        Ok(())
  874                    }
  875                }
  876            })
  877            .detach();
  878
  879        language_server
  880            .on_request::<lsp::request::CodeLensRefresh, _, _>({
  881                let this = lsp_store.clone();
  882                move |(), cx| {
  883                    let this = this.clone();
  884                    let mut cx = cx.clone();
  885                    async move {
  886                        this.update(&mut cx, |this, cx| {
  887                            cx.emit(LspStoreEvent::RefreshCodeLens);
  888                            this.downstream_client.as_ref().map(|(client, project_id)| {
  889                                client.send(proto::RefreshCodeLens {
  890                                    project_id: *project_id,
  891                                })
  892                            })
  893                        })?
  894                        .transpose()?;
  895                        Ok(())
  896                    }
  897                }
  898            })
  899            .detach();
  900
  901        language_server
  902            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
  903                let this = lsp_store.clone();
  904                move |(), cx| {
  905                    let this = this.clone();
  906                    let mut cx = cx.clone();
  907                    async move {
  908                        this.update(&mut cx, |lsp_store, _| {
  909                            lsp_store.pull_workspace_diagnostics(server_id);
  910                            lsp_store
  911                                .downstream_client
  912                                .as_ref()
  913                                .map(|(client, project_id)| {
  914                                    client.send(proto::PullWorkspaceDiagnostics {
  915                                        project_id: *project_id,
  916                                        server_id: server_id.to_proto(),
  917                                    })
  918                                })
  919                        })?
  920                        .transpose()?;
  921                        Ok(())
  922                    }
  923                }
  924            })
  925            .detach();
  926
  927        language_server
  928            .on_request::<lsp::request::ShowMessageRequest, _, _>({
  929                let this = lsp_store.clone();
  930                let name = name.to_string();
  931                move |params, cx| {
  932                    let this = this.clone();
  933                    let name = name.to_string();
  934                    let mut cx = cx.clone();
  935                    async move {
  936                        let actions = params.actions.unwrap_or_default();
  937                        let (tx, rx) = smol::channel::bounded(1);
  938                        let request = LanguageServerPromptRequest {
  939                            level: match params.typ {
  940                                lsp::MessageType::ERROR => PromptLevel::Critical,
  941                                lsp::MessageType::WARNING => PromptLevel::Warning,
  942                                _ => PromptLevel::Info,
  943                            },
  944                            message: params.message,
  945                            actions,
  946                            response_channel: tx,
  947                            lsp_name: name.clone(),
  948                        };
  949
  950                        let did_update = this
  951                            .update(&mut cx, |_, cx| {
  952                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
  953                            })
  954                            .is_ok();
  955                        if did_update {
  956                            let response = rx.recv().await.ok();
  957                            Ok(response)
  958                        } else {
  959                            Ok(None)
  960                        }
  961                    }
  962                }
  963            })
  964            .detach();
  965        language_server
  966            .on_notification::<lsp::notification::ShowMessage, _>({
  967                let this = lsp_store.clone();
  968                let name = name.to_string();
  969                move |params, cx| {
  970                    let this = this.clone();
  971                    let name = name.to_string();
  972                    let mut cx = cx.clone();
  973
  974                    let (tx, _) = smol::channel::bounded(1);
  975                    let request = LanguageServerPromptRequest {
  976                        level: match params.typ {
  977                            lsp::MessageType::ERROR => PromptLevel::Critical,
  978                            lsp::MessageType::WARNING => PromptLevel::Warning,
  979                            _ => PromptLevel::Info,
  980                        },
  981                        message: params.message,
  982                        actions: vec![],
  983                        response_channel: tx,
  984                        lsp_name: name,
  985                    };
  986
  987                    let _ = this.update(&mut cx, |_, cx| {
  988                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
  989                    });
  990                }
  991            })
  992            .detach();
  993
  994        let disk_based_diagnostics_progress_token =
  995            adapter.disk_based_diagnostics_progress_token.clone();
  996
  997        language_server
  998            .on_notification::<lsp::notification::Progress, _>({
  999                let this = lsp_store.clone();
 1000                move |params, cx| {
 1001                    if let Some(this) = this.upgrade() {
 1002                        this.update(cx, |this, cx| {
 1003                            this.on_lsp_progress(
 1004                                params,
 1005                                server_id,
 1006                                disk_based_diagnostics_progress_token.clone(),
 1007                                cx,
 1008                            );
 1009                        })
 1010                        .ok();
 1011                    }
 1012                }
 1013            })
 1014            .detach();
 1015
 1016        language_server
 1017            .on_notification::<lsp::notification::LogMessage, _>({
 1018                let this = lsp_store.clone();
 1019                move |params, cx| {
 1020                    if let Some(this) = this.upgrade() {
 1021                        this.update(cx, |_, cx| {
 1022                            cx.emit(LspStoreEvent::LanguageServerLog(
 1023                                server_id,
 1024                                LanguageServerLogType::Log(params.typ),
 1025                                params.message,
 1026                            ));
 1027                        })
 1028                        .ok();
 1029                    }
 1030                }
 1031            })
 1032            .detach();
 1033
 1034        language_server
 1035            .on_notification::<lsp::notification::LogTrace, _>({
 1036                let this = lsp_store.clone();
 1037                move |params, cx| {
 1038                    let mut cx = cx.clone();
 1039                    if let Some(this) = this.upgrade() {
 1040                        this.update(&mut cx, |_, cx| {
 1041                            cx.emit(LspStoreEvent::LanguageServerLog(
 1042                                server_id,
 1043                                LanguageServerLogType::Trace {
 1044                                    verbose_info: params.verbose,
 1045                                },
 1046                                params.message,
 1047                            ));
 1048                        })
 1049                        .ok();
 1050                    }
 1051                }
 1052            })
 1053            .detach();
 1054
 1055        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1056        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1057        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1058        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1059    }
 1060
 1061    fn shutdown_language_servers_on_quit(
 1062        &mut self,
 1063        _: &mut Context<LspStore>,
 1064    ) -> impl Future<Output = ()> + use<> {
 1065        let shutdown_futures = self
 1066            .language_servers
 1067            .drain()
 1068            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1069            .collect::<Vec<_>>();
 1070
 1071        async move {
 1072            join_all(shutdown_futures).await;
 1073        }
 1074    }
 1075
 1076    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1077        match server_state {
 1078            LanguageServerState::Running { server, .. } => {
 1079                if let Some(shutdown) = server.shutdown() {
 1080                    shutdown.await;
 1081                }
 1082            }
 1083            LanguageServerState::Starting { startup, .. } => {
 1084                if let Some(server) = startup.await
 1085                    && let Some(shutdown) = server.shutdown()
 1086                {
 1087                    shutdown.await;
 1088                }
 1089            }
 1090        }
 1091        Ok(())
 1092    }
 1093
 1094    fn language_servers_for_worktree(
 1095        &self,
 1096        worktree_id: WorktreeId,
 1097    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1098        self.language_server_ids
 1099            .iter()
 1100            .filter_map(move |(seed, state)| {
 1101                if seed.worktree_id != worktree_id {
 1102                    return None;
 1103                }
 1104
 1105                if let Some(LanguageServerState::Running { server, .. }) =
 1106                    self.language_servers.get(&state.id)
 1107                {
 1108                    Some(server)
 1109                } else {
 1110                    None
 1111                }
 1112            })
 1113    }
 1114
 1115    fn language_server_ids_for_project_path(
 1116        &self,
 1117        project_path: ProjectPath,
 1118        language: &Language,
 1119        cx: &mut App,
 1120    ) -> Vec<LanguageServerId> {
 1121        let Some(worktree) = self
 1122            .worktree_store
 1123            .read(cx)
 1124            .worktree_for_id(project_path.worktree_id, cx)
 1125        else {
 1126            return Vec::new();
 1127        };
 1128        let delegate: Arc<dyn ManifestDelegate> =
 1129            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1130
 1131        self.lsp_tree
 1132            .get(
 1133                project_path,
 1134                language.name(),
 1135                language.manifest(),
 1136                &delegate,
 1137                cx,
 1138            )
 1139            .collect::<Vec<_>>()
 1140    }
 1141
 1142    fn language_server_ids_for_buffer(
 1143        &self,
 1144        buffer: &Buffer,
 1145        cx: &mut App,
 1146    ) -> Vec<LanguageServerId> {
 1147        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1148            let worktree_id = file.worktree_id(cx);
 1149
 1150            let path: Arc<RelPath> = file
 1151                .path()
 1152                .parent()
 1153                .map(Arc::from)
 1154                .unwrap_or_else(|| file.path().clone());
 1155            let worktree_path = ProjectPath { worktree_id, path };
 1156            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1157        } else {
 1158            Vec::new()
 1159        }
 1160    }
 1161
 1162    fn language_servers_for_buffer<'a>(
 1163        &'a self,
 1164        buffer: &'a Buffer,
 1165        cx: &'a mut App,
 1166    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1167        self.language_server_ids_for_buffer(buffer, cx)
 1168            .into_iter()
 1169            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1170                LanguageServerState::Running {
 1171                    adapter, server, ..
 1172                } => Some((adapter, server)),
 1173                _ => None,
 1174            })
 1175    }
 1176
 1177    async fn execute_code_action_kind_locally(
 1178        lsp_store: WeakEntity<LspStore>,
 1179        mut buffers: Vec<Entity<Buffer>>,
 1180        kind: CodeActionKind,
 1181        push_to_history: bool,
 1182        cx: &mut AsyncApp,
 1183    ) -> anyhow::Result<ProjectTransaction> {
 1184        // Do not allow multiple concurrent code actions requests for the
 1185        // same buffer.
 1186        lsp_store.update(cx, |this, cx| {
 1187            let this = this.as_local_mut().unwrap();
 1188            buffers.retain(|buffer| {
 1189                this.buffers_being_formatted
 1190                    .insert(buffer.read(cx).remote_id())
 1191            });
 1192        })?;
 1193        let _cleanup = defer({
 1194            let this = lsp_store.clone();
 1195            let mut cx = cx.clone();
 1196            let buffers = &buffers;
 1197            move || {
 1198                this.update(&mut cx, |this, cx| {
 1199                    let this = this.as_local_mut().unwrap();
 1200                    for buffer in buffers {
 1201                        this.buffers_being_formatted
 1202                            .remove(&buffer.read(cx).remote_id());
 1203                    }
 1204                })
 1205                .ok();
 1206            }
 1207        });
 1208        let mut project_transaction = ProjectTransaction::default();
 1209
 1210        for buffer in &buffers {
 1211            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1212                buffer.update(cx, |buffer, cx| {
 1213                    lsp_store
 1214                        .as_local()
 1215                        .unwrap()
 1216                        .language_servers_for_buffer(buffer, cx)
 1217                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1218                        .collect::<Vec<_>>()
 1219                })
 1220            })?;
 1221            for (_, language_server) in adapters_and_servers.iter() {
 1222                let actions = Self::get_server_code_actions_from_action_kinds(
 1223                    &lsp_store,
 1224                    language_server.server_id(),
 1225                    vec![kind.clone()],
 1226                    buffer,
 1227                    cx,
 1228                )
 1229                .await?;
 1230                Self::execute_code_actions_on_server(
 1231                    &lsp_store,
 1232                    language_server,
 1233                    actions,
 1234                    push_to_history,
 1235                    &mut project_transaction,
 1236                    cx,
 1237                )
 1238                .await?;
 1239            }
 1240        }
 1241        Ok(project_transaction)
 1242    }
 1243
 1244    async fn format_locally(
 1245        lsp_store: WeakEntity<LspStore>,
 1246        mut buffers: Vec<FormattableBuffer>,
 1247        push_to_history: bool,
 1248        trigger: FormatTrigger,
 1249        logger: zlog::Logger,
 1250        cx: &mut AsyncApp,
 1251    ) -> anyhow::Result<ProjectTransaction> {
 1252        // Do not allow multiple concurrent formatting requests for the
 1253        // same buffer.
 1254        lsp_store.update(cx, |this, cx| {
 1255            let this = this.as_local_mut().unwrap();
 1256            buffers.retain(|buffer| {
 1257                this.buffers_being_formatted
 1258                    .insert(buffer.handle.read(cx).remote_id())
 1259            });
 1260        })?;
 1261
 1262        let _cleanup = defer({
 1263            let this = lsp_store.clone();
 1264            let mut cx = cx.clone();
 1265            let buffers = &buffers;
 1266            move || {
 1267                this.update(&mut cx, |this, cx| {
 1268                    let this = this.as_local_mut().unwrap();
 1269                    for buffer in buffers {
 1270                        this.buffers_being_formatted
 1271                            .remove(&buffer.handle.read(cx).remote_id());
 1272                    }
 1273                })
 1274                .ok();
 1275            }
 1276        });
 1277
 1278        let mut project_transaction = ProjectTransaction::default();
 1279
 1280        for buffer in &buffers {
 1281            zlog::debug!(
 1282                logger =>
 1283                "formatting buffer '{:?}'",
 1284                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1285            );
 1286            // Create an empty transaction to hold all of the formatting edits.
 1287            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1288                // ensure no transactions created while formatting are
 1289                // grouped with the previous transaction in the history
 1290                // based on the transaction group interval
 1291                buffer.finalize_last_transaction();
 1292                buffer
 1293                    .start_transaction()
 1294                    .context("transaction already open")?;
 1295                buffer.end_transaction(cx);
 1296                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1297                buffer.finalize_last_transaction();
 1298                anyhow::Ok(transaction_id)
 1299            })??;
 1300
 1301            let result = Self::format_buffer_locally(
 1302                lsp_store.clone(),
 1303                buffer,
 1304                formatting_transaction_id,
 1305                trigger,
 1306                logger,
 1307                cx,
 1308            )
 1309            .await;
 1310
 1311            buffer.handle.update(cx, |buffer, cx| {
 1312                let Some(formatting_transaction) =
 1313                    buffer.get_transaction(formatting_transaction_id).cloned()
 1314                else {
 1315                    zlog::warn!(logger => "no formatting transaction");
 1316                    return;
 1317                };
 1318                if formatting_transaction.edit_ids.is_empty() {
 1319                    zlog::debug!(logger => "no changes made while formatting");
 1320                    buffer.forget_transaction(formatting_transaction_id);
 1321                    return;
 1322                }
 1323                if !push_to_history {
 1324                    zlog::trace!(logger => "forgetting format transaction");
 1325                    buffer.forget_transaction(formatting_transaction.id);
 1326                }
 1327                project_transaction
 1328                    .0
 1329                    .insert(cx.entity(), formatting_transaction);
 1330            })?;
 1331
 1332            result?;
 1333        }
 1334
 1335        Ok(project_transaction)
 1336    }
 1337
 1338    async fn format_buffer_locally(
 1339        lsp_store: WeakEntity<LspStore>,
 1340        buffer: &FormattableBuffer,
 1341        formatting_transaction_id: clock::Lamport,
 1342        trigger: FormatTrigger,
 1343        logger: zlog::Logger,
 1344        cx: &mut AsyncApp,
 1345    ) -> Result<()> {
 1346        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1347            buffer.handle.update(cx, |buffer, cx| {
 1348                let adapters_and_servers = lsp_store
 1349                    .as_local()
 1350                    .unwrap()
 1351                    .language_servers_for_buffer(buffer, cx)
 1352                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1353                    .collect::<Vec<_>>();
 1354                let settings =
 1355                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1356                        .into_owned();
 1357                (adapters_and_servers, settings)
 1358            })
 1359        })?;
 1360
 1361        /// Apply edits to the buffer that will become part of the formatting transaction.
 1362        /// Fails if the buffer has been edited since the start of that transaction.
 1363        fn extend_formatting_transaction(
 1364            buffer: &FormattableBuffer,
 1365            formatting_transaction_id: text::TransactionId,
 1366            cx: &mut AsyncApp,
 1367            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1368        ) -> anyhow::Result<()> {
 1369            buffer.handle.update(cx, |buffer, cx| {
 1370                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1371                if last_transaction_id != Some(formatting_transaction_id) {
 1372                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1373                }
 1374                buffer.start_transaction();
 1375                operation(buffer, cx);
 1376                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1377                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1378                }
 1379                Ok(())
 1380            })?
 1381        }
 1382
 1383        // handle whitespace formatting
 1384        if settings.remove_trailing_whitespace_on_save {
 1385            zlog::trace!(logger => "removing trailing whitespace");
 1386            let diff = buffer
 1387                .handle
 1388                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))?
 1389                .await;
 1390            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1391                buffer.apply_diff(diff, cx);
 1392            })?;
 1393        }
 1394
 1395        if settings.ensure_final_newline_on_save {
 1396            zlog::trace!(logger => "ensuring final newline");
 1397            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1398                buffer.ensure_final_newline(cx);
 1399            })?;
 1400        }
 1401
 1402        // Formatter for `code_actions_on_format` that runs before
 1403        // the rest of the formatters
 1404        let mut code_actions_on_format_formatters = None;
 1405        let should_run_code_actions_on_format = !matches!(
 1406            (trigger, &settings.format_on_save),
 1407            (FormatTrigger::Save, &FormatOnSave::Off)
 1408        );
 1409        if should_run_code_actions_on_format {
 1410            let have_code_actions_to_run_on_format = settings
 1411                .code_actions_on_format
 1412                .values()
 1413                .any(|enabled| *enabled);
 1414            if have_code_actions_to_run_on_format {
 1415                zlog::trace!(logger => "going to run code actions on format");
 1416                code_actions_on_format_formatters = Some(
 1417                    settings
 1418                        .code_actions_on_format
 1419                        .iter()
 1420                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1421                        .cloned()
 1422                        .map(Formatter::CodeAction)
 1423                        .collect::<Vec<_>>(),
 1424                );
 1425            }
 1426        }
 1427
 1428        let formatters = match (trigger, &settings.format_on_save) {
 1429            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1430            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1431                settings.formatter.as_ref()
 1432            }
 1433        };
 1434
 1435        let formatters = code_actions_on_format_formatters
 1436            .iter()
 1437            .flatten()
 1438            .chain(formatters);
 1439
 1440        for formatter in formatters {
 1441            let formatter = if formatter == &Formatter::Auto {
 1442                if settings.prettier.allowed {
 1443                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1444                    &Formatter::Prettier
 1445                } else {
 1446                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1447                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1448                }
 1449            } else {
 1450                formatter
 1451            };
 1452            match formatter {
 1453                Formatter::Auto => unreachable!("Auto resolved above"),
 1454                Formatter::Prettier => {
 1455                    let logger = zlog::scoped!(logger => "prettier");
 1456                    zlog::trace!(logger => "formatting");
 1457                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1458
 1459                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1460                        lsp_store.prettier_store().unwrap().downgrade()
 1461                    })?;
 1462                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1463                        .await
 1464                        .transpose()?;
 1465                    let Some(diff) = diff else {
 1466                        zlog::trace!(logger => "No changes");
 1467                        continue;
 1468                    };
 1469
 1470                    extend_formatting_transaction(
 1471                        buffer,
 1472                        formatting_transaction_id,
 1473                        cx,
 1474                        |buffer, cx| {
 1475                            buffer.apply_diff(diff, cx);
 1476                        },
 1477                    )?;
 1478                }
 1479                Formatter::External { command, arguments } => {
 1480                    let logger = zlog::scoped!(logger => "command");
 1481                    zlog::trace!(logger => "formatting");
 1482                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1483
 1484                    let diff = Self::format_via_external_command(
 1485                        buffer,
 1486                        command.as_ref(),
 1487                        arguments.as_deref(),
 1488                        cx,
 1489                    )
 1490                    .await
 1491                    .with_context(|| {
 1492                        format!("Failed to format buffer via external command: {}", command)
 1493                    })?;
 1494                    let Some(diff) = diff else {
 1495                        zlog::trace!(logger => "No changes");
 1496                        continue;
 1497                    };
 1498
 1499                    extend_formatting_transaction(
 1500                        buffer,
 1501                        formatting_transaction_id,
 1502                        cx,
 1503                        |buffer, cx| {
 1504                            buffer.apply_diff(diff, cx);
 1505                        },
 1506                    )?;
 1507                }
 1508                Formatter::LanguageServer(specifier) => {
 1509                    let logger = zlog::scoped!(logger => "language-server");
 1510                    zlog::trace!(logger => "formatting");
 1511                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1512
 1513                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1514                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1515                        continue;
 1516                    };
 1517
 1518                    let language_server = match specifier {
 1519                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1520                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1521                                if adapter.name.0.as_ref() == name {
 1522                                    Some(server.clone())
 1523                                } else {
 1524                                    None
 1525                                }
 1526                            })
 1527                        }
 1528                        settings::LanguageServerFormatterSpecifier::Current => {
 1529                            adapters_and_servers.first().map(|e| e.1.clone())
 1530                        }
 1531                    };
 1532
 1533                    let Some(language_server) = language_server else {
 1534                        log::debug!(
 1535                            "No language server found to format buffer '{:?}'. Skipping",
 1536                            buffer_path_abs.as_path().to_string_lossy()
 1537                        );
 1538                        continue;
 1539                    };
 1540
 1541                    zlog::trace!(
 1542                        logger =>
 1543                        "Formatting buffer '{:?}' using language server '{:?}'",
 1544                        buffer_path_abs.as_path().to_string_lossy(),
 1545                        language_server.name()
 1546                    );
 1547
 1548                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1549                        zlog::trace!(logger => "formatting ranges");
 1550                        Self::format_ranges_via_lsp(
 1551                            &lsp_store,
 1552                            &buffer.handle,
 1553                            ranges,
 1554                            buffer_path_abs,
 1555                            &language_server,
 1556                            &settings,
 1557                            cx,
 1558                        )
 1559                        .await
 1560                        .context("Failed to format ranges via language server")?
 1561                    } else {
 1562                        zlog::trace!(logger => "formatting full");
 1563                        Self::format_via_lsp(
 1564                            &lsp_store,
 1565                            &buffer.handle,
 1566                            buffer_path_abs,
 1567                            &language_server,
 1568                            &settings,
 1569                            cx,
 1570                        )
 1571                        .await
 1572                        .context("failed to format via language server")?
 1573                    };
 1574
 1575                    if edits.is_empty() {
 1576                        zlog::trace!(logger => "No changes");
 1577                        continue;
 1578                    }
 1579                    extend_formatting_transaction(
 1580                        buffer,
 1581                        formatting_transaction_id,
 1582                        cx,
 1583                        |buffer, cx| {
 1584                            buffer.edit(edits, None, cx);
 1585                        },
 1586                    )?;
 1587                }
 1588                Formatter::CodeAction(code_action_name) => {
 1589                    let logger = zlog::scoped!(logger => "code-actions");
 1590                    zlog::trace!(logger => "formatting");
 1591                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1592
 1593                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1594                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1595                        continue;
 1596                    };
 1597
 1598                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1599                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1600
 1601                    let mut actions_and_servers = Vec::new();
 1602
 1603                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1604                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1605                            &lsp_store,
 1606                            language_server.server_id(),
 1607                            vec![code_action_kind.clone()],
 1608                            &buffer.handle,
 1609                            cx,
 1610                        )
 1611                        .await
 1612                        .with_context(|| {
 1613                            format!(
 1614                                "Failed to resolve code action {:?} with language server {}",
 1615                                code_action_kind,
 1616                                language_server.name()
 1617                            )
 1618                        });
 1619                        let Ok(actions) = actions_result else {
 1620                            // note: it may be better to set result to the error and break formatters here
 1621                            // but for now we try to execute the actions that we can resolve and skip the rest
 1622                            zlog::error!(
 1623                                logger =>
 1624                                "Failed to resolve code action {:?} with language server {}",
 1625                                code_action_kind,
 1626                                language_server.name()
 1627                            );
 1628                            continue;
 1629                        };
 1630                        for action in actions {
 1631                            actions_and_servers.push((action, index));
 1632                        }
 1633                    }
 1634
 1635                    if actions_and_servers.is_empty() {
 1636                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1637                        continue;
 1638                    }
 1639
 1640                    'actions: for (mut action, server_index) in actions_and_servers {
 1641                        let server = &adapters_and_servers[server_index].1;
 1642
 1643                        let describe_code_action = |action: &CodeAction| {
 1644                            format!(
 1645                                "code action '{}' with title \"{}\" on server {}",
 1646                                action
 1647                                    .lsp_action
 1648                                    .action_kind()
 1649                                    .unwrap_or("unknown".into())
 1650                                    .as_str(),
 1651                                action.lsp_action.title(),
 1652                                server.name(),
 1653                            )
 1654                        };
 1655
 1656                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1657
 1658                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1659                            zlog::error!(
 1660                                logger =>
 1661                                "Failed to resolve {}. Error: {}",
 1662                                describe_code_action(&action),
 1663                                err
 1664                            );
 1665                            continue;
 1666                        }
 1667
 1668                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1669                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1670                            // but filters out and logs warnings for code actions that require unreasonably
 1671                            // difficult handling on our part, such as:
 1672                            // - applying edits that call commands
 1673                            //   which can result in arbitrary workspace edits being sent from the server that
 1674                            //   have no way of being tied back to the command that initiated them (i.e. we
 1675                            //   can't know which edits are part of the format request, or if the server is done sending
 1676                            //   actions in response to the command)
 1677                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1678                            //   as we then would need to handle such changes correctly in the local history as well
 1679                            //   as the remote history through the ProjectTransaction
 1680                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1681                            // Supporting these actions is not impossible, but not supported as of yet.
 1682                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1683                                zlog::trace!(
 1684                                    logger =>
 1685                                    "No changes for code action. Skipping {}",
 1686                                    describe_code_action(&action),
 1687                                );
 1688                                continue;
 1689                            }
 1690
 1691                            let mut operations = Vec::new();
 1692                            if let Some(document_changes) = edit.document_changes {
 1693                                match document_changes {
 1694                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1695                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1696                                    ),
 1697                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1698                                }
 1699                            } else if let Some(changes) = edit.changes {
 1700                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1701                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1702                                        text_document:
 1703                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1704                                                uri,
 1705                                                version: None,
 1706                                            },
 1707                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1708                                    })
 1709                                }));
 1710                            }
 1711
 1712                            let mut edits = Vec::with_capacity(operations.len());
 1713
 1714                            if operations.is_empty() {
 1715                                zlog::trace!(
 1716                                    logger =>
 1717                                    "No changes for code action. Skipping {}",
 1718                                    describe_code_action(&action),
 1719                                );
 1720                                continue;
 1721                            }
 1722                            for operation in operations {
 1723                                let op = match operation {
 1724                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1725                                    lsp::DocumentChangeOperation::Op(_) => {
 1726                                        zlog::warn!(
 1727                                            logger =>
 1728                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1729                                            describe_code_action(&action),
 1730                                        );
 1731                                        continue 'actions;
 1732                                    }
 1733                                };
 1734                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1735                                    zlog::warn!(
 1736                                        logger =>
 1737                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1738                                        &op.text_document.uri,
 1739                                        describe_code_action(&action),
 1740                                    );
 1741                                    continue 'actions;
 1742                                };
 1743                                if &file_path != buffer_path_abs {
 1744                                    zlog::warn!(
 1745                                        logger =>
 1746                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1747                                        file_path,
 1748                                        buffer_path_abs,
 1749                                        describe_code_action(&action),
 1750                                    );
 1751                                    continue 'actions;
 1752                                }
 1753
 1754                                let mut lsp_edits = Vec::new();
 1755                                for edit in op.edits {
 1756                                    match edit {
 1757                                        Edit::Plain(edit) => {
 1758                                            if !lsp_edits.contains(&edit) {
 1759                                                lsp_edits.push(edit);
 1760                                            }
 1761                                        }
 1762                                        Edit::Annotated(edit) => {
 1763                                            if !lsp_edits.contains(&edit.text_edit) {
 1764                                                lsp_edits.push(edit.text_edit);
 1765                                            }
 1766                                        }
 1767                                        Edit::Snippet(_) => {
 1768                                            zlog::warn!(
 1769                                                logger =>
 1770                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1771                                                describe_code_action(&action),
 1772                                            );
 1773                                            continue 'actions;
 1774                                        }
 1775                                    }
 1776                                }
 1777                                let edits_result = lsp_store
 1778                                    .update(cx, |lsp_store, cx| {
 1779                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1780                                            &buffer.handle,
 1781                                            lsp_edits,
 1782                                            server.server_id(),
 1783                                            op.text_document.version,
 1784                                            cx,
 1785                                        )
 1786                                    })?
 1787                                    .await;
 1788                                let Ok(resolved_edits) = edits_result else {
 1789                                    zlog::warn!(
 1790                                        logger =>
 1791                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1792                                        buffer_path_abs.as_path(),
 1793                                        describe_code_action(&action),
 1794                                    );
 1795                                    continue 'actions;
 1796                                };
 1797                                edits.extend(resolved_edits);
 1798                            }
 1799
 1800                            if edits.is_empty() {
 1801                                zlog::warn!(logger => "No edits resolved from LSP");
 1802                                continue;
 1803                            }
 1804
 1805                            extend_formatting_transaction(
 1806                                buffer,
 1807                                formatting_transaction_id,
 1808                                cx,
 1809                                |buffer, cx| {
 1810                                    zlog::info!(
 1811                                        "Applying edits {edits:?}. Content: {:?}",
 1812                                        buffer.text()
 1813                                    );
 1814                                    buffer.edit(edits, None, cx);
 1815                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 1816                                },
 1817                            )?;
 1818                        }
 1819
 1820                        if let Some(command) = action.lsp_action.command() {
 1821                            zlog::warn!(
 1822                                logger =>
 1823                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1824                                &command.command,
 1825                            );
 1826
 1827                            // bail early if command is invalid
 1828                            let server_capabilities = server.capabilities();
 1829                            let available_commands = server_capabilities
 1830                                .execute_command_provider
 1831                                .as_ref()
 1832                                .map(|options| options.commands.as_slice())
 1833                                .unwrap_or_default();
 1834                            if !available_commands.contains(&command.command) {
 1835                                zlog::warn!(
 1836                                    logger =>
 1837                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1838                                    command.command,
 1839                                    server.name(),
 1840                                );
 1841                                continue;
 1842                            }
 1843
 1844                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 1845                            extend_formatting_transaction(
 1846                                buffer,
 1847                                formatting_transaction_id,
 1848                                cx,
 1849                                |_, _| {},
 1850                            )?;
 1851                            zlog::info!(logger => "Executing command {}", &command.command);
 1852
 1853                            lsp_store.update(cx, |this, _| {
 1854                                this.as_local_mut()
 1855                                    .unwrap()
 1856                                    .last_workspace_edits_by_language_server
 1857                                    .remove(&server.server_id());
 1858                            })?;
 1859
 1860                            let execute_command_result = server
 1861                                .request::<lsp::request::ExecuteCommand>(
 1862                                    lsp::ExecuteCommandParams {
 1863                                        command: command.command.clone(),
 1864                                        arguments: command.arguments.clone().unwrap_or_default(),
 1865                                        ..Default::default()
 1866                                    },
 1867                                )
 1868                                .await
 1869                                .into_response();
 1870
 1871                            if execute_command_result.is_err() {
 1872                                zlog::error!(
 1873                                    logger =>
 1874                                    "Failed to execute command '{}' as part of {}",
 1875                                    &command.command,
 1876                                    describe_code_action(&action),
 1877                                );
 1878                                continue 'actions;
 1879                            }
 1880
 1881                            let mut project_transaction_command =
 1882                                lsp_store.update(cx, |this, _| {
 1883                                    this.as_local_mut()
 1884                                        .unwrap()
 1885                                        .last_workspace_edits_by_language_server
 1886                                        .remove(&server.server_id())
 1887                                        .unwrap_or_default()
 1888                                })?;
 1889
 1890                            if let Some(transaction) =
 1891                                project_transaction_command.0.remove(&buffer.handle)
 1892                            {
 1893                                zlog::trace!(
 1894                                    logger =>
 1895                                    "Successfully captured {} edits that resulted from command {}",
 1896                                    transaction.edit_ids.len(),
 1897                                    &command.command,
 1898                                );
 1899                                let transaction_id_project_transaction = transaction.id;
 1900                                buffer.handle.update(cx, |buffer, _| {
 1901                                    // it may have been removed from history if push_to_history was
 1902                                    // false in deserialize_workspace_edit. If so push it so we
 1903                                    // can merge it with the format transaction
 1904                                    // and pop the combined transaction off the history stack
 1905                                    // later if push_to_history is false
 1906                                    if buffer.get_transaction(transaction.id).is_none() {
 1907                                        buffer.push_transaction(transaction, Instant::now());
 1908                                    }
 1909                                    buffer.merge_transactions(
 1910                                        transaction_id_project_transaction,
 1911                                        formatting_transaction_id,
 1912                                    );
 1913                                })?;
 1914                            }
 1915
 1916                            if !project_transaction_command.0.is_empty() {
 1917                                let mut extra_buffers = String::new();
 1918                                for buffer in project_transaction_command.0.keys() {
 1919                                    buffer
 1920                                        .read_with(cx, |b, cx| {
 1921                                            if let Some(path) = b.project_path(cx) {
 1922                                                if !extra_buffers.is_empty() {
 1923                                                    extra_buffers.push_str(", ");
 1924                                                }
 1925                                                extra_buffers.push_str(path.path.as_unix_str());
 1926                                            }
 1927                                        })
 1928                                        .ok();
 1929                                }
 1930                                zlog::warn!(
 1931                                    logger =>
 1932                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 1933                                    &command.command,
 1934                                    extra_buffers,
 1935                                );
 1936                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 1937                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 1938                                // add it so it's included, and merge it into the format transaction when its created later
 1939                            }
 1940                        }
 1941                    }
 1942                }
 1943            }
 1944        }
 1945
 1946        Ok(())
 1947    }
 1948
 1949    pub async fn format_ranges_via_lsp(
 1950        this: &WeakEntity<LspStore>,
 1951        buffer_handle: &Entity<Buffer>,
 1952        ranges: &[Range<Anchor>],
 1953        abs_path: &Path,
 1954        language_server: &Arc<LanguageServer>,
 1955        settings: &LanguageSettings,
 1956        cx: &mut AsyncApp,
 1957    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 1958        let capabilities = &language_server.capabilities();
 1959        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 1960        if range_formatting_provider == Some(&OneOf::Left(false)) {
 1961            anyhow::bail!(
 1962                "{} language server does not support range formatting",
 1963                language_server.name()
 1964            );
 1965        }
 1966
 1967        let uri = file_path_to_lsp_url(abs_path)?;
 1968        let text_document = lsp::TextDocumentIdentifier::new(uri);
 1969
 1970        let lsp_edits = {
 1971            let mut lsp_ranges = Vec::new();
 1972            this.update(cx, |_this, cx| {
 1973                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 1974                // not have been sent to the language server. This seems like a fairly systemic
 1975                // issue, though, the resolution probably is not specific to formatting.
 1976                //
 1977                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 1978                // LSP.
 1979                let snapshot = buffer_handle.read(cx).snapshot();
 1980                for range in ranges {
 1981                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 1982                }
 1983                anyhow::Ok(())
 1984            })??;
 1985
 1986            let mut edits = None;
 1987            for range in lsp_ranges {
 1988                if let Some(mut edit) = language_server
 1989                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 1990                        text_document: text_document.clone(),
 1991                        range,
 1992                        options: lsp_command::lsp_formatting_options(settings),
 1993                        work_done_progress_params: Default::default(),
 1994                    })
 1995                    .await
 1996                    .into_response()?
 1997                {
 1998                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 1999                }
 2000            }
 2001            edits
 2002        };
 2003
 2004        if let Some(lsp_edits) = lsp_edits {
 2005            this.update(cx, |this, cx| {
 2006                this.as_local_mut().unwrap().edits_from_lsp(
 2007                    buffer_handle,
 2008                    lsp_edits,
 2009                    language_server.server_id(),
 2010                    None,
 2011                    cx,
 2012                )
 2013            })?
 2014            .await
 2015        } else {
 2016            Ok(Vec::with_capacity(0))
 2017        }
 2018    }
 2019
 2020    async fn format_via_lsp(
 2021        this: &WeakEntity<LspStore>,
 2022        buffer: &Entity<Buffer>,
 2023        abs_path: &Path,
 2024        language_server: &Arc<LanguageServer>,
 2025        settings: &LanguageSettings,
 2026        cx: &mut AsyncApp,
 2027    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2028        let logger = zlog::scoped!("lsp_format");
 2029        zlog::info!(logger => "Formatting via LSP");
 2030
 2031        let uri = file_path_to_lsp_url(abs_path)?;
 2032        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2033        let capabilities = &language_server.capabilities();
 2034
 2035        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2036        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2037
 2038        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2039            let _timer = zlog::time!(logger => "format-full");
 2040            language_server
 2041                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 2042                    text_document,
 2043                    options: lsp_command::lsp_formatting_options(settings),
 2044                    work_done_progress_params: Default::default(),
 2045                })
 2046                .await
 2047                .into_response()?
 2048        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2049            let _timer = zlog::time!(logger => "format-range");
 2050            let buffer_start = lsp::Position::new(0, 0);
 2051            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 2052            language_server
 2053                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2054                    text_document: text_document.clone(),
 2055                    range: lsp::Range::new(buffer_start, buffer_end),
 2056                    options: lsp_command::lsp_formatting_options(settings),
 2057                    work_done_progress_params: Default::default(),
 2058                })
 2059                .await
 2060                .into_response()?
 2061        } else {
 2062            None
 2063        };
 2064
 2065        if let Some(lsp_edits) = lsp_edits {
 2066            this.update(cx, |this, cx| {
 2067                this.as_local_mut().unwrap().edits_from_lsp(
 2068                    buffer,
 2069                    lsp_edits,
 2070                    language_server.server_id(),
 2071                    None,
 2072                    cx,
 2073                )
 2074            })?
 2075            .await
 2076        } else {
 2077            Ok(Vec::with_capacity(0))
 2078        }
 2079    }
 2080
 2081    async fn format_via_external_command(
 2082        buffer: &FormattableBuffer,
 2083        command: &str,
 2084        arguments: Option<&[String]>,
 2085        cx: &mut AsyncApp,
 2086    ) -> Result<Option<Diff>> {
 2087        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2088            let file = File::from_dyn(buffer.file())?;
 2089            let worktree = file.worktree.read(cx);
 2090            let mut worktree_path = worktree.abs_path().to_path_buf();
 2091            if worktree.root_entry()?.is_file() {
 2092                worktree_path.pop();
 2093            }
 2094            Some(worktree_path)
 2095        })?;
 2096
 2097        let mut child = util::command::new_smol_command(command);
 2098
 2099        if let Some(buffer_env) = buffer.env.as_ref() {
 2100            child.envs(buffer_env);
 2101        }
 2102
 2103        if let Some(working_dir_path) = working_dir_path {
 2104            child.current_dir(working_dir_path);
 2105        }
 2106
 2107        if let Some(arguments) = arguments {
 2108            child.args(arguments.iter().map(|arg| {
 2109                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2110                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2111                } else {
 2112                    arg.replace("{buffer_path}", "Untitled")
 2113                }
 2114            }));
 2115        }
 2116
 2117        let mut child = child
 2118            .stdin(smol::process::Stdio::piped())
 2119            .stdout(smol::process::Stdio::piped())
 2120            .stderr(smol::process::Stdio::piped())
 2121            .spawn()?;
 2122
 2123        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2124        let text = buffer
 2125            .handle
 2126            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2127        for chunk in text.chunks() {
 2128            stdin.write_all(chunk.as_bytes()).await?;
 2129        }
 2130        stdin.flush().await?;
 2131
 2132        let output = child.output().await?;
 2133        anyhow::ensure!(
 2134            output.status.success(),
 2135            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2136            output.status.code(),
 2137            String::from_utf8_lossy(&output.stdout),
 2138            String::from_utf8_lossy(&output.stderr),
 2139        );
 2140
 2141        let stdout = String::from_utf8(output.stdout)?;
 2142        Ok(Some(
 2143            buffer
 2144                .handle
 2145                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2146                .await,
 2147        ))
 2148    }
 2149
 2150    async fn try_resolve_code_action(
 2151        lang_server: &LanguageServer,
 2152        action: &mut CodeAction,
 2153    ) -> anyhow::Result<()> {
 2154        match &mut action.lsp_action {
 2155            LspAction::Action(lsp_action) => {
 2156                if !action.resolved
 2157                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2158                    && lsp_action.data.is_some()
 2159                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2160                {
 2161                    *lsp_action = Box::new(
 2162                        lang_server
 2163                            .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2164                            .await
 2165                            .into_response()?,
 2166                    );
 2167                }
 2168            }
 2169            LspAction::CodeLens(lens) => {
 2170                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2171                    *lens = lang_server
 2172                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2173                        .await
 2174                        .into_response()?;
 2175                }
 2176            }
 2177            LspAction::Command(_) => {}
 2178        }
 2179
 2180        action.resolved = true;
 2181        anyhow::Ok(())
 2182    }
 2183
 2184    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2185        let buffer = buffer_handle.read(cx);
 2186
 2187        let file = buffer.file().cloned();
 2188
 2189        let Some(file) = File::from_dyn(file.as_ref()) else {
 2190            return;
 2191        };
 2192        if !file.is_local() {
 2193            return;
 2194        }
 2195        let path = ProjectPath::from_file(file, cx);
 2196        let worktree_id = file.worktree_id(cx);
 2197        let language = buffer.language().cloned();
 2198
 2199        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2200            for (server_id, diagnostics) in
 2201                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2202            {
 2203                self.update_buffer_diagnostics(
 2204                    buffer_handle,
 2205                    server_id,
 2206                    None,
 2207                    None,
 2208                    diagnostics,
 2209                    Vec::new(),
 2210                    cx,
 2211                )
 2212                .log_err();
 2213            }
 2214        }
 2215        let Some(language) = language else {
 2216            return;
 2217        };
 2218        let Some(snapshot) = self
 2219            .worktree_store
 2220            .read(cx)
 2221            .worktree_for_id(worktree_id, cx)
 2222            .map(|worktree| worktree.read(cx).snapshot())
 2223        else {
 2224            return;
 2225        };
 2226        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2227
 2228        for server_id in
 2229            self.lsp_tree
 2230                .get(path, language.name(), language.manifest(), &delegate, cx)
 2231        {
 2232            let server = self
 2233                .language_servers
 2234                .get(&server_id)
 2235                .and_then(|server_state| {
 2236                    if let LanguageServerState::Running { server, .. } = server_state {
 2237                        Some(server.clone())
 2238                    } else {
 2239                        None
 2240                    }
 2241                });
 2242            let server = match server {
 2243                Some(server) => server,
 2244                None => continue,
 2245            };
 2246
 2247            buffer_handle.update(cx, |buffer, cx| {
 2248                buffer.set_completion_triggers(
 2249                    server.server_id(),
 2250                    server
 2251                        .capabilities()
 2252                        .completion_provider
 2253                        .as_ref()
 2254                        .and_then(|provider| {
 2255                            provider
 2256                                .trigger_characters
 2257                                .as_ref()
 2258                                .map(|characters| characters.iter().cloned().collect())
 2259                        })
 2260                        .unwrap_or_default(),
 2261                    cx,
 2262                );
 2263            });
 2264        }
 2265    }
 2266
 2267    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2268        buffer.update(cx, |buffer, cx| {
 2269            let Some(language) = buffer.language() else {
 2270                return;
 2271            };
 2272            let path = ProjectPath {
 2273                worktree_id: old_file.worktree_id(cx),
 2274                path: old_file.path.clone(),
 2275            };
 2276            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2277                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2278                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2279            }
 2280        });
 2281    }
 2282
 2283    fn update_buffer_diagnostics(
 2284        &mut self,
 2285        buffer: &Entity<Buffer>,
 2286        server_id: LanguageServerId,
 2287        result_id: Option<String>,
 2288        version: Option<i32>,
 2289        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2290        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2291        cx: &mut Context<LspStore>,
 2292    ) -> Result<()> {
 2293        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2294            Ordering::Equal
 2295                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2296                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2297                .then_with(|| a.severity.cmp(&b.severity))
 2298                .then_with(|| a.message.cmp(&b.message))
 2299        }
 2300
 2301        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2302        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2303        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2304
 2305        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2306            Ordering::Equal
 2307                .then_with(|| a.range.start.cmp(&b.range.start))
 2308                .then_with(|| b.range.end.cmp(&a.range.end))
 2309                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2310        });
 2311
 2312        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2313
 2314        let edits_since_save = std::cell::LazyCell::new(|| {
 2315            let saved_version = buffer.read(cx).saved_version();
 2316            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2317        });
 2318
 2319        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2320
 2321        for (new_diagnostic, entry) in diagnostics {
 2322            let start;
 2323            let end;
 2324            if new_diagnostic && entry.diagnostic.is_disk_based {
 2325                // Some diagnostics are based on files on disk instead of buffers'
 2326                // current contents. Adjust these diagnostics' ranges to reflect
 2327                // any unsaved edits.
 2328                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2329                // and were properly adjusted on reuse.
 2330                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2331                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2332            } else {
 2333                start = entry.range.start;
 2334                end = entry.range.end;
 2335            }
 2336
 2337            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2338                ..snapshot.clip_point_utf16(end, Bias::Right);
 2339
 2340            // Expand empty ranges by one codepoint
 2341            if range.start == range.end {
 2342                // This will be go to the next boundary when being clipped
 2343                range.end.column += 1;
 2344                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2345                if range.start == range.end && range.end.column > 0 {
 2346                    range.start.column -= 1;
 2347                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2348                }
 2349            }
 2350
 2351            sanitized_diagnostics.push(DiagnosticEntry {
 2352                range,
 2353                diagnostic: entry.diagnostic,
 2354            });
 2355        }
 2356        drop(edits_since_save);
 2357
 2358        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2359        buffer.update(cx, |buffer, cx| {
 2360            if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2361                self.buffer_pull_diagnostics_result_ids
 2362                    .entry(server_id)
 2363                    .or_default()
 2364                    .insert(abs_path, result_id);
 2365            }
 2366
 2367            buffer.update_diagnostics(server_id, set, cx)
 2368        });
 2369
 2370        Ok(())
 2371    }
 2372
 2373    fn register_language_server_for_invisible_worktree(
 2374        &mut self,
 2375        worktree: &Entity<Worktree>,
 2376        language_server_id: LanguageServerId,
 2377        cx: &mut App,
 2378    ) {
 2379        let worktree = worktree.read(cx);
 2380        let worktree_id = worktree.id();
 2381        debug_assert!(!worktree.is_visible());
 2382        let Some(mut origin_seed) = self
 2383            .language_server_ids
 2384            .iter()
 2385            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2386        else {
 2387            return;
 2388        };
 2389        origin_seed.worktree_id = worktree_id;
 2390        self.language_server_ids
 2391            .entry(origin_seed)
 2392            .or_insert_with(|| UnifiedLanguageServer {
 2393                id: language_server_id,
 2394                project_roots: Default::default(),
 2395            });
 2396    }
 2397
 2398    fn register_buffer_with_language_servers(
 2399        &mut self,
 2400        buffer_handle: &Entity<Buffer>,
 2401        only_register_servers: HashSet<LanguageServerSelector>,
 2402        cx: &mut Context<LspStore>,
 2403    ) {
 2404        let buffer = buffer_handle.read(cx);
 2405        let buffer_id = buffer.remote_id();
 2406
 2407        let Some(file) = File::from_dyn(buffer.file()) else {
 2408            return;
 2409        };
 2410        if !file.is_local() {
 2411            return;
 2412        }
 2413
 2414        let abs_path = file.abs_path(cx);
 2415        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2416            return;
 2417        };
 2418        let initial_snapshot = buffer.text_snapshot();
 2419        let worktree_id = file.worktree_id(cx);
 2420
 2421        let Some(language) = buffer.language().cloned() else {
 2422            return;
 2423        };
 2424        let path: Arc<RelPath> = file
 2425            .path()
 2426            .parent()
 2427            .map(Arc::from)
 2428            .unwrap_or_else(|| file.path().clone());
 2429        let Some(worktree) = self
 2430            .worktree_store
 2431            .read(cx)
 2432            .worktree_for_id(worktree_id, cx)
 2433        else {
 2434            return;
 2435        };
 2436        let language_name = language.name();
 2437        let (reused, delegate, servers) = self
 2438            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2439            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2440            .unwrap_or_else(|| {
 2441                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2442                let delegate: Arc<dyn ManifestDelegate> =
 2443                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2444
 2445                let servers = self
 2446                    .lsp_tree
 2447                    .walk(
 2448                        ProjectPath { worktree_id, path },
 2449                        language.name(),
 2450                        language.manifest(),
 2451                        &delegate,
 2452                        cx,
 2453                    )
 2454                    .collect::<Vec<_>>();
 2455                (false, lsp_delegate, servers)
 2456            });
 2457        let servers_and_adapters = servers
 2458            .into_iter()
 2459            .filter_map(|server_node| {
 2460                if reused && server_node.server_id().is_none() {
 2461                    return None;
 2462                }
 2463                if !only_register_servers.is_empty() {
 2464                    if let Some(server_id) = server_node.server_id()
 2465                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2466                    {
 2467                        return None;
 2468                    }
 2469                    if let Some(name) = server_node.name()
 2470                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2471                    {
 2472                        return None;
 2473                    }
 2474                }
 2475
 2476                let server_id = server_node.server_id_or_init(|disposition| {
 2477                    let path = &disposition.path;
 2478
 2479                    {
 2480                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2481
 2482                        let server_id = self.get_or_insert_language_server(
 2483                            &worktree,
 2484                            delegate.clone(),
 2485                            disposition,
 2486                            &language_name,
 2487                            cx,
 2488                        );
 2489
 2490                        if let Some(state) = self.language_servers.get(&server_id)
 2491                            && let Ok(uri) = uri
 2492                        {
 2493                            state.add_workspace_folder(uri);
 2494                        };
 2495                        server_id
 2496                    }
 2497                })?;
 2498                let server_state = self.language_servers.get(&server_id)?;
 2499                if let LanguageServerState::Running {
 2500                    server, adapter, ..
 2501                } = server_state
 2502                {
 2503                    Some((server.clone(), adapter.clone()))
 2504                } else {
 2505                    None
 2506                }
 2507            })
 2508            .collect::<Vec<_>>();
 2509        for (server, adapter) in servers_and_adapters {
 2510            buffer_handle.update(cx, |buffer, cx| {
 2511                buffer.set_completion_triggers(
 2512                    server.server_id(),
 2513                    server
 2514                        .capabilities()
 2515                        .completion_provider
 2516                        .as_ref()
 2517                        .and_then(|provider| {
 2518                            provider
 2519                                .trigger_characters
 2520                                .as_ref()
 2521                                .map(|characters| characters.iter().cloned().collect())
 2522                        })
 2523                        .unwrap_or_default(),
 2524                    cx,
 2525                );
 2526            });
 2527
 2528            let snapshot = LspBufferSnapshot {
 2529                version: 0,
 2530                snapshot: initial_snapshot.clone(),
 2531            };
 2532
 2533            let mut registered = false;
 2534            self.buffer_snapshots
 2535                .entry(buffer_id)
 2536                .or_default()
 2537                .entry(server.server_id())
 2538                .or_insert_with(|| {
 2539                    registered = true;
 2540                    server.register_buffer(
 2541                        uri.clone(),
 2542                        adapter.language_id(&language.name()),
 2543                        0,
 2544                        initial_snapshot.text(),
 2545                    );
 2546
 2547                    vec![snapshot]
 2548                });
 2549
 2550            self.buffers_opened_in_servers
 2551                .entry(buffer_id)
 2552                .or_default()
 2553                .insert(server.server_id());
 2554            if registered {
 2555                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2556                    language_server_id: server.server_id(),
 2557                    name: None,
 2558                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2559                        proto::RegisteredForBuffer {
 2560                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2561                            buffer_id: buffer_id.to_proto(),
 2562                        },
 2563                    ),
 2564                });
 2565            }
 2566        }
 2567    }
 2568
 2569    fn reuse_existing_language_server<'lang_name>(
 2570        &self,
 2571        server_tree: &LanguageServerTree,
 2572        worktree: &Entity<Worktree>,
 2573        language_name: &'lang_name LanguageName,
 2574        cx: &mut App,
 2575    ) -> Option<(
 2576        Arc<LocalLspAdapterDelegate>,
 2577        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2578    )> {
 2579        if worktree.read(cx).is_visible() {
 2580            return None;
 2581        }
 2582
 2583        let worktree_store = self.worktree_store.read(cx);
 2584        let servers = server_tree
 2585            .instances
 2586            .iter()
 2587            .filter(|(worktree_id, _)| {
 2588                worktree_store
 2589                    .worktree_for_id(**worktree_id, cx)
 2590                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2591            })
 2592            .flat_map(|(worktree_id, servers)| {
 2593                servers
 2594                    .roots
 2595                    .iter()
 2596                    .flat_map(|(_, language_servers)| language_servers)
 2597                    .map(move |(_, (server_node, server_languages))| {
 2598                        (worktree_id, server_node, server_languages)
 2599                    })
 2600                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2601                    .map(|(worktree_id, server_node, _)| {
 2602                        (
 2603                            *worktree_id,
 2604                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2605                        )
 2606                    })
 2607            })
 2608            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2609                acc.entry(worktree_id)
 2610                    .or_insert_with(Vec::new)
 2611                    .push(server_node);
 2612                acc
 2613            })
 2614            .into_values()
 2615            .max_by_key(|servers| servers.len())?;
 2616
 2617        let worktree_id = worktree.read(cx).id();
 2618        let apply = move |tree: &mut LanguageServerTree| {
 2619            for server_node in &servers {
 2620                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2621            }
 2622            servers
 2623        };
 2624
 2625        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2626        Some((delegate, apply))
 2627    }
 2628
 2629    pub(crate) fn unregister_old_buffer_from_language_servers(
 2630        &mut self,
 2631        buffer: &Entity<Buffer>,
 2632        old_file: &File,
 2633        cx: &mut App,
 2634    ) {
 2635        let old_path = match old_file.as_local() {
 2636            Some(local) => local.abs_path(cx),
 2637            None => return,
 2638        };
 2639
 2640        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2641            debug_panic!("{old_path:?} is not parseable as an URI");
 2642            return;
 2643        };
 2644        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2645    }
 2646
 2647    pub(crate) fn unregister_buffer_from_language_servers(
 2648        &mut self,
 2649        buffer: &Entity<Buffer>,
 2650        file_url: &lsp::Uri,
 2651        cx: &mut App,
 2652    ) {
 2653        buffer.update(cx, |buffer, cx| {
 2654            let _ = self.buffer_snapshots.remove(&buffer.remote_id());
 2655
 2656            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2657                language_server.unregister_buffer(file_url.clone());
 2658            }
 2659        });
 2660    }
 2661
 2662    fn buffer_snapshot_for_lsp_version(
 2663        &mut self,
 2664        buffer: &Entity<Buffer>,
 2665        server_id: LanguageServerId,
 2666        version: Option<i32>,
 2667        cx: &App,
 2668    ) -> Result<TextBufferSnapshot> {
 2669        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2670
 2671        if let Some(version) = version {
 2672            let buffer_id = buffer.read(cx).remote_id();
 2673            let snapshots = if let Some(snapshots) = self
 2674                .buffer_snapshots
 2675                .get_mut(&buffer_id)
 2676                .and_then(|m| m.get_mut(&server_id))
 2677            {
 2678                snapshots
 2679            } else if version == 0 {
 2680                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2681                // We detect this case and treat it as if the version was `None`.
 2682                return Ok(buffer.read(cx).text_snapshot());
 2683            } else {
 2684                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2685            };
 2686
 2687            let found_snapshot = snapshots
 2688                    .binary_search_by_key(&version, |e| e.version)
 2689                    .map(|ix| snapshots[ix].snapshot.clone())
 2690                    .map_err(|_| {
 2691                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2692                    })?;
 2693
 2694            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2695            Ok(found_snapshot)
 2696        } else {
 2697            Ok((buffer.read(cx)).text_snapshot())
 2698        }
 2699    }
 2700
 2701    async fn get_server_code_actions_from_action_kinds(
 2702        lsp_store: &WeakEntity<LspStore>,
 2703        language_server_id: LanguageServerId,
 2704        code_action_kinds: Vec<lsp::CodeActionKind>,
 2705        buffer: &Entity<Buffer>,
 2706        cx: &mut AsyncApp,
 2707    ) -> Result<Vec<CodeAction>> {
 2708        let actions = lsp_store
 2709            .update(cx, move |this, cx| {
 2710                let request = GetCodeActions {
 2711                    range: text::Anchor::MIN..text::Anchor::MAX,
 2712                    kinds: Some(code_action_kinds),
 2713                };
 2714                let server = LanguageServerToQuery::Other(language_server_id);
 2715                this.request_lsp(buffer.clone(), server, request, cx)
 2716            })?
 2717            .await?;
 2718        Ok(actions)
 2719    }
 2720
 2721    pub async fn execute_code_actions_on_server(
 2722        lsp_store: &WeakEntity<LspStore>,
 2723        language_server: &Arc<LanguageServer>,
 2724
 2725        actions: Vec<CodeAction>,
 2726        push_to_history: bool,
 2727        project_transaction: &mut ProjectTransaction,
 2728        cx: &mut AsyncApp,
 2729    ) -> anyhow::Result<()> {
 2730        for mut action in actions {
 2731            Self::try_resolve_code_action(language_server, &mut action)
 2732                .await
 2733                .context("resolving a formatting code action")?;
 2734
 2735            if let Some(edit) = action.lsp_action.edit() {
 2736                if edit.changes.is_none() && edit.document_changes.is_none() {
 2737                    continue;
 2738                }
 2739
 2740                let new = Self::deserialize_workspace_edit(
 2741                    lsp_store.upgrade().context("project dropped")?,
 2742                    edit.clone(),
 2743                    push_to_history,
 2744                    language_server.clone(),
 2745                    cx,
 2746                )
 2747                .await?;
 2748                project_transaction.0.extend(new.0);
 2749            }
 2750
 2751            if let Some(command) = action.lsp_action.command() {
 2752                let server_capabilities = language_server.capabilities();
 2753                let available_commands = server_capabilities
 2754                    .execute_command_provider
 2755                    .as_ref()
 2756                    .map(|options| options.commands.as_slice())
 2757                    .unwrap_or_default();
 2758                if available_commands.contains(&command.command) {
 2759                    lsp_store.update(cx, |lsp_store, _| {
 2760                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2761                            mode.last_workspace_edits_by_language_server
 2762                                .remove(&language_server.server_id());
 2763                        }
 2764                    })?;
 2765
 2766                    language_server
 2767                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2768                            command: command.command.clone(),
 2769                            arguments: command.arguments.clone().unwrap_or_default(),
 2770                            ..Default::default()
 2771                        })
 2772                        .await
 2773                        .into_response()
 2774                        .context("execute command")?;
 2775
 2776                    lsp_store.update(cx, |this, _| {
 2777                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2778                            project_transaction.0.extend(
 2779                                mode.last_workspace_edits_by_language_server
 2780                                    .remove(&language_server.server_id())
 2781                                    .unwrap_or_default()
 2782                                    .0,
 2783                            )
 2784                        }
 2785                    })?;
 2786                } else {
 2787                    log::warn!(
 2788                        "Cannot execute a command {} not listed in the language server capabilities",
 2789                        command.command
 2790                    )
 2791                }
 2792            }
 2793        }
 2794        Ok(())
 2795    }
 2796
 2797    pub async fn deserialize_text_edits(
 2798        this: Entity<LspStore>,
 2799        buffer_to_edit: Entity<Buffer>,
 2800        edits: Vec<lsp::TextEdit>,
 2801        push_to_history: bool,
 2802        _: Arc<CachedLspAdapter>,
 2803        language_server: Arc<LanguageServer>,
 2804        cx: &mut AsyncApp,
 2805    ) -> Result<Option<Transaction>> {
 2806        let edits = this
 2807            .update(cx, |this, cx| {
 2808                this.as_local_mut().unwrap().edits_from_lsp(
 2809                    &buffer_to_edit,
 2810                    edits,
 2811                    language_server.server_id(),
 2812                    None,
 2813                    cx,
 2814                )
 2815            })?
 2816            .await?;
 2817
 2818        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2819            buffer.finalize_last_transaction();
 2820            buffer.start_transaction();
 2821            for (range, text) in edits {
 2822                buffer.edit([(range, text)], None, cx);
 2823            }
 2824
 2825            if buffer.end_transaction(cx).is_some() {
 2826                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2827                if !push_to_history {
 2828                    buffer.forget_transaction(transaction.id);
 2829                }
 2830                Some(transaction)
 2831            } else {
 2832                None
 2833            }
 2834        })?;
 2835
 2836        Ok(transaction)
 2837    }
 2838
 2839    #[allow(clippy::type_complexity)]
 2840    pub(crate) fn edits_from_lsp(
 2841        &mut self,
 2842        buffer: &Entity<Buffer>,
 2843        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2844        server_id: LanguageServerId,
 2845        version: Option<i32>,
 2846        cx: &mut Context<LspStore>,
 2847    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 2848        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 2849        cx.background_spawn(async move {
 2850            let snapshot = snapshot?;
 2851            let mut lsp_edits = lsp_edits
 2852                .into_iter()
 2853                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 2854                .collect::<Vec<_>>();
 2855
 2856            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 2857
 2858            let mut lsp_edits = lsp_edits.into_iter().peekable();
 2859            let mut edits = Vec::new();
 2860            while let Some((range, mut new_text)) = lsp_edits.next() {
 2861                // Clip invalid ranges provided by the language server.
 2862                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 2863                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 2864
 2865                // Combine any LSP edits that are adjacent.
 2866                //
 2867                // Also, combine LSP edits that are separated from each other by only
 2868                // a newline. This is important because for some code actions,
 2869                // Rust-analyzer rewrites the entire buffer via a series of edits that
 2870                // are separated by unchanged newline characters.
 2871                //
 2872                // In order for the diffing logic below to work properly, any edits that
 2873                // cancel each other out must be combined into one.
 2874                while let Some((next_range, next_text)) = lsp_edits.peek() {
 2875                    if next_range.start.0 > range.end {
 2876                        if next_range.start.0.row > range.end.row + 1
 2877                            || next_range.start.0.column > 0
 2878                            || snapshot.clip_point_utf16(
 2879                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 2880                                Bias::Left,
 2881                            ) > range.end
 2882                        {
 2883                            break;
 2884                        }
 2885                        new_text.push('\n');
 2886                    }
 2887                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 2888                    new_text.push_str(next_text);
 2889                    lsp_edits.next();
 2890                }
 2891
 2892                // For multiline edits, perform a diff of the old and new text so that
 2893                // we can identify the changes more precisely, preserving the locations
 2894                // of any anchors positioned in the unchanged regions.
 2895                if range.end.row > range.start.row {
 2896                    let offset = range.start.to_offset(&snapshot);
 2897                    let old_text = snapshot.text_for_range(range).collect::<String>();
 2898                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 2899                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 2900                        (
 2901                            snapshot.anchor_after(offset + range.start)
 2902                                ..snapshot.anchor_before(offset + range.end),
 2903                            replacement,
 2904                        )
 2905                    }));
 2906                } else if range.end == range.start {
 2907                    let anchor = snapshot.anchor_after(range.start);
 2908                    edits.push((anchor..anchor, new_text.into()));
 2909                } else {
 2910                    let edit_start = snapshot.anchor_after(range.start);
 2911                    let edit_end = snapshot.anchor_before(range.end);
 2912                    edits.push((edit_start..edit_end, new_text.into()));
 2913                }
 2914            }
 2915
 2916            Ok(edits)
 2917        })
 2918    }
 2919
 2920    pub(crate) async fn deserialize_workspace_edit(
 2921        this: Entity<LspStore>,
 2922        edit: lsp::WorkspaceEdit,
 2923        push_to_history: bool,
 2924        language_server: Arc<LanguageServer>,
 2925        cx: &mut AsyncApp,
 2926    ) -> Result<ProjectTransaction> {
 2927        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 2928
 2929        let mut operations = Vec::new();
 2930        if let Some(document_changes) = edit.document_changes {
 2931            match document_changes {
 2932                lsp::DocumentChanges::Edits(edits) => {
 2933                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 2934                }
 2935                lsp::DocumentChanges::Operations(ops) => operations = ops,
 2936            }
 2937        } else if let Some(changes) = edit.changes {
 2938            operations.extend(changes.into_iter().map(|(uri, edits)| {
 2939                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 2940                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 2941                        uri,
 2942                        version: None,
 2943                    },
 2944                    edits: edits.into_iter().map(Edit::Plain).collect(),
 2945                })
 2946            }));
 2947        }
 2948
 2949        let mut project_transaction = ProjectTransaction::default();
 2950        for operation in operations {
 2951            match operation {
 2952                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 2953                    let abs_path = op
 2954                        .uri
 2955                        .to_file_path()
 2956                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2957
 2958                    if let Some(parent_path) = abs_path.parent() {
 2959                        fs.create_dir(parent_path).await?;
 2960                    }
 2961                    if abs_path.ends_with("/") {
 2962                        fs.create_dir(&abs_path).await?;
 2963                    } else {
 2964                        fs.create_file(
 2965                            &abs_path,
 2966                            op.options
 2967                                .map(|options| fs::CreateOptions {
 2968                                    overwrite: options.overwrite.unwrap_or(false),
 2969                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 2970                                })
 2971                                .unwrap_or_default(),
 2972                        )
 2973                        .await?;
 2974                    }
 2975                }
 2976
 2977                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 2978                    let source_abs_path = op
 2979                        .old_uri
 2980                        .to_file_path()
 2981                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2982                    let target_abs_path = op
 2983                        .new_uri
 2984                        .to_file_path()
 2985                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2986                    fs.rename(
 2987                        &source_abs_path,
 2988                        &target_abs_path,
 2989                        op.options
 2990                            .map(|options| fs::RenameOptions {
 2991                                overwrite: options.overwrite.unwrap_or(false),
 2992                                ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 2993                            })
 2994                            .unwrap_or_default(),
 2995                    )
 2996                    .await?;
 2997                }
 2998
 2999                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3000                    let abs_path = op
 3001                        .uri
 3002                        .to_file_path()
 3003                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3004                    let options = op
 3005                        .options
 3006                        .map(|options| fs::RemoveOptions {
 3007                            recursive: options.recursive.unwrap_or(false),
 3008                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3009                        })
 3010                        .unwrap_or_default();
 3011                    if abs_path.ends_with("/") {
 3012                        fs.remove_dir(&abs_path, options).await?;
 3013                    } else {
 3014                        fs.remove_file(&abs_path, options).await?;
 3015                    }
 3016                }
 3017
 3018                lsp::DocumentChangeOperation::Edit(op) => {
 3019                    let buffer_to_edit = this
 3020                        .update(cx, |this, cx| {
 3021                            this.open_local_buffer_via_lsp(
 3022                                op.text_document.uri.clone(),
 3023                                language_server.server_id(),
 3024                                cx,
 3025                            )
 3026                        })?
 3027                        .await?;
 3028
 3029                    let edits = this
 3030                        .update(cx, |this, cx| {
 3031                            let path = buffer_to_edit.read(cx).project_path(cx);
 3032                            let active_entry = this.active_entry;
 3033                            let is_active_entry = path.is_some_and(|project_path| {
 3034                                this.worktree_store
 3035                                    .read(cx)
 3036                                    .entry_for_path(&project_path, cx)
 3037                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3038                            });
 3039                            let local = this.as_local_mut().unwrap();
 3040
 3041                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3042                            for edit in op.edits {
 3043                                match edit {
 3044                                    Edit::Plain(edit) => {
 3045                                        if !edits.contains(&edit) {
 3046                                            edits.push(edit)
 3047                                        }
 3048                                    }
 3049                                    Edit::Annotated(edit) => {
 3050                                        if !edits.contains(&edit.text_edit) {
 3051                                            edits.push(edit.text_edit)
 3052                                        }
 3053                                    }
 3054                                    Edit::Snippet(edit) => {
 3055                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3056                                        else {
 3057                                            continue;
 3058                                        };
 3059
 3060                                        if is_active_entry {
 3061                                            snippet_edits.push((edit.range, snippet));
 3062                                        } else {
 3063                                            // Since this buffer is not focused, apply a normal edit.
 3064                                            let new_edit = TextEdit {
 3065                                                range: edit.range,
 3066                                                new_text: snippet.text,
 3067                                            };
 3068                                            if !edits.contains(&new_edit) {
 3069                                                edits.push(new_edit);
 3070                                            }
 3071                                        }
 3072                                    }
 3073                                }
 3074                            }
 3075                            if !snippet_edits.is_empty() {
 3076                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3077                                let version = if let Some(buffer_version) = op.text_document.version
 3078                                {
 3079                                    local
 3080                                        .buffer_snapshot_for_lsp_version(
 3081                                            &buffer_to_edit,
 3082                                            language_server.server_id(),
 3083                                            Some(buffer_version),
 3084                                            cx,
 3085                                        )
 3086                                        .ok()
 3087                                        .map(|snapshot| snapshot.version)
 3088                                } else {
 3089                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3090                                };
 3091
 3092                                let most_recent_edit =
 3093                                    version.and_then(|version| version.most_recent());
 3094                                // Check if the edit that triggered that edit has been made by this participant.
 3095
 3096                                if let Some(most_recent_edit) = most_recent_edit {
 3097                                    cx.emit(LspStoreEvent::SnippetEdit {
 3098                                        buffer_id,
 3099                                        edits: snippet_edits,
 3100                                        most_recent_edit,
 3101                                    });
 3102                                }
 3103                            }
 3104
 3105                            local.edits_from_lsp(
 3106                                &buffer_to_edit,
 3107                                edits,
 3108                                language_server.server_id(),
 3109                                op.text_document.version,
 3110                                cx,
 3111                            )
 3112                        })?
 3113                        .await?;
 3114
 3115                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3116                        buffer.finalize_last_transaction();
 3117                        buffer.start_transaction();
 3118                        for (range, text) in edits {
 3119                            buffer.edit([(range, text)], None, cx);
 3120                        }
 3121
 3122                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3123                            if push_to_history {
 3124                                buffer.finalize_last_transaction();
 3125                                buffer.get_transaction(transaction_id).cloned()
 3126                            } else {
 3127                                buffer.forget_transaction(transaction_id)
 3128                            }
 3129                        })
 3130                    })?;
 3131                    if let Some(transaction) = transaction {
 3132                        project_transaction.0.insert(buffer_to_edit, transaction);
 3133                    }
 3134                }
 3135            }
 3136        }
 3137
 3138        Ok(project_transaction)
 3139    }
 3140
 3141    async fn on_lsp_workspace_edit(
 3142        this: WeakEntity<LspStore>,
 3143        params: lsp::ApplyWorkspaceEditParams,
 3144        server_id: LanguageServerId,
 3145        cx: &mut AsyncApp,
 3146    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3147        let this = this.upgrade().context("project project closed")?;
 3148        let language_server = this
 3149            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3150            .context("language server not found")?;
 3151        let transaction = Self::deserialize_workspace_edit(
 3152            this.clone(),
 3153            params.edit,
 3154            true,
 3155            language_server.clone(),
 3156            cx,
 3157        )
 3158        .await
 3159        .log_err();
 3160        this.update(cx, |this, _| {
 3161            if let Some(transaction) = transaction {
 3162                this.as_local_mut()
 3163                    .unwrap()
 3164                    .last_workspace_edits_by_language_server
 3165                    .insert(server_id, transaction);
 3166            }
 3167        })?;
 3168        Ok(lsp::ApplyWorkspaceEditResponse {
 3169            applied: true,
 3170            failed_change: None,
 3171            failure_reason: None,
 3172        })
 3173    }
 3174
 3175    fn remove_worktree(
 3176        &mut self,
 3177        id_to_remove: WorktreeId,
 3178        cx: &mut Context<LspStore>,
 3179    ) -> Vec<LanguageServerId> {
 3180        self.diagnostics.remove(&id_to_remove);
 3181        self.prettier_store.update(cx, |prettier_store, cx| {
 3182            prettier_store.remove_worktree(id_to_remove, cx);
 3183        });
 3184
 3185        let mut servers_to_remove = BTreeSet::default();
 3186        let mut servers_to_preserve = HashSet::default();
 3187        for (seed, state) in &self.language_server_ids {
 3188            if seed.worktree_id == id_to_remove {
 3189                servers_to_remove.insert(state.id);
 3190            } else {
 3191                servers_to_preserve.insert(state.id);
 3192            }
 3193        }
 3194        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3195        self.language_server_ids
 3196            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3197        for server_id_to_remove in &servers_to_remove {
 3198            self.language_server_watched_paths
 3199                .remove(server_id_to_remove);
 3200            self.language_server_paths_watched_for_rename
 3201                .remove(server_id_to_remove);
 3202            self.last_workspace_edits_by_language_server
 3203                .remove(server_id_to_remove);
 3204            self.language_servers.remove(server_id_to_remove);
 3205            self.buffer_pull_diagnostics_result_ids
 3206                .remove(server_id_to_remove);
 3207            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3208                buffer_servers.remove(server_id_to_remove);
 3209            }
 3210            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3211        }
 3212        servers_to_remove.into_iter().collect()
 3213    }
 3214
 3215    fn rebuild_watched_paths_inner<'a>(
 3216        &'a self,
 3217        language_server_id: LanguageServerId,
 3218        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3219        cx: &mut Context<LspStore>,
 3220    ) -> LanguageServerWatchedPathsBuilder {
 3221        let worktrees = self
 3222            .worktree_store
 3223            .read(cx)
 3224            .worktrees()
 3225            .filter_map(|worktree| {
 3226                self.language_servers_for_worktree(worktree.read(cx).id())
 3227                    .find(|server| server.server_id() == language_server_id)
 3228                    .map(|_| worktree)
 3229            })
 3230            .collect::<Vec<_>>();
 3231
 3232        let mut worktree_globs = HashMap::default();
 3233        let mut abs_globs = HashMap::default();
 3234        log::trace!(
 3235            "Processing new watcher paths for language server with id {}",
 3236            language_server_id
 3237        );
 3238
 3239        for watcher in watchers {
 3240            if let Some((worktree, literal_prefix, pattern)) =
 3241                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3242            {
 3243                worktree.update(cx, |worktree, _| {
 3244                    if let Some((tree, glob)) =
 3245                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3246                    {
 3247                        tree.add_path_prefix_to_scan(literal_prefix);
 3248                        worktree_globs
 3249                            .entry(tree.id())
 3250                            .or_insert_with(GlobSetBuilder::new)
 3251                            .add(glob);
 3252                    }
 3253                });
 3254            } else {
 3255                let (path, pattern) = match &watcher.glob_pattern {
 3256                    lsp::GlobPattern::String(s) => {
 3257                        let watcher_path = SanitizedPath::new(s);
 3258                        let path = glob_literal_prefix(watcher_path.as_path());
 3259                        let pattern = watcher_path
 3260                            .as_path()
 3261                            .strip_prefix(&path)
 3262                            .map(|p| p.to_string_lossy().into_owned())
 3263                            .unwrap_or_else(|e| {
 3264                                debug_panic!(
 3265                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3266                                    s,
 3267                                    path.display(),
 3268                                    e
 3269                                );
 3270                                watcher_path.as_path().to_string_lossy().into_owned()
 3271                            });
 3272                        (path, pattern)
 3273                    }
 3274                    lsp::GlobPattern::Relative(rp) => {
 3275                        let Ok(mut base_uri) = match &rp.base_uri {
 3276                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3277                            lsp::OneOf::Right(base_uri) => base_uri,
 3278                        }
 3279                        .to_file_path() else {
 3280                            continue;
 3281                        };
 3282
 3283                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3284                        let pattern = Path::new(&rp.pattern)
 3285                            .strip_prefix(&path)
 3286                            .map(|p| p.to_string_lossy().into_owned())
 3287                            .unwrap_or_else(|e| {
 3288                                debug_panic!(
 3289                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3290                                    rp.pattern,
 3291                                    path.display(),
 3292                                    e
 3293                                );
 3294                                rp.pattern.clone()
 3295                            });
 3296                        base_uri.push(path);
 3297                        (base_uri, pattern)
 3298                    }
 3299                };
 3300
 3301                if let Some(glob) = Glob::new(&pattern).log_err() {
 3302                    if !path
 3303                        .components()
 3304                        .any(|c| matches!(c, path::Component::Normal(_)))
 3305                    {
 3306                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3307                        // rather than adding a new watcher for `/`.
 3308                        for worktree in &worktrees {
 3309                            worktree_globs
 3310                                .entry(worktree.read(cx).id())
 3311                                .or_insert_with(GlobSetBuilder::new)
 3312                                .add(glob.clone());
 3313                        }
 3314                    } else {
 3315                        abs_globs
 3316                            .entry(path.into())
 3317                            .or_insert_with(GlobSetBuilder::new)
 3318                            .add(glob);
 3319                    }
 3320                }
 3321            }
 3322        }
 3323
 3324        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3325        for (worktree_id, builder) in worktree_globs {
 3326            if let Ok(globset) = builder.build() {
 3327                watch_builder.watch_worktree(worktree_id, globset);
 3328            }
 3329        }
 3330        for (abs_path, builder) in abs_globs {
 3331            if let Ok(globset) = builder.build() {
 3332                watch_builder.watch_abs_path(abs_path, globset);
 3333            }
 3334        }
 3335        watch_builder
 3336    }
 3337
 3338    fn worktree_and_path_for_file_watcher(
 3339        worktrees: &[Entity<Worktree>],
 3340        watcher: &FileSystemWatcher,
 3341        cx: &App,
 3342    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3343        worktrees.iter().find_map(|worktree| {
 3344            let tree = worktree.read(cx);
 3345            let worktree_root_path = tree.abs_path();
 3346            let path_style = tree.path_style();
 3347            match &watcher.glob_pattern {
 3348                lsp::GlobPattern::String(s) => {
 3349                    let watcher_path = SanitizedPath::new(s);
 3350                    let relative = watcher_path
 3351                        .as_path()
 3352                        .strip_prefix(&worktree_root_path)
 3353                        .ok()?;
 3354                    let literal_prefix = glob_literal_prefix(relative);
 3355                    Some((
 3356                        worktree.clone(),
 3357                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3358                        relative.to_string_lossy().into_owned(),
 3359                    ))
 3360                }
 3361                lsp::GlobPattern::Relative(rp) => {
 3362                    let base_uri = match &rp.base_uri {
 3363                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3364                        lsp::OneOf::Right(base_uri) => base_uri,
 3365                    }
 3366                    .to_file_path()
 3367                    .ok()?;
 3368                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3369                    let mut literal_prefix = relative.to_owned();
 3370                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3371                    Some((
 3372                        worktree.clone(),
 3373                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3374                        rp.pattern.clone(),
 3375                    ))
 3376                }
 3377            }
 3378        })
 3379    }
 3380
 3381    fn rebuild_watched_paths(
 3382        &mut self,
 3383        language_server_id: LanguageServerId,
 3384        cx: &mut Context<LspStore>,
 3385    ) {
 3386        let Some(registrations) = self
 3387            .language_server_dynamic_registrations
 3388            .get(&language_server_id)
 3389        else {
 3390            return;
 3391        };
 3392
 3393        let watch_builder = self.rebuild_watched_paths_inner(
 3394            language_server_id,
 3395            registrations.did_change_watched_files.values().flatten(),
 3396            cx,
 3397        );
 3398        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3399        self.language_server_watched_paths
 3400            .insert(language_server_id, watcher);
 3401
 3402        cx.notify();
 3403    }
 3404
 3405    fn on_lsp_did_change_watched_files(
 3406        &mut self,
 3407        language_server_id: LanguageServerId,
 3408        registration_id: &str,
 3409        params: DidChangeWatchedFilesRegistrationOptions,
 3410        cx: &mut Context<LspStore>,
 3411    ) {
 3412        let registrations = self
 3413            .language_server_dynamic_registrations
 3414            .entry(language_server_id)
 3415            .or_default();
 3416
 3417        registrations
 3418            .did_change_watched_files
 3419            .insert(registration_id.to_string(), params.watchers);
 3420
 3421        self.rebuild_watched_paths(language_server_id, cx);
 3422    }
 3423
 3424    fn on_lsp_unregister_did_change_watched_files(
 3425        &mut self,
 3426        language_server_id: LanguageServerId,
 3427        registration_id: &str,
 3428        cx: &mut Context<LspStore>,
 3429    ) {
 3430        let registrations = self
 3431            .language_server_dynamic_registrations
 3432            .entry(language_server_id)
 3433            .or_default();
 3434
 3435        if registrations
 3436            .did_change_watched_files
 3437            .remove(registration_id)
 3438            .is_some()
 3439        {
 3440            log::info!(
 3441                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3442                language_server_id,
 3443                registration_id
 3444            );
 3445        } else {
 3446            log::warn!(
 3447                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3448                language_server_id,
 3449                registration_id
 3450            );
 3451        }
 3452
 3453        self.rebuild_watched_paths(language_server_id, cx);
 3454    }
 3455
 3456    async fn initialization_options_for_adapter(
 3457        adapter: Arc<dyn LspAdapter>,
 3458        delegate: &Arc<dyn LspAdapterDelegate>,
 3459    ) -> Result<Option<serde_json::Value>> {
 3460        let Some(mut initialization_config) =
 3461            adapter.clone().initialization_options(delegate).await?
 3462        else {
 3463            return Ok(None);
 3464        };
 3465
 3466        for other_adapter in delegate.registered_lsp_adapters() {
 3467            if other_adapter.name() == adapter.name() {
 3468                continue;
 3469            }
 3470            if let Ok(Some(target_config)) = other_adapter
 3471                .clone()
 3472                .additional_initialization_options(adapter.name(), delegate)
 3473                .await
 3474            {
 3475                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3476            }
 3477        }
 3478
 3479        Ok(Some(initialization_config))
 3480    }
 3481
 3482    async fn workspace_configuration_for_adapter(
 3483        adapter: Arc<dyn LspAdapter>,
 3484        delegate: &Arc<dyn LspAdapterDelegate>,
 3485        toolchain: Option<Toolchain>,
 3486        cx: &mut AsyncApp,
 3487    ) -> Result<serde_json::Value> {
 3488        let mut workspace_config = adapter
 3489            .clone()
 3490            .workspace_configuration(delegate, toolchain, cx)
 3491            .await?;
 3492
 3493        for other_adapter in delegate.registered_lsp_adapters() {
 3494            if other_adapter.name() == adapter.name() {
 3495                continue;
 3496            }
 3497            if let Ok(Some(target_config)) = other_adapter
 3498                .clone()
 3499                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3500                .await
 3501            {
 3502                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3503            }
 3504        }
 3505
 3506        Ok(workspace_config)
 3507    }
 3508
 3509    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3510        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3511            Some(server.clone())
 3512        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3513            Some(Arc::clone(server))
 3514        } else {
 3515            None
 3516        }
 3517    }
 3518}
 3519
 3520fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3521    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3522        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3523            language_server_id: server.server_id(),
 3524            name: Some(server.name()),
 3525            message: proto::update_language_server::Variant::MetadataUpdated(
 3526                proto::ServerMetadataUpdated {
 3527                    capabilities: Some(capabilities),
 3528                },
 3529            ),
 3530        });
 3531    }
 3532}
 3533
 3534#[derive(Debug)]
 3535pub struct FormattableBuffer {
 3536    handle: Entity<Buffer>,
 3537    abs_path: Option<PathBuf>,
 3538    env: Option<HashMap<String, String>>,
 3539    ranges: Option<Vec<Range<Anchor>>>,
 3540}
 3541
 3542pub struct RemoteLspStore {
 3543    upstream_client: Option<AnyProtoClient>,
 3544    upstream_project_id: u64,
 3545}
 3546
 3547pub(crate) enum LspStoreMode {
 3548    Local(LocalLspStore),   // ssh host and collab host
 3549    Remote(RemoteLspStore), // collab guest
 3550}
 3551
 3552impl LspStoreMode {
 3553    fn is_local(&self) -> bool {
 3554        matches!(self, LspStoreMode::Local(_))
 3555    }
 3556}
 3557
 3558pub struct LspStore {
 3559    mode: LspStoreMode,
 3560    last_formatting_failure: Option<String>,
 3561    downstream_client: Option<(AnyProtoClient, u64)>,
 3562    nonce: u128,
 3563    buffer_store: Entity<BufferStore>,
 3564    worktree_store: Entity<WorktreeStore>,
 3565    pub languages: Arc<LanguageRegistry>,
 3566    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3567    active_entry: Option<ProjectEntryId>,
 3568    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3569    _maintain_buffer_languages: Task<()>,
 3570    diagnostic_summaries:
 3571        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3572    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3573    lsp_data: HashMap<BufferId, BufferLspData>,
 3574    next_hint_id: Arc<AtomicUsize>,
 3575}
 3576
 3577#[derive(Debug)]
 3578pub struct BufferLspData {
 3579    buffer_version: Global,
 3580    document_colors: Option<DocumentColorData>,
 3581    code_lens: Option<CodeLensData>,
 3582    inlay_hints: BufferInlayHints,
 3583    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3584    chunk_lsp_requests: HashMap<LspKey, HashMap<BufferChunk, LspRequestId>>,
 3585}
 3586
 3587#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3588struct LspKey {
 3589    request_type: TypeId,
 3590    server_queried: Option<LanguageServerId>,
 3591}
 3592
 3593impl BufferLspData {
 3594    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3595        Self {
 3596            buffer_version: buffer.read(cx).version(),
 3597            document_colors: None,
 3598            code_lens: None,
 3599            inlay_hints: BufferInlayHints::new(buffer, cx),
 3600            lsp_requests: HashMap::default(),
 3601            chunk_lsp_requests: HashMap::default(),
 3602        }
 3603    }
 3604
 3605    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3606        if let Some(document_colors) = &mut self.document_colors {
 3607            document_colors.colors.remove(&for_server);
 3608            document_colors.cache_version += 1;
 3609        }
 3610
 3611        if let Some(code_lens) = &mut self.code_lens {
 3612            code_lens.lens.remove(&for_server);
 3613        }
 3614
 3615        self.inlay_hints.remove_server_data(for_server);
 3616    }
 3617
 3618    #[cfg(any(test, feature = "test-support"))]
 3619    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3620        &self.inlay_hints
 3621    }
 3622}
 3623
 3624#[derive(Debug, Default, Clone)]
 3625pub struct DocumentColors {
 3626    pub colors: HashSet<DocumentColor>,
 3627    pub cache_version: Option<usize>,
 3628}
 3629
 3630type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3631type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3632
 3633#[derive(Debug, Default)]
 3634struct DocumentColorData {
 3635    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3636    cache_version: usize,
 3637    colors_update: Option<(Global, DocumentColorTask)>,
 3638}
 3639
 3640#[derive(Debug, Default)]
 3641struct CodeLensData {
 3642    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3643    update: Option<(Global, CodeLensTask)>,
 3644}
 3645
 3646#[derive(Debug)]
 3647pub enum LspStoreEvent {
 3648    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3649    LanguageServerRemoved(LanguageServerId),
 3650    LanguageServerUpdate {
 3651        language_server_id: LanguageServerId,
 3652        name: Option<LanguageServerName>,
 3653        message: proto::update_language_server::Variant,
 3654    },
 3655    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3656    LanguageServerPrompt(LanguageServerPromptRequest),
 3657    LanguageDetected {
 3658        buffer: Entity<Buffer>,
 3659        new_language: Option<Arc<Language>>,
 3660    },
 3661    Notification(String),
 3662    RefreshInlayHints(LanguageServerId),
 3663    RefreshCodeLens,
 3664    DiagnosticsUpdated {
 3665        server_id: LanguageServerId,
 3666        paths: Vec<ProjectPath>,
 3667    },
 3668    DiskBasedDiagnosticsStarted {
 3669        language_server_id: LanguageServerId,
 3670    },
 3671    DiskBasedDiagnosticsFinished {
 3672        language_server_id: LanguageServerId,
 3673    },
 3674    SnippetEdit {
 3675        buffer_id: BufferId,
 3676        edits: Vec<(lsp::Range, Snippet)>,
 3677        most_recent_edit: clock::Lamport,
 3678    },
 3679}
 3680
 3681#[derive(Clone, Debug, Serialize)]
 3682pub struct LanguageServerStatus {
 3683    pub name: LanguageServerName,
 3684    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 3685    pub has_pending_diagnostic_updates: bool,
 3686    progress_tokens: HashSet<ProgressToken>,
 3687    pub worktree: Option<WorktreeId>,
 3688}
 3689
 3690#[derive(Clone, Debug)]
 3691struct CoreSymbol {
 3692    pub language_server_name: LanguageServerName,
 3693    pub source_worktree_id: WorktreeId,
 3694    pub source_language_server_id: LanguageServerId,
 3695    pub path: SymbolLocation,
 3696    pub name: String,
 3697    pub kind: lsp::SymbolKind,
 3698    pub range: Range<Unclipped<PointUtf16>>,
 3699}
 3700
 3701#[derive(Clone, Debug, PartialEq, Eq)]
 3702pub enum SymbolLocation {
 3703    InProject(ProjectPath),
 3704    OutsideProject {
 3705        abs_path: Arc<Path>,
 3706        signature: [u8; 32],
 3707    },
 3708}
 3709
 3710impl SymbolLocation {
 3711    fn file_name(&self) -> Option<&str> {
 3712        match self {
 3713            Self::InProject(path) => path.path.file_name(),
 3714            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3715        }
 3716    }
 3717}
 3718
 3719impl LspStore {
 3720    pub fn init(client: &AnyProtoClient) {
 3721        client.add_entity_request_handler(Self::handle_lsp_query);
 3722        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3723        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3724        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3725        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3726        client.add_entity_message_handler(Self::handle_start_language_server);
 3727        client.add_entity_message_handler(Self::handle_update_language_server);
 3728        client.add_entity_message_handler(Self::handle_language_server_log);
 3729        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3730        client.add_entity_request_handler(Self::handle_format_buffers);
 3731        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3732        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3733        client.add_entity_request_handler(Self::handle_apply_code_action);
 3734        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3735        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3736        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3737        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3738        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3739        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3740        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3741        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3742        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3743        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3744        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3745        client.add_entity_request_handler(Self::handle_lsp_command::<GetCompletions>);
 3746        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3747        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3748        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3749        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3750        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3751
 3752        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3753        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3754        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3755        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3756        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3757        client.add_entity_request_handler(
 3758            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3759        );
 3760        client.add_entity_request_handler(
 3761            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3762        );
 3763        client.add_entity_request_handler(
 3764            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3765        );
 3766    }
 3767
 3768    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3769        match &self.mode {
 3770            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3771            _ => None,
 3772        }
 3773    }
 3774
 3775    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3776        match &self.mode {
 3777            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3778            _ => None,
 3779        }
 3780    }
 3781
 3782    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3783        match &mut self.mode {
 3784            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3785            _ => None,
 3786        }
 3787    }
 3788
 3789    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3790        match &self.mode {
 3791            LspStoreMode::Remote(RemoteLspStore {
 3792                upstream_client: Some(upstream_client),
 3793                upstream_project_id,
 3794                ..
 3795            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3796
 3797            LspStoreMode::Remote(RemoteLspStore {
 3798                upstream_client: None,
 3799                ..
 3800            }) => None,
 3801            LspStoreMode::Local(_) => None,
 3802        }
 3803    }
 3804
 3805    pub fn new_local(
 3806        buffer_store: Entity<BufferStore>,
 3807        worktree_store: Entity<WorktreeStore>,
 3808        prettier_store: Entity<PrettierStore>,
 3809        toolchain_store: Entity<LocalToolchainStore>,
 3810        environment: Entity<ProjectEnvironment>,
 3811        manifest_tree: Entity<ManifestTree>,
 3812        languages: Arc<LanguageRegistry>,
 3813        http_client: Arc<dyn HttpClient>,
 3814        fs: Arc<dyn Fs>,
 3815        cx: &mut Context<Self>,
 3816    ) -> Self {
 3817        let yarn = YarnPathStore::new(fs.clone(), cx);
 3818        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3819            .detach();
 3820        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3821            .detach();
 3822        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 3823            .detach();
 3824        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 3825            .detach();
 3826        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 3827            .detach();
 3828        subscribe_to_binary_statuses(&languages, cx).detach();
 3829
 3830        let _maintain_workspace_config = {
 3831            let (sender, receiver) = watch::channel();
 3832            (Self::maintain_workspace_config(receiver, cx), sender)
 3833        };
 3834
 3835        Self {
 3836            mode: LspStoreMode::Local(LocalLspStore {
 3837                weak: cx.weak_entity(),
 3838                worktree_store: worktree_store.clone(),
 3839
 3840                supplementary_language_servers: Default::default(),
 3841                languages: languages.clone(),
 3842                language_server_ids: Default::default(),
 3843                language_servers: Default::default(),
 3844                last_workspace_edits_by_language_server: Default::default(),
 3845                language_server_watched_paths: Default::default(),
 3846                language_server_paths_watched_for_rename: Default::default(),
 3847                language_server_dynamic_registrations: Default::default(),
 3848                buffers_being_formatted: Default::default(),
 3849                buffer_snapshots: Default::default(),
 3850                prettier_store,
 3851                environment,
 3852                http_client,
 3853                fs,
 3854                yarn,
 3855                next_diagnostic_group_id: Default::default(),
 3856                diagnostics: Default::default(),
 3857                _subscription: cx.on_app_quit(|this, cx| {
 3858                    this.as_local_mut()
 3859                        .unwrap()
 3860                        .shutdown_language_servers_on_quit(cx)
 3861                }),
 3862                lsp_tree: LanguageServerTree::new(
 3863                    manifest_tree,
 3864                    languages.clone(),
 3865                    toolchain_store.clone(),
 3866                ),
 3867                toolchain_store,
 3868                registered_buffers: HashMap::default(),
 3869                buffers_opened_in_servers: HashMap::default(),
 3870                buffer_pull_diagnostics_result_ids: HashMap::default(),
 3871                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 3872                    .manifest_file_names(),
 3873            }),
 3874            last_formatting_failure: None,
 3875            downstream_client: None,
 3876            buffer_store,
 3877            worktree_store,
 3878            languages: languages.clone(),
 3879            language_server_statuses: Default::default(),
 3880            nonce: StdRng::from_os_rng().random(),
 3881            diagnostic_summaries: HashMap::default(),
 3882            lsp_server_capabilities: HashMap::default(),
 3883            lsp_data: HashMap::default(),
 3884            next_hint_id: Arc::default(),
 3885            active_entry: None,
 3886            _maintain_workspace_config,
 3887            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 3888        }
 3889    }
 3890
 3891    fn send_lsp_proto_request<R: LspCommand>(
 3892        &self,
 3893        buffer: Entity<Buffer>,
 3894        client: AnyProtoClient,
 3895        upstream_project_id: u64,
 3896        request: R,
 3897        cx: &mut Context<LspStore>,
 3898    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 3899        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 3900            return Task::ready(Ok(R::Response::default()));
 3901        }
 3902        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 3903        cx.spawn(async move |this, cx| {
 3904            let response = client.request(message).await?;
 3905            let this = this.upgrade().context("project dropped")?;
 3906            request
 3907                .response_from_proto(response, this, buffer, cx.clone())
 3908                .await
 3909        })
 3910    }
 3911
 3912    pub(super) fn new_remote(
 3913        buffer_store: Entity<BufferStore>,
 3914        worktree_store: Entity<WorktreeStore>,
 3915        languages: Arc<LanguageRegistry>,
 3916        upstream_client: AnyProtoClient,
 3917        project_id: u64,
 3918        cx: &mut Context<Self>,
 3919    ) -> Self {
 3920        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3921            .detach();
 3922        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3923            .detach();
 3924        subscribe_to_binary_statuses(&languages, cx).detach();
 3925        let _maintain_workspace_config = {
 3926            let (sender, receiver) = watch::channel();
 3927            (Self::maintain_workspace_config(receiver, cx), sender)
 3928        };
 3929        Self {
 3930            mode: LspStoreMode::Remote(RemoteLspStore {
 3931                upstream_client: Some(upstream_client),
 3932                upstream_project_id: project_id,
 3933            }),
 3934            downstream_client: None,
 3935            last_formatting_failure: None,
 3936            buffer_store,
 3937            worktree_store,
 3938            languages: languages.clone(),
 3939            language_server_statuses: Default::default(),
 3940            nonce: StdRng::from_os_rng().random(),
 3941            diagnostic_summaries: HashMap::default(),
 3942            lsp_server_capabilities: HashMap::default(),
 3943            next_hint_id: Arc::default(),
 3944            lsp_data: HashMap::default(),
 3945            active_entry: None,
 3946
 3947            _maintain_workspace_config,
 3948            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 3949        }
 3950    }
 3951
 3952    fn on_buffer_store_event(
 3953        &mut self,
 3954        _: Entity<BufferStore>,
 3955        event: &BufferStoreEvent,
 3956        cx: &mut Context<Self>,
 3957    ) {
 3958        match event {
 3959            BufferStoreEvent::BufferAdded(buffer) => {
 3960                self.on_buffer_added(buffer, cx).log_err();
 3961            }
 3962            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 3963                let buffer_id = buffer.read(cx).remote_id();
 3964                if let Some(local) = self.as_local_mut()
 3965                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 3966                {
 3967                    local.reset_buffer(buffer, old_file, cx);
 3968
 3969                    if local.registered_buffers.contains_key(&buffer_id) {
 3970                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 3971                    }
 3972                }
 3973
 3974                self.detect_language_for_buffer(buffer, cx);
 3975                if let Some(local) = self.as_local_mut() {
 3976                    local.initialize_buffer(buffer, cx);
 3977                    if local.registered_buffers.contains_key(&buffer_id) {
 3978                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 3979                    }
 3980                }
 3981            }
 3982            _ => {}
 3983        }
 3984    }
 3985
 3986    fn on_worktree_store_event(
 3987        &mut self,
 3988        _: Entity<WorktreeStore>,
 3989        event: &WorktreeStoreEvent,
 3990        cx: &mut Context<Self>,
 3991    ) {
 3992        match event {
 3993            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 3994                if !worktree.read(cx).is_local() {
 3995                    return;
 3996                }
 3997                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 3998                    worktree::Event::UpdatedEntries(changes) => {
 3999                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4000                    }
 4001                    worktree::Event::UpdatedGitRepositories(_)
 4002                    | worktree::Event::DeletedEntry(_) => {}
 4003                })
 4004                .detach()
 4005            }
 4006            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4007            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4008                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4009            }
 4010            WorktreeStoreEvent::WorktreeReleased(..)
 4011            | WorktreeStoreEvent::WorktreeOrderChanged
 4012            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4013            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4014            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4015        }
 4016    }
 4017
 4018    fn on_prettier_store_event(
 4019        &mut self,
 4020        _: Entity<PrettierStore>,
 4021        event: &PrettierStoreEvent,
 4022        cx: &mut Context<Self>,
 4023    ) {
 4024        match event {
 4025            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4026                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4027            }
 4028            PrettierStoreEvent::LanguageServerAdded {
 4029                new_server_id,
 4030                name,
 4031                prettier_server,
 4032            } => {
 4033                self.register_supplementary_language_server(
 4034                    *new_server_id,
 4035                    name.clone(),
 4036                    prettier_server.clone(),
 4037                    cx,
 4038                );
 4039            }
 4040        }
 4041    }
 4042
 4043    fn on_toolchain_store_event(
 4044        &mut self,
 4045        _: Entity<LocalToolchainStore>,
 4046        event: &ToolchainStoreEvent,
 4047        _: &mut Context<Self>,
 4048    ) {
 4049        if let ToolchainStoreEvent::ToolchainActivated = event {
 4050            self.request_workspace_config_refresh()
 4051        }
 4052    }
 4053
 4054    fn request_workspace_config_refresh(&mut self) {
 4055        *self._maintain_workspace_config.1.borrow_mut() = ();
 4056    }
 4057
 4058    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4059        self.as_local().map(|local| local.prettier_store.clone())
 4060    }
 4061
 4062    fn on_buffer_event(
 4063        &mut self,
 4064        buffer: Entity<Buffer>,
 4065        event: &language::BufferEvent,
 4066        cx: &mut Context<Self>,
 4067    ) {
 4068        match event {
 4069            language::BufferEvent::Edited => {
 4070                self.on_buffer_edited(buffer, cx);
 4071            }
 4072
 4073            language::BufferEvent::Saved => {
 4074                self.on_buffer_saved(buffer, cx);
 4075            }
 4076
 4077            _ => {}
 4078        }
 4079    }
 4080
 4081    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4082        buffer
 4083            .read(cx)
 4084            .set_language_registry(self.languages.clone());
 4085
 4086        cx.subscribe(buffer, |this, buffer, event, cx| {
 4087            this.on_buffer_event(buffer, event, cx);
 4088        })
 4089        .detach();
 4090
 4091        self.detect_language_for_buffer(buffer, cx);
 4092        if let Some(local) = self.as_local_mut() {
 4093            local.initialize_buffer(buffer, cx);
 4094        }
 4095
 4096        Ok(())
 4097    }
 4098
 4099    pub(crate) fn register_buffer_with_language_servers(
 4100        &mut self,
 4101        buffer: &Entity<Buffer>,
 4102        only_register_servers: HashSet<LanguageServerSelector>,
 4103        ignore_refcounts: bool,
 4104        cx: &mut Context<Self>,
 4105    ) -> OpenLspBufferHandle {
 4106        let buffer_id = buffer.read(cx).remote_id();
 4107        let handle = cx.new(|_| buffer.clone());
 4108        if let Some(local) = self.as_local_mut() {
 4109            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4110            if !ignore_refcounts {
 4111                *refcount += 1;
 4112            }
 4113
 4114            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4115            // When a new unnamed buffer is created and saved, we will start loading it's language. Once the language is loaded, we go over all "language-less" buffers and try to fit that new language
 4116            // with them. However, we do that only for the buffers that we think are open in at least one editor; thus, we need to keep tab of unnamed buffers as well, even though they're not actually registered with any language
 4117            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4118            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4119                return handle;
 4120            };
 4121            if !file.is_local() {
 4122                return handle;
 4123            }
 4124
 4125            if ignore_refcounts || *refcount == 1 {
 4126                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4127            }
 4128            if !ignore_refcounts {
 4129                cx.observe_release(&handle, move |lsp_store, buffer, cx| {
 4130                    let refcount = {
 4131                        let local = lsp_store.as_local_mut().unwrap();
 4132                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4133                            debug_panic!("bad refcounting");
 4134                            return;
 4135                        };
 4136
 4137                        *refcount -= 1;
 4138                        *refcount
 4139                    };
 4140                    if refcount == 0 {
 4141                        lsp_store.lsp_data.remove(&buffer_id);
 4142                        let local = lsp_store.as_local_mut().unwrap();
 4143                        local.registered_buffers.remove(&buffer_id);
 4144                        local.buffers_opened_in_servers.remove(&buffer_id);
 4145                        if let Some(file) = File::from_dyn(buffer.read(cx).file()).cloned() {
 4146                            local.unregister_old_buffer_from_language_servers(buffer, &file, cx);
 4147                        }
 4148                    }
 4149                })
 4150                .detach();
 4151            }
 4152        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4153            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4154            cx.background_spawn(async move {
 4155                upstream_client
 4156                    .request(proto::RegisterBufferWithLanguageServers {
 4157                        project_id: upstream_project_id,
 4158                        buffer_id,
 4159                        only_servers: only_register_servers
 4160                            .into_iter()
 4161                            .map(|selector| {
 4162                                let selector = match selector {
 4163                                    LanguageServerSelector::Id(language_server_id) => {
 4164                                        proto::language_server_selector::Selector::ServerId(
 4165                                            language_server_id.to_proto(),
 4166                                        )
 4167                                    }
 4168                                    LanguageServerSelector::Name(language_server_name) => {
 4169                                        proto::language_server_selector::Selector::Name(
 4170                                            language_server_name.to_string(),
 4171                                        )
 4172                                    }
 4173                                };
 4174                                proto::LanguageServerSelector {
 4175                                    selector: Some(selector),
 4176                                }
 4177                            })
 4178                            .collect(),
 4179                    })
 4180                    .await
 4181            })
 4182            .detach();
 4183        } else {
 4184            panic!("oops!");
 4185        }
 4186        handle
 4187    }
 4188
 4189    fn maintain_buffer_languages(
 4190        languages: Arc<LanguageRegistry>,
 4191        cx: &mut Context<Self>,
 4192    ) -> Task<()> {
 4193        let mut subscription = languages.subscribe();
 4194        let mut prev_reload_count = languages.reload_count();
 4195        cx.spawn(async move |this, cx| {
 4196            while let Some(()) = subscription.next().await {
 4197                if let Some(this) = this.upgrade() {
 4198                    // If the language registry has been reloaded, then remove and
 4199                    // re-assign the languages on all open buffers.
 4200                    let reload_count = languages.reload_count();
 4201                    if reload_count > prev_reload_count {
 4202                        prev_reload_count = reload_count;
 4203                        this.update(cx, |this, cx| {
 4204                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4205                                for buffer in buffer_store.buffers() {
 4206                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4207                                    {
 4208                                        buffer
 4209                                            .update(cx, |buffer, cx| buffer.set_language(None, cx));
 4210                                        if let Some(local) = this.as_local_mut() {
 4211                                            local.reset_buffer(&buffer, &f, cx);
 4212
 4213                                            if local
 4214                                                .registered_buffers
 4215                                                .contains_key(&buffer.read(cx).remote_id())
 4216                                                && let Some(file_url) =
 4217                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4218                                            {
 4219                                                local.unregister_buffer_from_language_servers(
 4220                                                    &buffer, &file_url, cx,
 4221                                                );
 4222                                            }
 4223                                        }
 4224                                    }
 4225                                }
 4226                            });
 4227                        })
 4228                        .ok();
 4229                    }
 4230
 4231                    this.update(cx, |this, cx| {
 4232                        let mut plain_text_buffers = Vec::new();
 4233                        let mut buffers_with_unknown_injections = Vec::new();
 4234                        for handle in this.buffer_store.read(cx).buffers() {
 4235                            let buffer = handle.read(cx);
 4236                            if buffer.language().is_none()
 4237                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4238                            {
 4239                                plain_text_buffers.push(handle);
 4240                            } else if buffer.contains_unknown_injections() {
 4241                                buffers_with_unknown_injections.push(handle);
 4242                            }
 4243                        }
 4244
 4245                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4246                        // and reused later in the invisible worktrees.
 4247                        plain_text_buffers.sort_by_key(|buffer| {
 4248                            Reverse(
 4249                                File::from_dyn(buffer.read(cx).file())
 4250                                    .map(|file| file.worktree.read(cx).is_visible()),
 4251                            )
 4252                        });
 4253
 4254                        for buffer in plain_text_buffers {
 4255                            this.detect_language_for_buffer(&buffer, cx);
 4256                            if let Some(local) = this.as_local_mut() {
 4257                                local.initialize_buffer(&buffer, cx);
 4258                                if local
 4259                                    .registered_buffers
 4260                                    .contains_key(&buffer.read(cx).remote_id())
 4261                                {
 4262                                    local.register_buffer_with_language_servers(
 4263                                        &buffer,
 4264                                        HashSet::default(),
 4265                                        cx,
 4266                                    );
 4267                                }
 4268                            }
 4269                        }
 4270
 4271                        for buffer in buffers_with_unknown_injections {
 4272                            buffer.update(cx, |buffer, cx| buffer.reparse(cx));
 4273                        }
 4274                    })
 4275                    .ok();
 4276                }
 4277            }
 4278        })
 4279    }
 4280
 4281    fn detect_language_for_buffer(
 4282        &mut self,
 4283        buffer_handle: &Entity<Buffer>,
 4284        cx: &mut Context<Self>,
 4285    ) -> Option<language::AvailableLanguage> {
 4286        // If the buffer has a language, set it and start the language server if we haven't already.
 4287        let buffer = buffer_handle.read(cx);
 4288        let file = buffer.file()?;
 4289
 4290        let content = buffer.as_rope();
 4291        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4292        if let Some(available_language) = &available_language {
 4293            if let Some(Ok(Ok(new_language))) = self
 4294                .languages
 4295                .load_language(available_language)
 4296                .now_or_never()
 4297            {
 4298                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4299            }
 4300        } else {
 4301            cx.emit(LspStoreEvent::LanguageDetected {
 4302                buffer: buffer_handle.clone(),
 4303                new_language: None,
 4304            });
 4305        }
 4306
 4307        available_language
 4308    }
 4309
 4310    pub(crate) fn set_language_for_buffer(
 4311        &mut self,
 4312        buffer_entity: &Entity<Buffer>,
 4313        new_language: Arc<Language>,
 4314        cx: &mut Context<Self>,
 4315    ) {
 4316        let buffer = buffer_entity.read(cx);
 4317        let buffer_file = buffer.file().cloned();
 4318        let buffer_id = buffer.remote_id();
 4319        if let Some(local_store) = self.as_local_mut()
 4320            && local_store.registered_buffers.contains_key(&buffer_id)
 4321            && let Some(abs_path) =
 4322                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4323            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4324        {
 4325            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4326        }
 4327        buffer_entity.update(cx, |buffer, cx| {
 4328            if buffer
 4329                .language()
 4330                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4331            {
 4332                buffer.set_language(Some(new_language.clone()), cx);
 4333            }
 4334        });
 4335
 4336        let settings =
 4337            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4338        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4339
 4340        let worktree_id = if let Some(file) = buffer_file {
 4341            let worktree = file.worktree.clone();
 4342
 4343            if let Some(local) = self.as_local_mut()
 4344                && local.registered_buffers.contains_key(&buffer_id)
 4345            {
 4346                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4347            }
 4348            Some(worktree.read(cx).id())
 4349        } else {
 4350            None
 4351        };
 4352
 4353        if settings.prettier.allowed
 4354            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4355        {
 4356            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4357            if let Some(prettier_store) = prettier_store {
 4358                prettier_store.update(cx, |prettier_store, cx| {
 4359                    prettier_store.install_default_prettier(
 4360                        worktree_id,
 4361                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4362                        cx,
 4363                    )
 4364                })
 4365            }
 4366        }
 4367
 4368        cx.emit(LspStoreEvent::LanguageDetected {
 4369            buffer: buffer_entity.clone(),
 4370            new_language: Some(new_language),
 4371        })
 4372    }
 4373
 4374    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4375        self.buffer_store.clone()
 4376    }
 4377
 4378    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4379        self.active_entry = active_entry;
 4380    }
 4381
 4382    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4383        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4384            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4385        {
 4386            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4387                summaries
 4388                    .iter()
 4389                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4390            });
 4391            if let Some(summary) = summaries.next() {
 4392                client
 4393                    .send(proto::UpdateDiagnosticSummary {
 4394                        project_id: downstream_project_id,
 4395                        worktree_id: worktree.id().to_proto(),
 4396                        summary: Some(summary),
 4397                        more_summaries: summaries.collect(),
 4398                    })
 4399                    .log_err();
 4400            }
 4401        }
 4402    }
 4403
 4404    fn is_capable_for_proto_request<R>(
 4405        &self,
 4406        buffer: &Entity<Buffer>,
 4407        request: &R,
 4408        cx: &App,
 4409    ) -> bool
 4410    where
 4411        R: LspCommand,
 4412    {
 4413        self.check_if_capable_for_proto_request(
 4414            buffer,
 4415            |capabilities| {
 4416                request.check_capabilities(AdapterServerCapabilities {
 4417                    server_capabilities: capabilities.clone(),
 4418                    code_action_kinds: None,
 4419                })
 4420            },
 4421            cx,
 4422        )
 4423    }
 4424
 4425    fn check_if_capable_for_proto_request<F>(
 4426        &self,
 4427        buffer: &Entity<Buffer>,
 4428        check: F,
 4429        cx: &App,
 4430    ) -> bool
 4431    where
 4432        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4433    {
 4434        let Some(language) = buffer.read(cx).language().cloned() else {
 4435            return false;
 4436        };
 4437        let relevant_language_servers = self
 4438            .languages
 4439            .lsp_adapters(&language.name())
 4440            .into_iter()
 4441            .map(|lsp_adapter| lsp_adapter.name())
 4442            .collect::<HashSet<_>>();
 4443        self.language_server_statuses
 4444            .iter()
 4445            .filter_map(|(server_id, server_status)| {
 4446                relevant_language_servers
 4447                    .contains(&server_status.name)
 4448                    .then_some(server_id)
 4449            })
 4450            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4451            .any(check)
 4452    }
 4453
 4454    pub fn request_lsp<R>(
 4455        &mut self,
 4456        buffer: Entity<Buffer>,
 4457        server: LanguageServerToQuery,
 4458        request: R,
 4459        cx: &mut Context<Self>,
 4460    ) -> Task<Result<R::Response>>
 4461    where
 4462        R: LspCommand,
 4463        <R::LspRequest as lsp::request::Request>::Result: Send,
 4464        <R::LspRequest as lsp::request::Request>::Params: Send,
 4465    {
 4466        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4467            return self.send_lsp_proto_request(
 4468                buffer,
 4469                upstream_client,
 4470                upstream_project_id,
 4471                request,
 4472                cx,
 4473            );
 4474        }
 4475
 4476        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4477            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4478                local
 4479                    .language_servers_for_buffer(buffer, cx)
 4480                    .find(|(_, server)| {
 4481                        request.check_capabilities(server.adapter_server_capabilities())
 4482                    })
 4483                    .map(|(_, server)| server.clone())
 4484            }),
 4485            LanguageServerToQuery::Other(id) => self
 4486                .language_server_for_local_buffer(buffer, id, cx)
 4487                .and_then(|(_, server)| {
 4488                    request
 4489                        .check_capabilities(server.adapter_server_capabilities())
 4490                        .then(|| Arc::clone(server))
 4491                }),
 4492        }) else {
 4493            return Task::ready(Ok(Default::default()));
 4494        };
 4495
 4496        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4497
 4498        let Some(file) = file else {
 4499            return Task::ready(Ok(Default::default()));
 4500        };
 4501
 4502        let lsp_params = match request.to_lsp_params_or_response(
 4503            &file.abs_path(cx),
 4504            buffer.read(cx),
 4505            &language_server,
 4506            cx,
 4507        ) {
 4508            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4509            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4510
 4511            Err(err) => {
 4512                let message = format!(
 4513                    "{} via {} failed: {}",
 4514                    request.display_name(),
 4515                    language_server.name(),
 4516                    err
 4517                );
 4518                log::warn!("{message}");
 4519                return Task::ready(Err(anyhow!(message)));
 4520            }
 4521        };
 4522
 4523        let status = request.status();
 4524        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4525            return Task::ready(Ok(Default::default()));
 4526        }
 4527        cx.spawn(async move |this, cx| {
 4528            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4529
 4530            let id = lsp_request.id();
 4531            let _cleanup = if status.is_some() {
 4532                cx.update(|cx| {
 4533                    this.update(cx, |this, cx| {
 4534                        this.on_lsp_work_start(
 4535                            language_server.server_id(),
 4536                            ProgressToken::Number(id),
 4537                            LanguageServerProgress {
 4538                                is_disk_based_diagnostics_progress: false,
 4539                                is_cancellable: false,
 4540                                title: None,
 4541                                message: status.clone(),
 4542                                percentage: None,
 4543                                last_update_at: cx.background_executor().now(),
 4544                            },
 4545                            cx,
 4546                        );
 4547                    })
 4548                })
 4549                .log_err();
 4550
 4551                Some(defer(|| {
 4552                    cx.update(|cx| {
 4553                        this.update(cx, |this, cx| {
 4554                            this.on_lsp_work_end(
 4555                                language_server.server_id(),
 4556                                ProgressToken::Number(id),
 4557                                cx,
 4558                            );
 4559                        })
 4560                    })
 4561                    .log_err();
 4562                }))
 4563            } else {
 4564                None
 4565            };
 4566
 4567            let result = lsp_request.await.into_response();
 4568
 4569            let response = result.map_err(|err| {
 4570                let message = format!(
 4571                    "{} via {} failed: {}",
 4572                    request.display_name(),
 4573                    language_server.name(),
 4574                    err
 4575                );
 4576                log::warn!("{message}");
 4577                anyhow::anyhow!(message)
 4578            })?;
 4579
 4580            request
 4581                .response_from_lsp(
 4582                    response,
 4583                    this.upgrade().context("no app context")?,
 4584                    buffer,
 4585                    language_server.server_id(),
 4586                    cx.clone(),
 4587                )
 4588                .await
 4589        })
 4590    }
 4591
 4592    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4593        let mut language_formatters_to_check = Vec::new();
 4594        for buffer in self.buffer_store.read(cx).buffers() {
 4595            let buffer = buffer.read(cx);
 4596            let buffer_file = File::from_dyn(buffer.file());
 4597            let buffer_language = buffer.language();
 4598            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4599            if buffer_language.is_some() {
 4600                language_formatters_to_check.push((
 4601                    buffer_file.map(|f| f.worktree_id(cx)),
 4602                    settings.into_owned(),
 4603                ));
 4604            }
 4605        }
 4606
 4607        self.request_workspace_config_refresh();
 4608
 4609        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4610            prettier_store.update(cx, |prettier_store, cx| {
 4611                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4612            })
 4613        }
 4614
 4615        cx.notify();
 4616    }
 4617
 4618    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4619        let buffer_store = self.buffer_store.clone();
 4620        let Some(local) = self.as_local_mut() else {
 4621            return;
 4622        };
 4623        let mut adapters = BTreeMap::default();
 4624        let get_adapter = {
 4625            let languages = local.languages.clone();
 4626            let environment = local.environment.clone();
 4627            let weak = local.weak.clone();
 4628            let worktree_store = local.worktree_store.clone();
 4629            let http_client = local.http_client.clone();
 4630            let fs = local.fs.clone();
 4631            move |worktree_id, cx: &mut App| {
 4632                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4633                Some(LocalLspAdapterDelegate::new(
 4634                    languages.clone(),
 4635                    &environment,
 4636                    weak.clone(),
 4637                    &worktree,
 4638                    http_client.clone(),
 4639                    fs.clone(),
 4640                    cx,
 4641                ))
 4642            }
 4643        };
 4644
 4645        let mut messages_to_report = Vec::new();
 4646        let (new_tree, to_stop) = {
 4647            let mut rebase = local.lsp_tree.rebase();
 4648            let buffers = buffer_store
 4649                .read(cx)
 4650                .buffers()
 4651                .filter_map(|buffer| {
 4652                    let raw_buffer = buffer.read(cx);
 4653                    if !local
 4654                        .registered_buffers
 4655                        .contains_key(&raw_buffer.remote_id())
 4656                    {
 4657                        return None;
 4658                    }
 4659                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4660                    let language = raw_buffer.language().cloned()?;
 4661                    Some((file, language, raw_buffer.remote_id()))
 4662                })
 4663                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4664            for (file, language, buffer_id) in buffers {
 4665                let worktree_id = file.worktree_id(cx);
 4666                let Some(worktree) = local
 4667                    .worktree_store
 4668                    .read(cx)
 4669                    .worktree_for_id(worktree_id, cx)
 4670                else {
 4671                    continue;
 4672                };
 4673
 4674                if let Some((_, apply)) = local.reuse_existing_language_server(
 4675                    rebase.server_tree(),
 4676                    &worktree,
 4677                    &language.name(),
 4678                    cx,
 4679                ) {
 4680                    (apply)(rebase.server_tree());
 4681                } else if let Some(lsp_delegate) = adapters
 4682                    .entry(worktree_id)
 4683                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4684                    .clone()
 4685                {
 4686                    let delegate =
 4687                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4688                    let path = file
 4689                        .path()
 4690                        .parent()
 4691                        .map(Arc::from)
 4692                        .unwrap_or_else(|| file.path().clone());
 4693                    let worktree_path = ProjectPath { worktree_id, path };
 4694                    let abs_path = file.abs_path(cx);
 4695                    let nodes = rebase
 4696                        .walk(
 4697                            worktree_path,
 4698                            language.name(),
 4699                            language.manifest(),
 4700                            delegate.clone(),
 4701                            cx,
 4702                        )
 4703                        .collect::<Vec<_>>();
 4704                    for node in nodes {
 4705                        let server_id = node.server_id_or_init(|disposition| {
 4706                            let path = &disposition.path;
 4707                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 4708                            let key = LanguageServerSeed {
 4709                                worktree_id,
 4710                                name: disposition.server_name.clone(),
 4711                                settings: disposition.settings.clone(),
 4712                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4713                                    path.worktree_id,
 4714                                    &path.path,
 4715                                    language.name(),
 4716                                ),
 4717                            };
 4718                            local.language_server_ids.remove(&key);
 4719
 4720                            let server_id = local.get_or_insert_language_server(
 4721                                &worktree,
 4722                                lsp_delegate.clone(),
 4723                                disposition,
 4724                                &language.name(),
 4725                                cx,
 4726                            );
 4727                            if let Some(state) = local.language_servers.get(&server_id)
 4728                                && let Ok(uri) = uri
 4729                            {
 4730                                state.add_workspace_folder(uri);
 4731                            };
 4732                            server_id
 4733                        });
 4734
 4735                        if let Some(language_server_id) = server_id {
 4736                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 4737                                language_server_id,
 4738                                name: node.name(),
 4739                                message:
 4740                                    proto::update_language_server::Variant::RegisteredForBuffer(
 4741                                        proto::RegisteredForBuffer {
 4742                                            buffer_abs_path: abs_path
 4743                                                .to_string_lossy()
 4744                                                .into_owned(),
 4745                                            buffer_id: buffer_id.to_proto(),
 4746                                        },
 4747                                    ),
 4748                            });
 4749                        }
 4750                    }
 4751                } else {
 4752                    continue;
 4753                }
 4754            }
 4755            rebase.finish()
 4756        };
 4757        for message in messages_to_report {
 4758            cx.emit(message);
 4759        }
 4760        local.lsp_tree = new_tree;
 4761        for (id, _) in to_stop {
 4762            self.stop_local_language_server(id, cx).detach();
 4763        }
 4764    }
 4765
 4766    pub fn apply_code_action(
 4767        &self,
 4768        buffer_handle: Entity<Buffer>,
 4769        mut action: CodeAction,
 4770        push_to_history: bool,
 4771        cx: &mut Context<Self>,
 4772    ) -> Task<Result<ProjectTransaction>> {
 4773        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4774            let request = proto::ApplyCodeAction {
 4775                project_id,
 4776                buffer_id: buffer_handle.read(cx).remote_id().into(),
 4777                action: Some(Self::serialize_code_action(&action)),
 4778            };
 4779            let buffer_store = self.buffer_store();
 4780            cx.spawn(async move |_, cx| {
 4781                let response = upstream_client
 4782                    .request(request)
 4783                    .await?
 4784                    .transaction
 4785                    .context("missing transaction")?;
 4786
 4787                buffer_store
 4788                    .update(cx, |buffer_store, cx| {
 4789                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 4790                    })?
 4791                    .await
 4792            })
 4793        } else if self.mode.is_local() {
 4794            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 4795                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 4796                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 4797            }) else {
 4798                return Task::ready(Ok(ProjectTransaction::default()));
 4799            };
 4800            cx.spawn(async move |this,  cx| {
 4801                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 4802                    .await
 4803                    .context("resolving a code action")?;
 4804                if let Some(edit) = action.lsp_action.edit()
 4805                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 4806                        return LocalLspStore::deserialize_workspace_edit(
 4807                            this.upgrade().context("no app present")?,
 4808                            edit.clone(),
 4809                            push_to_history,
 4810
 4811                            lang_server.clone(),
 4812                            cx,
 4813                        )
 4814                        .await;
 4815                    }
 4816
 4817                if let Some(command) = action.lsp_action.command() {
 4818                    let server_capabilities = lang_server.capabilities();
 4819                    let available_commands = server_capabilities
 4820                        .execute_command_provider
 4821                        .as_ref()
 4822                        .map(|options| options.commands.as_slice())
 4823                        .unwrap_or_default();
 4824                    if available_commands.contains(&command.command) {
 4825                        this.update(cx, |this, _| {
 4826                            this.as_local_mut()
 4827                                .unwrap()
 4828                                .last_workspace_edits_by_language_server
 4829                                .remove(&lang_server.server_id());
 4830                        })?;
 4831
 4832                        let _result = lang_server
 4833                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 4834                                command: command.command.clone(),
 4835                                arguments: command.arguments.clone().unwrap_or_default(),
 4836                                ..lsp::ExecuteCommandParams::default()
 4837                            })
 4838                            .await.into_response()
 4839                            .context("execute command")?;
 4840
 4841                        return this.update(cx, |this, _| {
 4842                            this.as_local_mut()
 4843                                .unwrap()
 4844                                .last_workspace_edits_by_language_server
 4845                                .remove(&lang_server.server_id())
 4846                                .unwrap_or_default()
 4847                        });
 4848                    } else {
 4849                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 4850                    }
 4851                }
 4852
 4853                Ok(ProjectTransaction::default())
 4854            })
 4855        } else {
 4856            Task::ready(Err(anyhow!("no upstream client and not local")))
 4857        }
 4858    }
 4859
 4860    pub fn apply_code_action_kind(
 4861        &mut self,
 4862        buffers: HashSet<Entity<Buffer>>,
 4863        kind: CodeActionKind,
 4864        push_to_history: bool,
 4865        cx: &mut Context<Self>,
 4866    ) -> Task<anyhow::Result<ProjectTransaction>> {
 4867        if self.as_local().is_some() {
 4868            cx.spawn(async move |lsp_store, cx| {
 4869                let buffers = buffers.into_iter().collect::<Vec<_>>();
 4870                let result = LocalLspStore::execute_code_action_kind_locally(
 4871                    lsp_store.clone(),
 4872                    buffers,
 4873                    kind,
 4874                    push_to_history,
 4875                    cx,
 4876                )
 4877                .await;
 4878                lsp_store.update(cx, |lsp_store, _| {
 4879                    lsp_store.update_last_formatting_failure(&result);
 4880                })?;
 4881                result
 4882            })
 4883        } else if let Some((client, project_id)) = self.upstream_client() {
 4884            let buffer_store = self.buffer_store();
 4885            cx.spawn(async move |lsp_store, cx| {
 4886                let result = client
 4887                    .request(proto::ApplyCodeActionKind {
 4888                        project_id,
 4889                        kind: kind.as_str().to_owned(),
 4890                        buffer_ids: buffers
 4891                            .iter()
 4892                            .map(|buffer| {
 4893                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 4894                            })
 4895                            .collect::<Result<_>>()?,
 4896                    })
 4897                    .await
 4898                    .and_then(|result| result.transaction.context("missing transaction"));
 4899                lsp_store.update(cx, |lsp_store, _| {
 4900                    lsp_store.update_last_formatting_failure(&result);
 4901                })?;
 4902
 4903                let transaction_response = result?;
 4904                buffer_store
 4905                    .update(cx, |buffer_store, cx| {
 4906                        buffer_store.deserialize_project_transaction(
 4907                            transaction_response,
 4908                            push_to_history,
 4909                            cx,
 4910                        )
 4911                    })?
 4912                    .await
 4913            })
 4914        } else {
 4915            Task::ready(Ok(ProjectTransaction::default()))
 4916        }
 4917    }
 4918
 4919    pub fn resolved_hint(
 4920        &mut self,
 4921        buffer_id: BufferId,
 4922        id: InlayId,
 4923        cx: &mut Context<Self>,
 4924    ) -> Option<ResolvedHint> {
 4925        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 4926
 4927        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 4928        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 4929        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 4930        let (server_id, resolve_data) = match &hint.resolve_state {
 4931            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 4932            ResolveState::Resolving => {
 4933                return Some(ResolvedHint::Resolving(
 4934                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 4935                ));
 4936            }
 4937            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 4938        };
 4939
 4940        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 4941        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 4942        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 4943            id,
 4944            cx.spawn(async move |lsp_store, cx| {
 4945                let resolved_hint = resolve_task.await;
 4946                lsp_store
 4947                    .update(cx, |lsp_store, _| {
 4948                        if let Some(old_inlay_hint) = lsp_store
 4949                            .lsp_data
 4950                            .get_mut(&buffer_id)
 4951                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 4952                        {
 4953                            match resolved_hint {
 4954                                Ok(resolved_hint) => {
 4955                                    *old_inlay_hint = resolved_hint;
 4956                                }
 4957                                Err(e) => {
 4958                                    old_inlay_hint.resolve_state =
 4959                                        ResolveState::CanResolve(server_id, resolve_data);
 4960                                    log::error!("Inlay hint resolve failed: {e:#}");
 4961                                }
 4962                            }
 4963                        }
 4964                    })
 4965                    .ok();
 4966            })
 4967            .shared(),
 4968        );
 4969        debug_assert!(
 4970            previous_task.is_none(),
 4971            "Did not change hint's resolve state after spawning its resolve"
 4972        );
 4973        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 4974        None
 4975    }
 4976
 4977    fn resolve_inlay_hint(
 4978        &self,
 4979        mut hint: InlayHint,
 4980        buffer: Entity<Buffer>,
 4981        server_id: LanguageServerId,
 4982        cx: &mut Context<Self>,
 4983    ) -> Task<anyhow::Result<InlayHint>> {
 4984        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4985            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 4986            {
 4987                hint.resolve_state = ResolveState::Resolved;
 4988                return Task::ready(Ok(hint));
 4989            }
 4990            let request = proto::ResolveInlayHint {
 4991                project_id,
 4992                buffer_id: buffer.read(cx).remote_id().into(),
 4993                language_server_id: server_id.0 as u64,
 4994                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 4995            };
 4996            cx.background_spawn(async move {
 4997                let response = upstream_client
 4998                    .request(request)
 4999                    .await
 5000                    .context("inlay hints proto request")?;
 5001                match response.hint {
 5002                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5003                        .context("inlay hints proto resolve response conversion"),
 5004                    None => Ok(hint),
 5005                }
 5006            })
 5007        } else {
 5008            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5009                self.language_server_for_local_buffer(buffer, server_id, cx)
 5010                    .map(|(_, server)| server.clone())
 5011            }) else {
 5012                return Task::ready(Ok(hint));
 5013            };
 5014            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5015                return Task::ready(Ok(hint));
 5016            }
 5017            let buffer_snapshot = buffer.read(cx).snapshot();
 5018            cx.spawn(async move |_, cx| {
 5019                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5020                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5021                );
 5022                let resolved_hint = resolve_task
 5023                    .await
 5024                    .into_response()
 5025                    .context("inlay hint resolve LSP request")?;
 5026                let resolved_hint = InlayHints::lsp_to_project_hint(
 5027                    resolved_hint,
 5028                    &buffer,
 5029                    server_id,
 5030                    ResolveState::Resolved,
 5031                    false,
 5032                    cx,
 5033                )
 5034                .await?;
 5035                Ok(resolved_hint)
 5036            })
 5037        }
 5038    }
 5039
 5040    pub fn resolve_color_presentation(
 5041        &mut self,
 5042        mut color: DocumentColor,
 5043        buffer: Entity<Buffer>,
 5044        server_id: LanguageServerId,
 5045        cx: &mut Context<Self>,
 5046    ) -> Task<Result<DocumentColor>> {
 5047        if color.resolved {
 5048            return Task::ready(Ok(color));
 5049        }
 5050
 5051        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5052            let start = color.lsp_range.start;
 5053            let end = color.lsp_range.end;
 5054            let request = proto::GetColorPresentation {
 5055                project_id,
 5056                server_id: server_id.to_proto(),
 5057                buffer_id: buffer.read(cx).remote_id().into(),
 5058                color: Some(proto::ColorInformation {
 5059                    red: color.color.red,
 5060                    green: color.color.green,
 5061                    blue: color.color.blue,
 5062                    alpha: color.color.alpha,
 5063                    lsp_range_start: Some(proto::PointUtf16 {
 5064                        row: start.line,
 5065                        column: start.character,
 5066                    }),
 5067                    lsp_range_end: Some(proto::PointUtf16 {
 5068                        row: end.line,
 5069                        column: end.character,
 5070                    }),
 5071                }),
 5072            };
 5073            cx.background_spawn(async move {
 5074                let response = upstream_client
 5075                    .request(request)
 5076                    .await
 5077                    .context("color presentation proto request")?;
 5078                color.resolved = true;
 5079                color.color_presentations = response
 5080                    .presentations
 5081                    .into_iter()
 5082                    .map(|presentation| ColorPresentation {
 5083                        label: SharedString::from(presentation.label),
 5084                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5085                        additional_text_edits: presentation
 5086                            .additional_text_edits
 5087                            .into_iter()
 5088                            .filter_map(deserialize_lsp_edit)
 5089                            .collect(),
 5090                    })
 5091                    .collect();
 5092                Ok(color)
 5093            })
 5094        } else {
 5095            let path = match buffer
 5096                .update(cx, |buffer, cx| {
 5097                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5098                })
 5099                .context("buffer with the missing path")
 5100            {
 5101                Ok(path) => path,
 5102                Err(e) => return Task::ready(Err(e)),
 5103            };
 5104            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5105                self.language_server_for_local_buffer(buffer, server_id, cx)
 5106                    .map(|(_, server)| server.clone())
 5107            }) else {
 5108                return Task::ready(Ok(color));
 5109            };
 5110            cx.background_spawn(async move {
 5111                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5112                    lsp::ColorPresentationParams {
 5113                        text_document: make_text_document_identifier(&path)?,
 5114                        color: color.color,
 5115                        range: color.lsp_range,
 5116                        work_done_progress_params: Default::default(),
 5117                        partial_result_params: Default::default(),
 5118                    },
 5119                );
 5120                color.color_presentations = resolve_task
 5121                    .await
 5122                    .into_response()
 5123                    .context("color presentation resolve LSP request")?
 5124                    .into_iter()
 5125                    .map(|presentation| ColorPresentation {
 5126                        label: SharedString::from(presentation.label),
 5127                        text_edit: presentation.text_edit,
 5128                        additional_text_edits: presentation
 5129                            .additional_text_edits
 5130                            .unwrap_or_default(),
 5131                    })
 5132                    .collect();
 5133                color.resolved = true;
 5134                Ok(color)
 5135            })
 5136        }
 5137    }
 5138
 5139    pub(crate) fn linked_edits(
 5140        &mut self,
 5141        buffer: &Entity<Buffer>,
 5142        position: Anchor,
 5143        cx: &mut Context<Self>,
 5144    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5145        let snapshot = buffer.read(cx).snapshot();
 5146        let scope = snapshot.language_scope_at(position);
 5147        let Some(server_id) = self
 5148            .as_local()
 5149            .and_then(|local| {
 5150                buffer.update(cx, |buffer, cx| {
 5151                    local
 5152                        .language_servers_for_buffer(buffer, cx)
 5153                        .filter(|(_, server)| {
 5154                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5155                        })
 5156                        .filter(|(adapter, _)| {
 5157                            scope
 5158                                .as_ref()
 5159                                .map(|scope| scope.language_allowed(&adapter.name))
 5160                                .unwrap_or(true)
 5161                        })
 5162                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5163                        .next()
 5164                })
 5165            })
 5166            .or_else(|| {
 5167                self.upstream_client()
 5168                    .is_some()
 5169                    .then_some(LanguageServerToQuery::FirstCapable)
 5170            })
 5171            .filter(|_| {
 5172                maybe!({
 5173                    let language = buffer.read(cx).language_at(position)?;
 5174                    Some(
 5175                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5176                            .linked_edits,
 5177                    )
 5178                }) == Some(true)
 5179            })
 5180        else {
 5181            return Task::ready(Ok(Vec::new()));
 5182        };
 5183
 5184        self.request_lsp(
 5185            buffer.clone(),
 5186            server_id,
 5187            LinkedEditingRange { position },
 5188            cx,
 5189        )
 5190    }
 5191
 5192    fn apply_on_type_formatting(
 5193        &mut self,
 5194        buffer: Entity<Buffer>,
 5195        position: Anchor,
 5196        trigger: String,
 5197        cx: &mut Context<Self>,
 5198    ) -> Task<Result<Option<Transaction>>> {
 5199        if let Some((client, project_id)) = self.upstream_client() {
 5200            if !self.check_if_capable_for_proto_request(
 5201                &buffer,
 5202                |capabilities| {
 5203                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5204                },
 5205                cx,
 5206            ) {
 5207                return Task::ready(Ok(None));
 5208            }
 5209            let request = proto::OnTypeFormatting {
 5210                project_id,
 5211                buffer_id: buffer.read(cx).remote_id().into(),
 5212                position: Some(serialize_anchor(&position)),
 5213                trigger,
 5214                version: serialize_version(&buffer.read(cx).version()),
 5215            };
 5216            cx.background_spawn(async move {
 5217                client
 5218                    .request(request)
 5219                    .await?
 5220                    .transaction
 5221                    .map(language::proto::deserialize_transaction)
 5222                    .transpose()
 5223            })
 5224        } else if let Some(local) = self.as_local_mut() {
 5225            let buffer_id = buffer.read(cx).remote_id();
 5226            local.buffers_being_formatted.insert(buffer_id);
 5227            cx.spawn(async move |this, cx| {
 5228                let _cleanup = defer({
 5229                    let this = this.clone();
 5230                    let mut cx = cx.clone();
 5231                    move || {
 5232                        this.update(&mut cx, |this, _| {
 5233                            if let Some(local) = this.as_local_mut() {
 5234                                local.buffers_being_formatted.remove(&buffer_id);
 5235                            }
 5236                        })
 5237                        .ok();
 5238                    }
 5239                });
 5240
 5241                buffer
 5242                    .update(cx, |buffer, _| {
 5243                        buffer.wait_for_edits(Some(position.timestamp))
 5244                    })?
 5245                    .await?;
 5246                this.update(cx, |this, cx| {
 5247                    let position = position.to_point_utf16(buffer.read(cx));
 5248                    this.on_type_format(buffer, position, trigger, false, cx)
 5249                })?
 5250                .await
 5251            })
 5252        } else {
 5253            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5254        }
 5255    }
 5256
 5257    pub fn on_type_format<T: ToPointUtf16>(
 5258        &mut self,
 5259        buffer: Entity<Buffer>,
 5260        position: T,
 5261        trigger: String,
 5262        push_to_history: bool,
 5263        cx: &mut Context<Self>,
 5264    ) -> Task<Result<Option<Transaction>>> {
 5265        let position = position.to_point_utf16(buffer.read(cx));
 5266        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5267    }
 5268
 5269    fn on_type_format_impl(
 5270        &mut self,
 5271        buffer: Entity<Buffer>,
 5272        position: PointUtf16,
 5273        trigger: String,
 5274        push_to_history: bool,
 5275        cx: &mut Context<Self>,
 5276    ) -> Task<Result<Option<Transaction>>> {
 5277        let options = buffer.update(cx, |buffer, cx| {
 5278            lsp_command::lsp_formatting_options(
 5279                language_settings(
 5280                    buffer.language_at(position).map(|l| l.name()),
 5281                    buffer.file(),
 5282                    cx,
 5283                )
 5284                .as_ref(),
 5285            )
 5286        });
 5287
 5288        cx.spawn(async move |this, cx| {
 5289            if let Some(waiter) =
 5290                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5291            {
 5292                waiter.await?;
 5293            }
 5294            cx.update(|cx| {
 5295                this.update(cx, |this, cx| {
 5296                    this.request_lsp(
 5297                        buffer.clone(),
 5298                        LanguageServerToQuery::FirstCapable,
 5299                        OnTypeFormatting {
 5300                            position,
 5301                            trigger,
 5302                            options,
 5303                            push_to_history,
 5304                        },
 5305                        cx,
 5306                    )
 5307                })
 5308            })??
 5309            .await
 5310        })
 5311    }
 5312
 5313    pub fn definitions(
 5314        &mut self,
 5315        buffer: &Entity<Buffer>,
 5316        position: PointUtf16,
 5317        cx: &mut Context<Self>,
 5318    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5319        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5320            let request = GetDefinitions { position };
 5321            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5322                return Task::ready(Ok(None));
 5323            }
 5324            let request_task = upstream_client.request_lsp(
 5325                project_id,
 5326                None,
 5327                LSP_REQUEST_TIMEOUT,
 5328                cx.background_executor().clone(),
 5329                request.to_proto(project_id, buffer.read(cx)),
 5330            );
 5331            let buffer = buffer.clone();
 5332            cx.spawn(async move |weak_project, cx| {
 5333                let Some(project) = weak_project.upgrade() else {
 5334                    return Ok(None);
 5335                };
 5336                let Some(responses) = request_task.await? else {
 5337                    return Ok(None);
 5338                };
 5339                let actions = join_all(responses.payload.into_iter().map(|response| {
 5340                    GetDefinitions { position }.response_from_proto(
 5341                        response.response,
 5342                        project.clone(),
 5343                        buffer.clone(),
 5344                        cx.clone(),
 5345                    )
 5346                }))
 5347                .await;
 5348
 5349                Ok(Some(
 5350                    actions
 5351                        .into_iter()
 5352                        .collect::<Result<Vec<Vec<_>>>>()?
 5353                        .into_iter()
 5354                        .flatten()
 5355                        .dedup()
 5356                        .collect(),
 5357                ))
 5358            })
 5359        } else {
 5360            let definitions_task = self.request_multiple_lsp_locally(
 5361                buffer,
 5362                Some(position),
 5363                GetDefinitions { position },
 5364                cx,
 5365            );
 5366            cx.background_spawn(async move {
 5367                Ok(Some(
 5368                    definitions_task
 5369                        .await
 5370                        .into_iter()
 5371                        .flat_map(|(_, definitions)| definitions)
 5372                        .dedup()
 5373                        .collect(),
 5374                ))
 5375            })
 5376        }
 5377    }
 5378
 5379    pub fn declarations(
 5380        &mut self,
 5381        buffer: &Entity<Buffer>,
 5382        position: PointUtf16,
 5383        cx: &mut Context<Self>,
 5384    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5385        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5386            let request = GetDeclarations { position };
 5387            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5388                return Task::ready(Ok(None));
 5389            }
 5390            let request_task = upstream_client.request_lsp(
 5391                project_id,
 5392                None,
 5393                LSP_REQUEST_TIMEOUT,
 5394                cx.background_executor().clone(),
 5395                request.to_proto(project_id, buffer.read(cx)),
 5396            );
 5397            let buffer = buffer.clone();
 5398            cx.spawn(async move |weak_project, cx| {
 5399                let Some(project) = weak_project.upgrade() else {
 5400                    return Ok(None);
 5401                };
 5402                let Some(responses) = request_task.await? else {
 5403                    return Ok(None);
 5404                };
 5405                let actions = join_all(responses.payload.into_iter().map(|response| {
 5406                    GetDeclarations { position }.response_from_proto(
 5407                        response.response,
 5408                        project.clone(),
 5409                        buffer.clone(),
 5410                        cx.clone(),
 5411                    )
 5412                }))
 5413                .await;
 5414
 5415                Ok(Some(
 5416                    actions
 5417                        .into_iter()
 5418                        .collect::<Result<Vec<Vec<_>>>>()?
 5419                        .into_iter()
 5420                        .flatten()
 5421                        .dedup()
 5422                        .collect(),
 5423                ))
 5424            })
 5425        } else {
 5426            let declarations_task = self.request_multiple_lsp_locally(
 5427                buffer,
 5428                Some(position),
 5429                GetDeclarations { position },
 5430                cx,
 5431            );
 5432            cx.background_spawn(async move {
 5433                Ok(Some(
 5434                    declarations_task
 5435                        .await
 5436                        .into_iter()
 5437                        .flat_map(|(_, declarations)| declarations)
 5438                        .dedup()
 5439                        .collect(),
 5440                ))
 5441            })
 5442        }
 5443    }
 5444
 5445    pub fn type_definitions(
 5446        &mut self,
 5447        buffer: &Entity<Buffer>,
 5448        position: PointUtf16,
 5449        cx: &mut Context<Self>,
 5450    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5451        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5452            let request = GetTypeDefinitions { position };
 5453            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5454                return Task::ready(Ok(None));
 5455            }
 5456            let request_task = upstream_client.request_lsp(
 5457                project_id,
 5458                None,
 5459                LSP_REQUEST_TIMEOUT,
 5460                cx.background_executor().clone(),
 5461                request.to_proto(project_id, buffer.read(cx)),
 5462            );
 5463            let buffer = buffer.clone();
 5464            cx.spawn(async move |weak_project, cx| {
 5465                let Some(project) = weak_project.upgrade() else {
 5466                    return Ok(None);
 5467                };
 5468                let Some(responses) = request_task.await? else {
 5469                    return Ok(None);
 5470                };
 5471                let actions = join_all(responses.payload.into_iter().map(|response| {
 5472                    GetTypeDefinitions { position }.response_from_proto(
 5473                        response.response,
 5474                        project.clone(),
 5475                        buffer.clone(),
 5476                        cx.clone(),
 5477                    )
 5478                }))
 5479                .await;
 5480
 5481                Ok(Some(
 5482                    actions
 5483                        .into_iter()
 5484                        .collect::<Result<Vec<Vec<_>>>>()?
 5485                        .into_iter()
 5486                        .flatten()
 5487                        .dedup()
 5488                        .collect(),
 5489                ))
 5490            })
 5491        } else {
 5492            let type_definitions_task = self.request_multiple_lsp_locally(
 5493                buffer,
 5494                Some(position),
 5495                GetTypeDefinitions { position },
 5496                cx,
 5497            );
 5498            cx.background_spawn(async move {
 5499                Ok(Some(
 5500                    type_definitions_task
 5501                        .await
 5502                        .into_iter()
 5503                        .flat_map(|(_, type_definitions)| type_definitions)
 5504                        .dedup()
 5505                        .collect(),
 5506                ))
 5507            })
 5508        }
 5509    }
 5510
 5511    pub fn implementations(
 5512        &mut self,
 5513        buffer: &Entity<Buffer>,
 5514        position: PointUtf16,
 5515        cx: &mut Context<Self>,
 5516    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5517        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5518            let request = GetImplementations { position };
 5519            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5520                return Task::ready(Ok(None));
 5521            }
 5522            let request_task = upstream_client.request_lsp(
 5523                project_id,
 5524                None,
 5525                LSP_REQUEST_TIMEOUT,
 5526                cx.background_executor().clone(),
 5527                request.to_proto(project_id, buffer.read(cx)),
 5528            );
 5529            let buffer = buffer.clone();
 5530            cx.spawn(async move |weak_project, cx| {
 5531                let Some(project) = weak_project.upgrade() else {
 5532                    return Ok(None);
 5533                };
 5534                let Some(responses) = request_task.await? else {
 5535                    return Ok(None);
 5536                };
 5537                let actions = join_all(responses.payload.into_iter().map(|response| {
 5538                    GetImplementations { position }.response_from_proto(
 5539                        response.response,
 5540                        project.clone(),
 5541                        buffer.clone(),
 5542                        cx.clone(),
 5543                    )
 5544                }))
 5545                .await;
 5546
 5547                Ok(Some(
 5548                    actions
 5549                        .into_iter()
 5550                        .collect::<Result<Vec<Vec<_>>>>()?
 5551                        .into_iter()
 5552                        .flatten()
 5553                        .dedup()
 5554                        .collect(),
 5555                ))
 5556            })
 5557        } else {
 5558            let implementations_task = self.request_multiple_lsp_locally(
 5559                buffer,
 5560                Some(position),
 5561                GetImplementations { position },
 5562                cx,
 5563            );
 5564            cx.background_spawn(async move {
 5565                Ok(Some(
 5566                    implementations_task
 5567                        .await
 5568                        .into_iter()
 5569                        .flat_map(|(_, implementations)| implementations)
 5570                        .dedup()
 5571                        .collect(),
 5572                ))
 5573            })
 5574        }
 5575    }
 5576
 5577    pub fn references(
 5578        &mut self,
 5579        buffer: &Entity<Buffer>,
 5580        position: PointUtf16,
 5581        cx: &mut Context<Self>,
 5582    ) -> Task<Result<Option<Vec<Location>>>> {
 5583        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5584            let request = GetReferences { position };
 5585            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5586                return Task::ready(Ok(None));
 5587            }
 5588
 5589            let request_task = upstream_client.request_lsp(
 5590                project_id,
 5591                None,
 5592                LSP_REQUEST_TIMEOUT,
 5593                cx.background_executor().clone(),
 5594                request.to_proto(project_id, buffer.read(cx)),
 5595            );
 5596            let buffer = buffer.clone();
 5597            cx.spawn(async move |weak_project, cx| {
 5598                let Some(project) = weak_project.upgrade() else {
 5599                    return Ok(None);
 5600                };
 5601                let Some(responses) = request_task.await? else {
 5602                    return Ok(None);
 5603                };
 5604
 5605                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5606                    GetReferences { position }.response_from_proto(
 5607                        lsp_response.response,
 5608                        project.clone(),
 5609                        buffer.clone(),
 5610                        cx.clone(),
 5611                    )
 5612                }))
 5613                .await
 5614                .into_iter()
 5615                .collect::<Result<Vec<Vec<_>>>>()?
 5616                .into_iter()
 5617                .flatten()
 5618                .dedup()
 5619                .collect();
 5620                Ok(Some(locations))
 5621            })
 5622        } else {
 5623            let references_task = self.request_multiple_lsp_locally(
 5624                buffer,
 5625                Some(position),
 5626                GetReferences { position },
 5627                cx,
 5628            );
 5629            cx.background_spawn(async move {
 5630                Ok(Some(
 5631                    references_task
 5632                        .await
 5633                        .into_iter()
 5634                        .flat_map(|(_, references)| references)
 5635                        .dedup()
 5636                        .collect(),
 5637                ))
 5638            })
 5639        }
 5640    }
 5641
 5642    pub fn code_actions(
 5643        &mut self,
 5644        buffer: &Entity<Buffer>,
 5645        range: Range<Anchor>,
 5646        kinds: Option<Vec<CodeActionKind>>,
 5647        cx: &mut Context<Self>,
 5648    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5649        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5650            let request = GetCodeActions {
 5651                range: range.clone(),
 5652                kinds: kinds.clone(),
 5653            };
 5654            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5655                return Task::ready(Ok(None));
 5656            }
 5657            let request_task = upstream_client.request_lsp(
 5658                project_id,
 5659                None,
 5660                LSP_REQUEST_TIMEOUT,
 5661                cx.background_executor().clone(),
 5662                request.to_proto(project_id, buffer.read(cx)),
 5663            );
 5664            let buffer = buffer.clone();
 5665            cx.spawn(async move |weak_project, cx| {
 5666                let Some(project) = weak_project.upgrade() else {
 5667                    return Ok(None);
 5668                };
 5669                let Some(responses) = request_task.await? else {
 5670                    return Ok(None);
 5671                };
 5672                let actions = join_all(responses.payload.into_iter().map(|response| {
 5673                    GetCodeActions {
 5674                        range: range.clone(),
 5675                        kinds: kinds.clone(),
 5676                    }
 5677                    .response_from_proto(
 5678                        response.response,
 5679                        project.clone(),
 5680                        buffer.clone(),
 5681                        cx.clone(),
 5682                    )
 5683                }))
 5684                .await;
 5685
 5686                Ok(Some(
 5687                    actions
 5688                        .into_iter()
 5689                        .collect::<Result<Vec<Vec<_>>>>()?
 5690                        .into_iter()
 5691                        .flatten()
 5692                        .collect(),
 5693                ))
 5694            })
 5695        } else {
 5696            let all_actions_task = self.request_multiple_lsp_locally(
 5697                buffer,
 5698                Some(range.start),
 5699                GetCodeActions { range, kinds },
 5700                cx,
 5701            );
 5702            cx.background_spawn(async move {
 5703                Ok(Some(
 5704                    all_actions_task
 5705                        .await
 5706                        .into_iter()
 5707                        .flat_map(|(_, actions)| actions)
 5708                        .collect(),
 5709                ))
 5710            })
 5711        }
 5712    }
 5713
 5714    pub fn code_lens_actions(
 5715        &mut self,
 5716        buffer: &Entity<Buffer>,
 5717        cx: &mut Context<Self>,
 5718    ) -> CodeLensTask {
 5719        let version_queried_for = buffer.read(cx).version();
 5720        let buffer_id = buffer.read(cx).remote_id();
 5721        let existing_servers = self.as_local().map(|local| {
 5722            local
 5723                .buffers_opened_in_servers
 5724                .get(&buffer_id)
 5725                .cloned()
 5726                .unwrap_or_default()
 5727        });
 5728
 5729        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 5730            if let Some(cached_lens) = &lsp_data.code_lens {
 5731                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 5732                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 5733                        existing_servers != cached_lens.lens.keys().copied().collect()
 5734                    });
 5735                    if !has_different_servers {
 5736                        return Task::ready(Ok(Some(
 5737                            cached_lens.lens.values().flatten().cloned().collect(),
 5738                        )))
 5739                        .shared();
 5740                    }
 5741                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 5742                    if !version_queried_for.changed_since(updating_for) {
 5743                        return running_update.clone();
 5744                    }
 5745                }
 5746            }
 5747        }
 5748
 5749        let lens_lsp_data = self
 5750            .latest_lsp_data(buffer, cx)
 5751            .code_lens
 5752            .get_or_insert_default();
 5753        let buffer = buffer.clone();
 5754        let query_version_queried_for = version_queried_for.clone();
 5755        let new_task = cx
 5756            .spawn(async move |lsp_store, cx| {
 5757                cx.background_executor()
 5758                    .timer(Duration::from_millis(30))
 5759                    .await;
 5760                let fetched_lens = lsp_store
 5761                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 5762                    .map_err(Arc::new)?
 5763                    .await
 5764                    .context("fetching code lens")
 5765                    .map_err(Arc::new);
 5766                let fetched_lens = match fetched_lens {
 5767                    Ok(fetched_lens) => fetched_lens,
 5768                    Err(e) => {
 5769                        lsp_store
 5770                            .update(cx, |lsp_store, _| {
 5771                                if let Some(lens_lsp_data) = lsp_store
 5772                                    .lsp_data
 5773                                    .get_mut(&buffer_id)
 5774                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 5775                                {
 5776                                    lens_lsp_data.update = None;
 5777                                }
 5778                            })
 5779                            .ok();
 5780                        return Err(e);
 5781                    }
 5782                };
 5783
 5784                lsp_store
 5785                    .update(cx, |lsp_store, _| {
 5786                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 5787                        let code_lens = lsp_data.code_lens.as_mut()?;
 5788                        if let Some(fetched_lens) = fetched_lens {
 5789                            if lsp_data.buffer_version == query_version_queried_for {
 5790                                code_lens.lens.extend(fetched_lens);
 5791                            } else if !lsp_data
 5792                                .buffer_version
 5793                                .changed_since(&query_version_queried_for)
 5794                            {
 5795                                lsp_data.buffer_version = query_version_queried_for;
 5796                                code_lens.lens = fetched_lens;
 5797                            }
 5798                        }
 5799                        code_lens.update = None;
 5800                        Some(code_lens.lens.values().flatten().cloned().collect())
 5801                    })
 5802                    .map_err(Arc::new)
 5803            })
 5804            .shared();
 5805        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 5806        new_task
 5807    }
 5808
 5809    fn fetch_code_lens(
 5810        &mut self,
 5811        buffer: &Entity<Buffer>,
 5812        cx: &mut Context<Self>,
 5813    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 5814        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5815            let request = GetCodeLens;
 5816            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5817                return Task::ready(Ok(None));
 5818            }
 5819            let request_task = upstream_client.request_lsp(
 5820                project_id,
 5821                None,
 5822                LSP_REQUEST_TIMEOUT,
 5823                cx.background_executor().clone(),
 5824                request.to_proto(project_id, buffer.read(cx)),
 5825            );
 5826            let buffer = buffer.clone();
 5827            cx.spawn(async move |weak_lsp_store, cx| {
 5828                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5829                    return Ok(None);
 5830                };
 5831                let Some(responses) = request_task.await? else {
 5832                    return Ok(None);
 5833                };
 5834
 5835                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 5836                    let lsp_store = lsp_store.clone();
 5837                    let buffer = buffer.clone();
 5838                    let cx = cx.clone();
 5839                    async move {
 5840                        (
 5841                            LanguageServerId::from_proto(response.server_id),
 5842                            GetCodeLens
 5843                                .response_from_proto(response.response, lsp_store, buffer, cx)
 5844                                .await,
 5845                        )
 5846                    }
 5847                }))
 5848                .await;
 5849
 5850                let mut has_errors = false;
 5851                let code_lens_actions = code_lens_actions
 5852                    .into_iter()
 5853                    .filter_map(|(server_id, code_lens)| match code_lens {
 5854                        Ok(code_lens) => Some((server_id, code_lens)),
 5855                        Err(e) => {
 5856                            has_errors = true;
 5857                            log::error!("{e:#}");
 5858                            None
 5859                        }
 5860                    })
 5861                    .collect::<HashMap<_, _>>();
 5862                anyhow::ensure!(
 5863                    !has_errors || !code_lens_actions.is_empty(),
 5864                    "Failed to fetch code lens"
 5865                );
 5866                Ok(Some(code_lens_actions))
 5867            })
 5868        } else {
 5869            let code_lens_actions_task =
 5870                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 5871            cx.background_spawn(async move {
 5872                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 5873            })
 5874        }
 5875    }
 5876
 5877    #[inline(never)]
 5878    pub fn completions(
 5879        &self,
 5880        buffer: &Entity<Buffer>,
 5881        position: PointUtf16,
 5882        context: CompletionContext,
 5883        cx: &mut Context<Self>,
 5884    ) -> Task<Result<Vec<CompletionResponse>>> {
 5885        let language_registry = self.languages.clone();
 5886
 5887        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5888            let request = GetCompletions { position, context };
 5889            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5890                return Task::ready(Ok(Vec::new()));
 5891            }
 5892            let task = self.send_lsp_proto_request(
 5893                buffer.clone(),
 5894                upstream_client,
 5895                project_id,
 5896                request,
 5897                cx,
 5898            );
 5899            let language = buffer.read(cx).language().cloned();
 5900
 5901            // In the future, we should provide project guests with the names of LSP adapters,
 5902            // so that they can use the correct LSP adapter when computing labels. For now,
 5903            // guests just use the first LSP adapter associated with the buffer's language.
 5904            let lsp_adapter = language.as_ref().and_then(|language| {
 5905                language_registry
 5906                    .lsp_adapters(&language.name())
 5907                    .first()
 5908                    .cloned()
 5909            });
 5910
 5911            cx.foreground_executor().spawn(async move {
 5912                let completion_response = task.await?;
 5913                let completions = populate_labels_for_completions(
 5914                    completion_response.completions,
 5915                    language,
 5916                    lsp_adapter,
 5917                )
 5918                .await;
 5919                Ok(vec![CompletionResponse {
 5920                    completions,
 5921                    display_options: CompletionDisplayOptions::default(),
 5922                    is_incomplete: completion_response.is_incomplete,
 5923                }])
 5924            })
 5925        } else if let Some(local) = self.as_local() {
 5926            let snapshot = buffer.read(cx).snapshot();
 5927            let offset = position.to_offset(&snapshot);
 5928            let scope = snapshot.language_scope_at(offset);
 5929            let language = snapshot.language().cloned();
 5930            let completion_settings = language_settings(
 5931                language.as_ref().map(|language| language.name()),
 5932                buffer.read(cx).file(),
 5933                cx,
 5934            )
 5935            .completions
 5936            .clone();
 5937            if !completion_settings.lsp {
 5938                return Task::ready(Ok(Vec::new()));
 5939            }
 5940
 5941            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 5942                local
 5943                    .language_servers_for_buffer(buffer, cx)
 5944                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 5945                    .filter(|(adapter, _)| {
 5946                        scope
 5947                            .as_ref()
 5948                            .map(|scope| scope.language_allowed(&adapter.name))
 5949                            .unwrap_or(true)
 5950                    })
 5951                    .map(|(_, server)| server.server_id())
 5952                    .collect()
 5953            });
 5954
 5955            let buffer = buffer.clone();
 5956            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 5957            let lsp_timeout = if lsp_timeout > 0 {
 5958                Some(Duration::from_millis(lsp_timeout))
 5959            } else {
 5960                None
 5961            };
 5962            cx.spawn(async move |this,  cx| {
 5963                let mut tasks = Vec::with_capacity(server_ids.len());
 5964                this.update(cx, |lsp_store, cx| {
 5965                    for server_id in server_ids {
 5966                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 5967                        let lsp_timeout = lsp_timeout
 5968                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 5969                        let mut timeout = cx.background_spawn(async move {
 5970                            match lsp_timeout {
 5971                                Some(lsp_timeout) => {
 5972                                    lsp_timeout.await;
 5973                                    true
 5974                                },
 5975                                None => false,
 5976                            }
 5977                        }).fuse();
 5978                        let mut lsp_request = lsp_store.request_lsp(
 5979                            buffer.clone(),
 5980                            LanguageServerToQuery::Other(server_id),
 5981                            GetCompletions {
 5982                                position,
 5983                                context: context.clone(),
 5984                            },
 5985                            cx,
 5986                        ).fuse();
 5987                        let new_task = cx.background_spawn(async move {
 5988                            select_biased! {
 5989                                response = lsp_request => anyhow::Ok(Some(response?)),
 5990                                timeout_happened = timeout => {
 5991                                    if timeout_happened {
 5992                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 5993                                        Ok(None)
 5994                                    } else {
 5995                                        let completions = lsp_request.await?;
 5996                                        Ok(Some(completions))
 5997                                    }
 5998                                },
 5999                            }
 6000                        });
 6001                        tasks.push((lsp_adapter, new_task));
 6002                    }
 6003                })?;
 6004
 6005                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6006                    let completion_response = task.await.ok()??;
 6007                    let completions = populate_labels_for_completions(
 6008                            completion_response.completions,
 6009                            language.clone(),
 6010                            lsp_adapter,
 6011                        )
 6012                        .await;
 6013                    Some(CompletionResponse {
 6014                        completions,
 6015                        display_options: CompletionDisplayOptions::default(),
 6016                        is_incomplete: completion_response.is_incomplete,
 6017                    })
 6018                });
 6019
 6020                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6021
 6022                Ok(responses.into_iter().flatten().collect())
 6023            })
 6024        } else {
 6025            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6026        }
 6027    }
 6028
 6029    pub fn resolve_completions(
 6030        &self,
 6031        buffer: Entity<Buffer>,
 6032        completion_indices: Vec<usize>,
 6033        completions: Rc<RefCell<Box<[Completion]>>>,
 6034        cx: &mut Context<Self>,
 6035    ) -> Task<Result<bool>> {
 6036        let client = self.upstream_client();
 6037        let buffer_id = buffer.read(cx).remote_id();
 6038        let buffer_snapshot = buffer.read(cx).snapshot();
 6039
 6040        if !self.check_if_capable_for_proto_request(
 6041            &buffer,
 6042            GetCompletions::can_resolve_completions,
 6043            cx,
 6044        ) {
 6045            return Task::ready(Ok(false));
 6046        }
 6047        cx.spawn(async move |lsp_store, cx| {
 6048            let mut did_resolve = false;
 6049            if let Some((client, project_id)) = client {
 6050                for completion_index in completion_indices {
 6051                    let server_id = {
 6052                        let completion = &completions.borrow()[completion_index];
 6053                        completion.source.server_id()
 6054                    };
 6055                    if let Some(server_id) = server_id {
 6056                        if Self::resolve_completion_remote(
 6057                            project_id,
 6058                            server_id,
 6059                            buffer_id,
 6060                            completions.clone(),
 6061                            completion_index,
 6062                            client.clone(),
 6063                        )
 6064                        .await
 6065                        .log_err()
 6066                        .is_some()
 6067                        {
 6068                            did_resolve = true;
 6069                        }
 6070                    } else {
 6071                        resolve_word_completion(
 6072                            &buffer_snapshot,
 6073                            &mut completions.borrow_mut()[completion_index],
 6074                        );
 6075                    }
 6076                }
 6077            } else {
 6078                for completion_index in completion_indices {
 6079                    let server_id = {
 6080                        let completion = &completions.borrow()[completion_index];
 6081                        completion.source.server_id()
 6082                    };
 6083                    if let Some(server_id) = server_id {
 6084                        let server_and_adapter = lsp_store
 6085                            .read_with(cx, |lsp_store, _| {
 6086                                let server = lsp_store.language_server_for_id(server_id)?;
 6087                                let adapter =
 6088                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6089                                Some((server, adapter))
 6090                            })
 6091                            .ok()
 6092                            .flatten();
 6093                        let Some((server, adapter)) = server_and_adapter else {
 6094                            continue;
 6095                        };
 6096
 6097                        let resolved = Self::resolve_completion_local(
 6098                            server,
 6099                            completions.clone(),
 6100                            completion_index,
 6101                        )
 6102                        .await
 6103                        .log_err()
 6104                        .is_some();
 6105                        if resolved {
 6106                            Self::regenerate_completion_labels(
 6107                                adapter,
 6108                                &buffer_snapshot,
 6109                                completions.clone(),
 6110                                completion_index,
 6111                            )
 6112                            .await
 6113                            .log_err();
 6114                            did_resolve = true;
 6115                        }
 6116                    } else {
 6117                        resolve_word_completion(
 6118                            &buffer_snapshot,
 6119                            &mut completions.borrow_mut()[completion_index],
 6120                        );
 6121                    }
 6122                }
 6123            }
 6124
 6125            Ok(did_resolve)
 6126        })
 6127    }
 6128
 6129    async fn resolve_completion_local(
 6130        server: Arc<lsp::LanguageServer>,
 6131        completions: Rc<RefCell<Box<[Completion]>>>,
 6132        completion_index: usize,
 6133    ) -> Result<()> {
 6134        let server_id = server.server_id();
 6135        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6136            return Ok(());
 6137        }
 6138
 6139        let request = {
 6140            let completion = &completions.borrow()[completion_index];
 6141            match &completion.source {
 6142                CompletionSource::Lsp {
 6143                    lsp_completion,
 6144                    resolved,
 6145                    server_id: completion_server_id,
 6146                    ..
 6147                } => {
 6148                    if *resolved {
 6149                        return Ok(());
 6150                    }
 6151                    anyhow::ensure!(
 6152                        server_id == *completion_server_id,
 6153                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6154                    );
 6155                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6156                }
 6157                CompletionSource::BufferWord { .. }
 6158                | CompletionSource::Dap { .. }
 6159                | CompletionSource::Custom => {
 6160                    return Ok(());
 6161                }
 6162            }
 6163        };
 6164        let resolved_completion = request
 6165            .await
 6166            .into_response()
 6167            .context("resolve completion")?;
 6168
 6169        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6170        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6171
 6172        let mut completions = completions.borrow_mut();
 6173        let completion = &mut completions[completion_index];
 6174        if let CompletionSource::Lsp {
 6175            lsp_completion,
 6176            resolved,
 6177            server_id: completion_server_id,
 6178            ..
 6179        } = &mut completion.source
 6180        {
 6181            if *resolved {
 6182                return Ok(());
 6183            }
 6184            anyhow::ensure!(
 6185                server_id == *completion_server_id,
 6186                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6187            );
 6188            *lsp_completion = Box::new(resolved_completion);
 6189            *resolved = true;
 6190        }
 6191        Ok(())
 6192    }
 6193
 6194    async fn regenerate_completion_labels(
 6195        adapter: Arc<CachedLspAdapter>,
 6196        snapshot: &BufferSnapshot,
 6197        completions: Rc<RefCell<Box<[Completion]>>>,
 6198        completion_index: usize,
 6199    ) -> Result<()> {
 6200        let completion_item = completions.borrow()[completion_index]
 6201            .source
 6202            .lsp_completion(true)
 6203            .map(Cow::into_owned);
 6204        if let Some(lsp_documentation) = completion_item
 6205            .as_ref()
 6206            .and_then(|completion_item| completion_item.documentation.clone())
 6207        {
 6208            let mut completions = completions.borrow_mut();
 6209            let completion = &mut completions[completion_index];
 6210            completion.documentation = Some(lsp_documentation.into());
 6211        } else {
 6212            let mut completions = completions.borrow_mut();
 6213            let completion = &mut completions[completion_index];
 6214            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6215        }
 6216
 6217        let mut new_label = match completion_item {
 6218            Some(completion_item) => {
 6219                // NB: Zed does not have `details` inside the completion resolve capabilities, but certain language servers violate the spec and do not return `details` immediately, e.g. https://github.com/yioneko/vtsls/issues/213
 6220                // So we have to update the label here anyway...
 6221                let language = snapshot.language();
 6222                match language {
 6223                    Some(language) => {
 6224                        adapter
 6225                            .labels_for_completions(
 6226                                std::slice::from_ref(&completion_item),
 6227                                language,
 6228                            )
 6229                            .await?
 6230                    }
 6231                    None => Vec::new(),
 6232                }
 6233                .pop()
 6234                .flatten()
 6235                .unwrap_or_else(|| {
 6236                    CodeLabel::fallback_for_completion(
 6237                        &completion_item,
 6238                        language.map(|language| language.as_ref()),
 6239                    )
 6240                })
 6241            }
 6242            None => CodeLabel::plain(
 6243                completions.borrow()[completion_index].new_text.clone(),
 6244                None,
 6245            ),
 6246        };
 6247        ensure_uniform_list_compatible_label(&mut new_label);
 6248
 6249        let mut completions = completions.borrow_mut();
 6250        let completion = &mut completions[completion_index];
 6251        if completion.label.filter_text() == new_label.filter_text() {
 6252            completion.label = new_label;
 6253        } else {
 6254            log::error!(
 6255                "Resolved completion changed display label from {} to {}. \
 6256                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6257                completion.label.text(),
 6258                new_label.text(),
 6259                completion.label.filter_text(),
 6260                new_label.filter_text()
 6261            );
 6262        }
 6263
 6264        Ok(())
 6265    }
 6266
 6267    async fn resolve_completion_remote(
 6268        project_id: u64,
 6269        server_id: LanguageServerId,
 6270        buffer_id: BufferId,
 6271        completions: Rc<RefCell<Box<[Completion]>>>,
 6272        completion_index: usize,
 6273        client: AnyProtoClient,
 6274    ) -> Result<()> {
 6275        let lsp_completion = {
 6276            let completion = &completions.borrow()[completion_index];
 6277            match &completion.source {
 6278                CompletionSource::Lsp {
 6279                    lsp_completion,
 6280                    resolved,
 6281                    server_id: completion_server_id,
 6282                    ..
 6283                } => {
 6284                    anyhow::ensure!(
 6285                        server_id == *completion_server_id,
 6286                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6287                    );
 6288                    if *resolved {
 6289                        return Ok(());
 6290                    }
 6291                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6292                }
 6293                CompletionSource::Custom
 6294                | CompletionSource::Dap { .. }
 6295                | CompletionSource::BufferWord { .. } => {
 6296                    return Ok(());
 6297                }
 6298            }
 6299        };
 6300        let request = proto::ResolveCompletionDocumentation {
 6301            project_id,
 6302            language_server_id: server_id.0 as u64,
 6303            lsp_completion,
 6304            buffer_id: buffer_id.into(),
 6305        };
 6306
 6307        let response = client
 6308            .request(request)
 6309            .await
 6310            .context("completion documentation resolve proto request")?;
 6311        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6312
 6313        let documentation = if response.documentation.is_empty() {
 6314            CompletionDocumentation::Undocumented
 6315        } else if response.documentation_is_markdown {
 6316            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6317        } else if response.documentation.lines().count() <= 1 {
 6318            CompletionDocumentation::SingleLine(response.documentation.into())
 6319        } else {
 6320            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6321        };
 6322
 6323        let mut completions = completions.borrow_mut();
 6324        let completion = &mut completions[completion_index];
 6325        completion.documentation = Some(documentation);
 6326        if let CompletionSource::Lsp {
 6327            insert_range,
 6328            lsp_completion,
 6329            resolved,
 6330            server_id: completion_server_id,
 6331            lsp_defaults: _,
 6332        } = &mut completion.source
 6333        {
 6334            let completion_insert_range = response
 6335                .old_insert_start
 6336                .and_then(deserialize_anchor)
 6337                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6338            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6339
 6340            if *resolved {
 6341                return Ok(());
 6342            }
 6343            anyhow::ensure!(
 6344                server_id == *completion_server_id,
 6345                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6346            );
 6347            *lsp_completion = Box::new(resolved_lsp_completion);
 6348            *resolved = true;
 6349        }
 6350
 6351        let replace_range = response
 6352            .old_replace_start
 6353            .and_then(deserialize_anchor)
 6354            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6355        if let Some((old_replace_start, old_replace_end)) = replace_range
 6356            && !response.new_text.is_empty()
 6357        {
 6358            completion.new_text = response.new_text;
 6359            completion.replace_range = old_replace_start..old_replace_end;
 6360        }
 6361
 6362        Ok(())
 6363    }
 6364
 6365    pub fn apply_additional_edits_for_completion(
 6366        &self,
 6367        buffer_handle: Entity<Buffer>,
 6368        completions: Rc<RefCell<Box<[Completion]>>>,
 6369        completion_index: usize,
 6370        push_to_history: bool,
 6371        cx: &mut Context<Self>,
 6372    ) -> Task<Result<Option<Transaction>>> {
 6373        if let Some((client, project_id)) = self.upstream_client() {
 6374            let buffer = buffer_handle.read(cx);
 6375            let buffer_id = buffer.remote_id();
 6376            cx.spawn(async move |_, cx| {
 6377                let request = {
 6378                    let completion = completions.borrow()[completion_index].clone();
 6379                    proto::ApplyCompletionAdditionalEdits {
 6380                        project_id,
 6381                        buffer_id: buffer_id.into(),
 6382                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6383                            replace_range: completion.replace_range,
 6384                            new_text: completion.new_text,
 6385                            source: completion.source,
 6386                        })),
 6387                    }
 6388                };
 6389
 6390                if let Some(transaction) = client.request(request).await?.transaction {
 6391                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6392                    buffer_handle
 6393                        .update(cx, |buffer, _| {
 6394                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6395                        })?
 6396                        .await?;
 6397                    if push_to_history {
 6398                        buffer_handle.update(cx, |buffer, _| {
 6399                            buffer.push_transaction(transaction.clone(), Instant::now());
 6400                            buffer.finalize_last_transaction();
 6401                        })?;
 6402                    }
 6403                    Ok(Some(transaction))
 6404                } else {
 6405                    Ok(None)
 6406                }
 6407            })
 6408        } else {
 6409            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6410                let completion = &completions.borrow()[completion_index];
 6411                let server_id = completion.source.server_id()?;
 6412                Some(
 6413                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6414                        .1
 6415                        .clone(),
 6416                )
 6417            }) else {
 6418                return Task::ready(Ok(None));
 6419            };
 6420
 6421            cx.spawn(async move |this, cx| {
 6422                Self::resolve_completion_local(
 6423                    server.clone(),
 6424                    completions.clone(),
 6425                    completion_index,
 6426                )
 6427                .await
 6428                .context("resolving completion")?;
 6429                let completion = completions.borrow()[completion_index].clone();
 6430                let additional_text_edits = completion
 6431                    .source
 6432                    .lsp_completion(true)
 6433                    .as_ref()
 6434                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6435                if let Some(edits) = additional_text_edits {
 6436                    let edits = this
 6437                        .update(cx, |this, cx| {
 6438                            this.as_local_mut().unwrap().edits_from_lsp(
 6439                                &buffer_handle,
 6440                                edits,
 6441                                server.server_id(),
 6442                                None,
 6443                                cx,
 6444                            )
 6445                        })?
 6446                        .await?;
 6447
 6448                    buffer_handle.update(cx, |buffer, cx| {
 6449                        buffer.finalize_last_transaction();
 6450                        buffer.start_transaction();
 6451
 6452                        for (range, text) in edits {
 6453                            let primary = &completion.replace_range;
 6454
 6455                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6456                            // and the primary completion is just an insertion (empty range), then this is likely
 6457                            // an auto-import scenario and should not be considered overlapping
 6458                            // https://github.com/zed-industries/zed/issues/26136
 6459                            let is_file_start_auto_import = {
 6460                                let snapshot = buffer.snapshot();
 6461                                let primary_start_point = primary.start.to_point(&snapshot);
 6462                                let range_start_point = range.start.to_point(&snapshot);
 6463
 6464                                let result = primary_start_point.row == 0
 6465                                    && primary_start_point.column == 0
 6466                                    && range_start_point.row == 0
 6467                                    && range_start_point.column == 0;
 6468
 6469                                result
 6470                            };
 6471
 6472                            let has_overlap = if is_file_start_auto_import {
 6473                                false
 6474                            } else {
 6475                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6476                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6477                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6478                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6479                                let result = start_within || end_within;
 6480                                result
 6481                            };
 6482
 6483                            //Skip additional edits which overlap with the primary completion edit
 6484                            //https://github.com/zed-industries/zed/pull/1871
 6485                            if !has_overlap {
 6486                                buffer.edit([(range, text)], None, cx);
 6487                            }
 6488                        }
 6489
 6490                        let transaction = if buffer.end_transaction(cx).is_some() {
 6491                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6492                            if !push_to_history {
 6493                                buffer.forget_transaction(transaction.id);
 6494                            }
 6495                            Some(transaction)
 6496                        } else {
 6497                            None
 6498                        };
 6499                        Ok(transaction)
 6500                    })?
 6501                } else {
 6502                    Ok(None)
 6503                }
 6504            })
 6505        }
 6506    }
 6507
 6508    pub fn pull_diagnostics(
 6509        &mut self,
 6510        buffer: Entity<Buffer>,
 6511        cx: &mut Context<Self>,
 6512    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6513        let buffer_id = buffer.read(cx).remote_id();
 6514
 6515        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6516            let mut suitable_capabilities = None;
 6517            // Are we capable for proto request?
 6518            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6519                &buffer,
 6520                |capabilities| {
 6521                    if let Some(caps) = &capabilities.diagnostic_provider {
 6522                        suitable_capabilities = Some(caps.clone());
 6523                        true
 6524                    } else {
 6525                        false
 6526                    }
 6527                },
 6528                cx,
 6529            );
 6530            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6531            let Some(dynamic_caps) = suitable_capabilities else {
 6532                return Task::ready(Ok(None));
 6533            };
 6534            assert!(any_server_has_diagnostics_provider);
 6535
 6536            let request = GetDocumentDiagnostics {
 6537                previous_result_id: None,
 6538                dynamic_caps,
 6539            };
 6540            let request_task = client.request_lsp(
 6541                upstream_project_id,
 6542                None,
 6543                LSP_REQUEST_TIMEOUT,
 6544                cx.background_executor().clone(),
 6545                request.to_proto(upstream_project_id, buffer.read(cx)),
 6546            );
 6547            cx.background_spawn(async move {
 6548                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6549                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6550                // Do not attempt to further process the dummy responses here.
 6551                let _response = request_task.await?;
 6552                Ok(None)
 6553            })
 6554        } else {
 6555            let servers = buffer.update(cx, |buffer, cx| {
 6556                self.language_servers_for_local_buffer(buffer, cx)
 6557                    .map(|(_, server)| server.clone())
 6558                    .collect::<Vec<_>>()
 6559            });
 6560
 6561            let pull_diagnostics = servers
 6562                .into_iter()
 6563                .flat_map(|server| {
 6564                    let result = maybe!({
 6565                        let local = self.as_local()?;
 6566                        let server_id = server.server_id();
 6567                        let providers_with_identifiers = local
 6568                            .language_server_dynamic_registrations
 6569                            .get(&server_id)
 6570                            .into_iter()
 6571                            .flat_map(|registrations| registrations.diagnostics.values().cloned())
 6572                            .collect::<Vec<_>>();
 6573                        Some(
 6574                            providers_with_identifiers
 6575                                .into_iter()
 6576                                .map(|dynamic_caps| {
 6577                                    let result_id = self.result_id(server_id, buffer_id, cx);
 6578                                    self.request_lsp(
 6579                                        buffer.clone(),
 6580                                        LanguageServerToQuery::Other(server_id),
 6581                                        GetDocumentDiagnostics {
 6582                                            previous_result_id: result_id,
 6583                                            dynamic_caps,
 6584                                        },
 6585                                        cx,
 6586                                    )
 6587                                })
 6588                                .collect::<Vec<_>>(),
 6589                        )
 6590                    });
 6591
 6592                    result.unwrap_or_default()
 6593                })
 6594                .collect::<Vec<_>>();
 6595
 6596            cx.background_spawn(async move {
 6597                let mut responses = Vec::new();
 6598                for diagnostics in join_all(pull_diagnostics).await {
 6599                    responses.extend(diagnostics?);
 6600                }
 6601                Ok(Some(responses))
 6602            })
 6603        }
 6604    }
 6605
 6606    pub fn applicable_inlay_chunks(
 6607        &mut self,
 6608        buffer: &Entity<Buffer>,
 6609        ranges: &[Range<text::Anchor>],
 6610        cx: &mut Context<Self>,
 6611    ) -> Vec<Range<BufferRow>> {
 6612        self.latest_lsp_data(buffer, cx)
 6613            .inlay_hints
 6614            .applicable_chunks(ranges)
 6615            .map(|chunk| chunk.start..chunk.end)
 6616            .collect()
 6617    }
 6618
 6619    pub fn invalidate_inlay_hints<'a>(
 6620        &'a mut self,
 6621        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6622    ) {
 6623        for buffer_id in for_buffers {
 6624            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6625                lsp_data.inlay_hints.clear();
 6626            }
 6627        }
 6628    }
 6629
 6630    pub fn inlay_hints(
 6631        &mut self,
 6632        invalidate: InvalidationStrategy,
 6633        buffer: Entity<Buffer>,
 6634        ranges: Vec<Range<text::Anchor>>,
 6635        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6636        cx: &mut Context<Self>,
 6637    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6638        let buffer_snapshot = buffer.read(cx).snapshot();
 6639        let for_server = if let InvalidationStrategy::RefreshRequested(server_id) = invalidate {
 6640            Some(server_id)
 6641        } else {
 6642            None
 6643        };
 6644        let invalidate_cache = invalidate.should_invalidate();
 6645        let next_hint_id = self.next_hint_id.clone();
 6646        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6647        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6648        let known_chunks = known_chunks
 6649            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6650            .map(|(_, known_chunks)| known_chunks)
 6651            .unwrap_or_default();
 6652
 6653        let mut hint_fetch_tasks = Vec::new();
 6654        let mut cached_inlay_hints = HashMap::default();
 6655        let mut ranges_to_query = Vec::new();
 6656        let applicable_chunks = existing_inlay_hints
 6657            .applicable_chunks(ranges.as_slice())
 6658            .filter(|chunk| !known_chunks.contains(&(chunk.start..chunk.end)))
 6659            .collect::<Vec<_>>();
 6660        if applicable_chunks.is_empty() {
 6661            return HashMap::default();
 6662        }
 6663
 6664        let last_chunk_number = existing_inlay_hints.buffer_chunks_len() - 1;
 6665
 6666        for row_chunk in applicable_chunks {
 6667            match (
 6668                existing_inlay_hints
 6669                    .cached_hints(&row_chunk)
 6670                    .filter(|_| !invalidate_cache)
 6671                    .cloned(),
 6672                existing_inlay_hints
 6673                    .fetched_hints(&row_chunk)
 6674                    .as_ref()
 6675                    .filter(|_| !invalidate_cache)
 6676                    .cloned(),
 6677            ) {
 6678                (None, None) => {
 6679                    let end = if last_chunk_number == row_chunk.id {
 6680                        Point::new(row_chunk.end, buffer_snapshot.line_len(row_chunk.end))
 6681                    } else {
 6682                        Point::new(row_chunk.end, 0)
 6683                    };
 6684                    ranges_to_query.push((
 6685                        row_chunk,
 6686                        buffer_snapshot.anchor_before(Point::new(row_chunk.start, 0))
 6687                            ..buffer_snapshot.anchor_after(end),
 6688                    ));
 6689                }
 6690                (None, Some(fetched_hints)) => {
 6691                    hint_fetch_tasks.push((row_chunk, fetched_hints.clone()))
 6692                }
 6693                (Some(cached_hints), None) => {
 6694                    for (server_id, cached_hints) in cached_hints {
 6695                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6696                            cached_inlay_hints
 6697                                .entry(row_chunk.start..row_chunk.end)
 6698                                .or_insert_with(HashMap::default)
 6699                                .entry(server_id)
 6700                                .or_insert_with(Vec::new)
 6701                                .extend(cached_hints);
 6702                        }
 6703                    }
 6704                }
 6705                (Some(cached_hints), Some(fetched_hints)) => {
 6706                    hint_fetch_tasks.push((row_chunk, fetched_hints.clone()));
 6707                    for (server_id, cached_hints) in cached_hints {
 6708                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6709                            cached_inlay_hints
 6710                                .entry(row_chunk.start..row_chunk.end)
 6711                                .or_insert_with(HashMap::default)
 6712                                .entry(server_id)
 6713                                .or_insert_with(Vec::new)
 6714                                .extend(cached_hints);
 6715                        }
 6716                    }
 6717                }
 6718            }
 6719        }
 6720
 6721        let cached_chunk_data = cached_inlay_hints
 6722            .into_iter()
 6723            .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 6724            .collect();
 6725        if hint_fetch_tasks.is_empty() && ranges_to_query.is_empty() {
 6726            cached_chunk_data
 6727        } else {
 6728            if invalidate_cache {
 6729                lsp_data.inlay_hints.clear();
 6730            }
 6731
 6732            for (chunk, range_to_query) in ranges_to_query {
 6733                let next_hint_id = next_hint_id.clone();
 6734                let buffer = buffer.clone();
 6735                let new_inlay_hints = cx
 6736                    .spawn(async move |lsp_store, cx| {
 6737                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 6738                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 6739                        })?;
 6740                        new_fetch_task
 6741                            .await
 6742                            .and_then(|new_hints_by_server| {
 6743                                lsp_store.update(cx, |lsp_store, cx| {
 6744                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 6745                                    let update_cache = !lsp_data
 6746                                        .buffer_version
 6747                                        .changed_since(&buffer.read(cx).version());
 6748                                    new_hints_by_server
 6749                                        .into_iter()
 6750                                        .map(|(server_id, new_hints)| {
 6751                                            let new_hints = new_hints
 6752                                                .into_iter()
 6753                                                .map(|new_hint| {
 6754                                                    (
 6755                                                        InlayId::Hint(next_hint_id.fetch_add(
 6756                                                            1,
 6757                                                            atomic::Ordering::AcqRel,
 6758                                                        )),
 6759                                                        new_hint,
 6760                                                    )
 6761                                                })
 6762                                                .collect::<Vec<_>>();
 6763                                            if update_cache {
 6764                                                lsp_data.inlay_hints.insert_new_hints(
 6765                                                    chunk,
 6766                                                    server_id,
 6767                                                    new_hints.clone(),
 6768                                                );
 6769                                            }
 6770                                            (server_id, new_hints)
 6771                                        })
 6772                                        .collect()
 6773                                })
 6774                            })
 6775                            .map_err(Arc::new)
 6776                    })
 6777                    .shared();
 6778
 6779                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 6780                *fetch_task = Some(new_inlay_hints.clone());
 6781                hint_fetch_tasks.push((chunk, new_inlay_hints));
 6782            }
 6783
 6784            let mut combined_data = cached_chunk_data;
 6785            combined_data.extend(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 6786                (
 6787                    chunk.start..chunk.end,
 6788                    cx.spawn(async move |_, _| {
 6789                        hints_fetch.await.map_err(|e| {
 6790                            if e.error_code() != ErrorCode::Internal {
 6791                                anyhow!(e.error_code())
 6792                            } else {
 6793                                anyhow!("{e:#}")
 6794                            }
 6795                        })
 6796                    }),
 6797                )
 6798            }));
 6799            combined_data
 6800        }
 6801    }
 6802
 6803    fn fetch_inlay_hints(
 6804        &mut self,
 6805        for_server: Option<LanguageServerId>,
 6806        buffer: &Entity<Buffer>,
 6807        range: Range<Anchor>,
 6808        cx: &mut Context<Self>,
 6809    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 6810        let request = InlayHints {
 6811            range: range.clone(),
 6812        };
 6813        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6814            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6815                return Task::ready(Ok(HashMap::default()));
 6816            }
 6817            let request_task = upstream_client.request_lsp(
 6818                project_id,
 6819                for_server.map(|id| id.to_proto()),
 6820                LSP_REQUEST_TIMEOUT,
 6821                cx.background_executor().clone(),
 6822                request.to_proto(project_id, buffer.read(cx)),
 6823            );
 6824            let buffer = buffer.clone();
 6825            cx.spawn(async move |weak_lsp_store, cx| {
 6826                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6827                    return Ok(HashMap::default());
 6828                };
 6829                let Some(responses) = request_task.await? else {
 6830                    return Ok(HashMap::default());
 6831                };
 6832
 6833                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 6834                    let lsp_store = lsp_store.clone();
 6835                    let buffer = buffer.clone();
 6836                    let cx = cx.clone();
 6837                    let request = request.clone();
 6838                    async move {
 6839                        (
 6840                            LanguageServerId::from_proto(response.server_id),
 6841                            request
 6842                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6843                                .await,
 6844                        )
 6845                    }
 6846                }))
 6847                .await;
 6848
 6849                let mut has_errors = false;
 6850                let inlay_hints = inlay_hints
 6851                    .into_iter()
 6852                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 6853                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 6854                        Err(e) => {
 6855                            has_errors = true;
 6856                            log::error!("{e:#}");
 6857                            None
 6858                        }
 6859                    })
 6860                    .collect::<HashMap<_, _>>();
 6861                anyhow::ensure!(
 6862                    !has_errors || !inlay_hints.is_empty(),
 6863                    "Failed to fetch inlay hints"
 6864                );
 6865                Ok(inlay_hints)
 6866            })
 6867        } else {
 6868            let inlay_hints_task = match for_server {
 6869                Some(server_id) => {
 6870                    let server_task = self.request_lsp(
 6871                        buffer.clone(),
 6872                        LanguageServerToQuery::Other(server_id),
 6873                        request,
 6874                        cx,
 6875                    );
 6876                    cx.background_spawn(async move {
 6877                        let mut responses = Vec::new();
 6878                        match server_task.await {
 6879                            Ok(response) => responses.push((server_id, response)),
 6880                            Err(e) => log::error!(
 6881                                "Error handling response for inlay hints request: {e:#}"
 6882                            ),
 6883                        }
 6884                        responses
 6885                    })
 6886                }
 6887                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 6888            };
 6889            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 6890            cx.background_spawn(async move {
 6891                Ok(inlay_hints_task
 6892                    .await
 6893                    .into_iter()
 6894                    .map(|(server_id, mut new_hints)| {
 6895                        new_hints.retain(|hint| {
 6896                            hint.position.is_valid(&buffer_snapshot)
 6897                                && range.start.is_valid(&buffer_snapshot)
 6898                                && range.end.is_valid(&buffer_snapshot)
 6899                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 6900                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 6901                        });
 6902                        (server_id, new_hints)
 6903                    })
 6904                    .collect())
 6905            })
 6906        }
 6907    }
 6908
 6909    pub fn pull_diagnostics_for_buffer(
 6910        &mut self,
 6911        buffer: Entity<Buffer>,
 6912        cx: &mut Context<Self>,
 6913    ) -> Task<anyhow::Result<()>> {
 6914        let diagnostics = self.pull_diagnostics(buffer, cx);
 6915        cx.spawn(async move |lsp_store, cx| {
 6916            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 6917                return Ok(());
 6918            };
 6919            lsp_store.update(cx, |lsp_store, cx| {
 6920                if lsp_store.as_local().is_none() {
 6921                    return;
 6922                }
 6923
 6924                let mut unchanged_buffers = HashSet::default();
 6925                let mut changed_buffers = HashSet::default();
 6926                let server_diagnostics_updates = diagnostics
 6927                    .into_iter()
 6928                    .filter_map(|diagnostics_set| match diagnostics_set {
 6929                        LspPullDiagnostics::Response {
 6930                            server_id,
 6931                            uri,
 6932                            diagnostics,
 6933                        } => Some((server_id, uri, diagnostics)),
 6934                        LspPullDiagnostics::Default => None,
 6935                    })
 6936                    .fold(
 6937                        HashMap::default(),
 6938                        |mut acc, (server_id, uri, diagnostics)| {
 6939                            let (result_id, diagnostics) = match diagnostics {
 6940                                PulledDiagnostics::Unchanged { result_id } => {
 6941                                    unchanged_buffers.insert(uri.clone());
 6942                                    (Some(result_id), Vec::new())
 6943                                }
 6944                                PulledDiagnostics::Changed {
 6945                                    result_id,
 6946                                    diagnostics,
 6947                                } => {
 6948                                    changed_buffers.insert(uri.clone());
 6949                                    (result_id, diagnostics)
 6950                                }
 6951                            };
 6952                            let disk_based_sources = Cow::Owned(
 6953                                lsp_store
 6954                                    .language_server_adapter_for_id(server_id)
 6955                                    .as_ref()
 6956                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 6957                                    .unwrap_or(&[])
 6958                                    .to_vec(),
 6959                            );
 6960                            acc.entry(server_id).or_insert_with(Vec::new).push(
 6961                                DocumentDiagnosticsUpdate {
 6962                                    server_id,
 6963                                    diagnostics: lsp::PublishDiagnosticsParams {
 6964                                        uri,
 6965                                        diagnostics,
 6966                                        version: None,
 6967                                    },
 6968                                    result_id,
 6969                                    disk_based_sources,
 6970                                },
 6971                            );
 6972                            acc
 6973                        },
 6974                    );
 6975
 6976                for diagnostic_updates in server_diagnostics_updates.into_values() {
 6977                    lsp_store
 6978                        .merge_lsp_diagnostics(
 6979                            DiagnosticSourceKind::Pulled,
 6980                            diagnostic_updates,
 6981                            |buffer, old_diagnostic, cx| {
 6982                                File::from_dyn(buffer.file())
 6983                                    .and_then(|file| {
 6984                                        let abs_path = file.as_local()?.abs_path(cx);
 6985                                        lsp::Uri::from_file_path(abs_path).ok()
 6986                                    })
 6987                                    .is_none_or(|buffer_uri| {
 6988                                        unchanged_buffers.contains(&buffer_uri)
 6989                                            || match old_diagnostic.source_kind {
 6990                                                DiagnosticSourceKind::Pulled => {
 6991                                                    !changed_buffers.contains(&buffer_uri)
 6992                                                }
 6993                                                DiagnosticSourceKind::Other
 6994                                                | DiagnosticSourceKind::Pushed => true,
 6995                                            }
 6996                                    })
 6997                            },
 6998                            cx,
 6999                        )
 7000                        .log_err();
 7001                }
 7002            })
 7003        })
 7004    }
 7005
 7006    pub fn document_colors(
 7007        &mut self,
 7008        known_cache_version: Option<usize>,
 7009        buffer: Entity<Buffer>,
 7010        cx: &mut Context<Self>,
 7011    ) -> Option<DocumentColorTask> {
 7012        let version_queried_for = buffer.read(cx).version();
 7013        let buffer_id = buffer.read(cx).remote_id();
 7014
 7015        let current_language_servers = self.as_local().map(|local| {
 7016            local
 7017                .buffers_opened_in_servers
 7018                .get(&buffer_id)
 7019                .cloned()
 7020                .unwrap_or_default()
 7021        });
 7022
 7023        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7024            if let Some(cached_colors) = &lsp_data.document_colors {
 7025                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7026                    let has_different_servers =
 7027                        current_language_servers.is_some_and(|current_language_servers| {
 7028                            current_language_servers
 7029                                != cached_colors.colors.keys().copied().collect()
 7030                        });
 7031                    if !has_different_servers {
 7032                        let cache_version = cached_colors.cache_version;
 7033                        if Some(cache_version) == known_cache_version {
 7034                            return None;
 7035                        } else {
 7036                            return Some(
 7037                                Task::ready(Ok(DocumentColors {
 7038                                    colors: cached_colors
 7039                                        .colors
 7040                                        .values()
 7041                                        .flatten()
 7042                                        .cloned()
 7043                                        .collect(),
 7044                                    cache_version: Some(cache_version),
 7045                                }))
 7046                                .shared(),
 7047                            );
 7048                        }
 7049                    }
 7050                }
 7051            }
 7052        }
 7053
 7054        let color_lsp_data = self
 7055            .latest_lsp_data(&buffer, cx)
 7056            .document_colors
 7057            .get_or_insert_default();
 7058        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7059            && !version_queried_for.changed_since(updating_for)
 7060        {
 7061            return Some(running_update.clone());
 7062        }
 7063        let buffer_version_queried_for = version_queried_for.clone();
 7064        let new_task = cx
 7065            .spawn(async move |lsp_store, cx| {
 7066                cx.background_executor()
 7067                    .timer(Duration::from_millis(30))
 7068                    .await;
 7069                let fetched_colors = lsp_store
 7070                    .update(cx, |lsp_store, cx| {
 7071                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7072                    })?
 7073                    .await
 7074                    .context("fetching document colors")
 7075                    .map_err(Arc::new);
 7076                let fetched_colors = match fetched_colors {
 7077                    Ok(fetched_colors) => {
 7078                        if Some(true)
 7079                            == buffer
 7080                                .update(cx, |buffer, _| {
 7081                                    buffer.version() != buffer_version_queried_for
 7082                                })
 7083                                .ok()
 7084                        {
 7085                            return Ok(DocumentColors::default());
 7086                        }
 7087                        fetched_colors
 7088                    }
 7089                    Err(e) => {
 7090                        lsp_store
 7091                            .update(cx, |lsp_store, _| {
 7092                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7093                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7094                                        document_colors.colors_update = None;
 7095                                    }
 7096                                }
 7097                            })
 7098                            .ok();
 7099                        return Err(e);
 7100                    }
 7101                };
 7102
 7103                lsp_store
 7104                    .update(cx, |lsp_store, cx| {
 7105                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7106                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7107
 7108                        if let Some(fetched_colors) = fetched_colors {
 7109                            if lsp_data.buffer_version == buffer_version_queried_for {
 7110                                lsp_colors.colors.extend(fetched_colors);
 7111                                lsp_colors.cache_version += 1;
 7112                            } else if !lsp_data
 7113                                .buffer_version
 7114                                .changed_since(&buffer_version_queried_for)
 7115                            {
 7116                                lsp_data.buffer_version = buffer_version_queried_for;
 7117                                lsp_colors.colors = fetched_colors;
 7118                                lsp_colors.cache_version += 1;
 7119                            }
 7120                        }
 7121                        lsp_colors.colors_update = None;
 7122                        let colors = lsp_colors
 7123                            .colors
 7124                            .values()
 7125                            .flatten()
 7126                            .cloned()
 7127                            .collect::<HashSet<_>>();
 7128                        DocumentColors {
 7129                            colors,
 7130                            cache_version: Some(lsp_colors.cache_version),
 7131                        }
 7132                    })
 7133                    .map_err(Arc::new)
 7134            })
 7135            .shared();
 7136        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7137        Some(new_task)
 7138    }
 7139
 7140    fn fetch_document_colors_for_buffer(
 7141        &mut self,
 7142        buffer: &Entity<Buffer>,
 7143        cx: &mut Context<Self>,
 7144    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7145        if let Some((client, project_id)) = self.upstream_client() {
 7146            let request = GetDocumentColor {};
 7147            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7148                return Task::ready(Ok(None));
 7149            }
 7150
 7151            let request_task = client.request_lsp(
 7152                project_id,
 7153                None,
 7154                LSP_REQUEST_TIMEOUT,
 7155                cx.background_executor().clone(),
 7156                request.to_proto(project_id, buffer.read(cx)),
 7157            );
 7158            let buffer = buffer.clone();
 7159            cx.spawn(async move |lsp_store, cx| {
 7160                let Some(project) = lsp_store.upgrade() else {
 7161                    return Ok(None);
 7162                };
 7163                let colors = join_all(
 7164                    request_task
 7165                        .await
 7166                        .log_err()
 7167                        .flatten()
 7168                        .map(|response| response.payload)
 7169                        .unwrap_or_default()
 7170                        .into_iter()
 7171                        .map(|color_response| {
 7172                            let response = request.response_from_proto(
 7173                                color_response.response,
 7174                                project.clone(),
 7175                                buffer.clone(),
 7176                                cx.clone(),
 7177                            );
 7178                            async move {
 7179                                (
 7180                                    LanguageServerId::from_proto(color_response.server_id),
 7181                                    response.await.log_err().unwrap_or_default(),
 7182                                )
 7183                            }
 7184                        }),
 7185                )
 7186                .await
 7187                .into_iter()
 7188                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7189                    acc.entry(server_id)
 7190                        .or_insert_with(HashSet::default)
 7191                        .extend(colors);
 7192                    acc
 7193                });
 7194                Ok(Some(colors))
 7195            })
 7196        } else {
 7197            let document_colors_task =
 7198                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7199            cx.background_spawn(async move {
 7200                Ok(Some(
 7201                    document_colors_task
 7202                        .await
 7203                        .into_iter()
 7204                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7205                            acc.entry(server_id)
 7206                                .or_insert_with(HashSet::default)
 7207                                .extend(colors);
 7208                            acc
 7209                        })
 7210                        .into_iter()
 7211                        .collect(),
 7212                ))
 7213            })
 7214        }
 7215    }
 7216
 7217    pub fn signature_help<T: ToPointUtf16>(
 7218        &mut self,
 7219        buffer: &Entity<Buffer>,
 7220        position: T,
 7221        cx: &mut Context<Self>,
 7222    ) -> Task<Option<Vec<SignatureHelp>>> {
 7223        let position = position.to_point_utf16(buffer.read(cx));
 7224
 7225        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7226            let request = GetSignatureHelp { position };
 7227            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7228                return Task::ready(None);
 7229            }
 7230            let request_task = client.request_lsp(
 7231                upstream_project_id,
 7232                None,
 7233                LSP_REQUEST_TIMEOUT,
 7234                cx.background_executor().clone(),
 7235                request.to_proto(upstream_project_id, buffer.read(cx)),
 7236            );
 7237            let buffer = buffer.clone();
 7238            cx.spawn(async move |weak_project, cx| {
 7239                let project = weak_project.upgrade()?;
 7240                let signatures = join_all(
 7241                    request_task
 7242                        .await
 7243                        .log_err()
 7244                        .flatten()
 7245                        .map(|response| response.payload)
 7246                        .unwrap_or_default()
 7247                        .into_iter()
 7248                        .map(|response| {
 7249                            let response = GetSignatureHelp { position }.response_from_proto(
 7250                                response.response,
 7251                                project.clone(),
 7252                                buffer.clone(),
 7253                                cx.clone(),
 7254                            );
 7255                            async move { response.await.log_err().flatten() }
 7256                        }),
 7257                )
 7258                .await
 7259                .into_iter()
 7260                .flatten()
 7261                .collect();
 7262                Some(signatures)
 7263            })
 7264        } else {
 7265            let all_actions_task = self.request_multiple_lsp_locally(
 7266                buffer,
 7267                Some(position),
 7268                GetSignatureHelp { position },
 7269                cx,
 7270            );
 7271            cx.background_spawn(async move {
 7272                Some(
 7273                    all_actions_task
 7274                        .await
 7275                        .into_iter()
 7276                        .flat_map(|(_, actions)| actions)
 7277                        .collect::<Vec<_>>(),
 7278                )
 7279            })
 7280        }
 7281    }
 7282
 7283    pub fn hover(
 7284        &mut self,
 7285        buffer: &Entity<Buffer>,
 7286        position: PointUtf16,
 7287        cx: &mut Context<Self>,
 7288    ) -> Task<Option<Vec<Hover>>> {
 7289        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7290            let request = GetHover { position };
 7291            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7292                return Task::ready(None);
 7293            }
 7294            let request_task = client.request_lsp(
 7295                upstream_project_id,
 7296                None,
 7297                LSP_REQUEST_TIMEOUT,
 7298                cx.background_executor().clone(),
 7299                request.to_proto(upstream_project_id, buffer.read(cx)),
 7300            );
 7301            let buffer = buffer.clone();
 7302            cx.spawn(async move |weak_project, cx| {
 7303                let project = weak_project.upgrade()?;
 7304                let hovers = join_all(
 7305                    request_task
 7306                        .await
 7307                        .log_err()
 7308                        .flatten()
 7309                        .map(|response| response.payload)
 7310                        .unwrap_or_default()
 7311                        .into_iter()
 7312                        .map(|response| {
 7313                            let response = GetHover { position }.response_from_proto(
 7314                                response.response,
 7315                                project.clone(),
 7316                                buffer.clone(),
 7317                                cx.clone(),
 7318                            );
 7319                            async move {
 7320                                response
 7321                                    .await
 7322                                    .log_err()
 7323                                    .flatten()
 7324                                    .and_then(remove_empty_hover_blocks)
 7325                            }
 7326                        }),
 7327                )
 7328                .await
 7329                .into_iter()
 7330                .flatten()
 7331                .collect();
 7332                Some(hovers)
 7333            })
 7334        } else {
 7335            let all_actions_task = self.request_multiple_lsp_locally(
 7336                buffer,
 7337                Some(position),
 7338                GetHover { position },
 7339                cx,
 7340            );
 7341            cx.background_spawn(async move {
 7342                Some(
 7343                    all_actions_task
 7344                        .await
 7345                        .into_iter()
 7346                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7347                        .collect::<Vec<Hover>>(),
 7348                )
 7349            })
 7350        }
 7351    }
 7352
 7353    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7354        let language_registry = self.languages.clone();
 7355
 7356        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7357            let request = upstream_client.request(proto::GetProjectSymbols {
 7358                project_id: *project_id,
 7359                query: query.to_string(),
 7360            });
 7361            cx.foreground_executor().spawn(async move {
 7362                let response = request.await?;
 7363                let mut symbols = Vec::new();
 7364                let core_symbols = response
 7365                    .symbols
 7366                    .into_iter()
 7367                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7368                    .collect::<Vec<_>>();
 7369                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7370                    .await;
 7371                Ok(symbols)
 7372            })
 7373        } else if let Some(local) = self.as_local() {
 7374            struct WorkspaceSymbolsResult {
 7375                server_id: LanguageServerId,
 7376                lsp_adapter: Arc<CachedLspAdapter>,
 7377                worktree: WeakEntity<Worktree>,
 7378                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7379            }
 7380
 7381            let mut requests = Vec::new();
 7382            let mut requested_servers = BTreeSet::new();
 7383            for (seed, state) in local.language_server_ids.iter() {
 7384                let Some(worktree_handle) = self
 7385                    .worktree_store
 7386                    .read(cx)
 7387                    .worktree_for_id(seed.worktree_id, cx)
 7388                else {
 7389                    continue;
 7390                };
 7391                let worktree = worktree_handle.read(cx);
 7392                if !worktree.is_visible() {
 7393                    continue;
 7394                }
 7395
 7396                if !requested_servers.insert(state.id) {
 7397                    continue;
 7398                }
 7399
 7400                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7401                    Some(LanguageServerState::Running {
 7402                        adapter, server, ..
 7403                    }) => (adapter.clone(), server),
 7404
 7405                    _ => continue,
 7406                };
 7407                let supports_workspace_symbol_request =
 7408                    match server.capabilities().workspace_symbol_provider {
 7409                        Some(OneOf::Left(supported)) => supported,
 7410                        Some(OneOf::Right(_)) => true,
 7411                        None => false,
 7412                    };
 7413                if !supports_workspace_symbol_request {
 7414                    continue;
 7415                }
 7416                let worktree_handle = worktree_handle.clone();
 7417                let server_id = server.server_id();
 7418                requests.push(
 7419                        server
 7420                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7421                                lsp::WorkspaceSymbolParams {
 7422                                    query: query.to_string(),
 7423                                    ..Default::default()
 7424                                },
 7425                            )
 7426                            .map(move |response| {
 7427                                let lsp_symbols = response.into_response()
 7428                                    .context("workspace symbols request")
 7429                                    .log_err()
 7430                                    .flatten()
 7431                                    .map(|symbol_response| match symbol_response {
 7432                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7433                                            flat_responses.into_iter().map(|lsp_symbol| {
 7434                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7435                                            }).collect::<Vec<_>>()
 7436                                        }
 7437                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7438                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7439                                                let location = match lsp_symbol.location {
 7440                                                    OneOf::Left(location) => location,
 7441                                                    OneOf::Right(_) => {
 7442                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7443                                                        return None
 7444                                                    }
 7445                                                };
 7446                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7447                                            }).collect::<Vec<_>>()
 7448                                        }
 7449                                    }).unwrap_or_default();
 7450
 7451                                WorkspaceSymbolsResult {
 7452                                    server_id,
 7453                                    lsp_adapter,
 7454                                    worktree: worktree_handle.downgrade(),
 7455                                    lsp_symbols,
 7456                                }
 7457                            }),
 7458                    );
 7459            }
 7460
 7461            cx.spawn(async move |this, cx| {
 7462                let responses = futures::future::join_all(requests).await;
 7463                let this = match this.upgrade() {
 7464                    Some(this) => this,
 7465                    None => return Ok(Vec::new()),
 7466                };
 7467
 7468                let mut symbols = Vec::new();
 7469                for result in responses {
 7470                    let core_symbols = this.update(cx, |this, cx| {
 7471                        result
 7472                            .lsp_symbols
 7473                            .into_iter()
 7474                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7475                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7476                                let source_worktree = result.worktree.upgrade()?;
 7477                                let source_worktree_id = source_worktree.read(cx).id();
 7478
 7479                                let path = if let Some((tree, rel_path)) =
 7480                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7481                                {
 7482                                    let worktree_id = tree.read(cx).id();
 7483                                    SymbolLocation::InProject(ProjectPath {
 7484                                        worktree_id,
 7485                                        path: rel_path,
 7486                                    })
 7487                                } else {
 7488                                    SymbolLocation::OutsideProject {
 7489                                        signature: this.symbol_signature(&abs_path),
 7490                                        abs_path: abs_path.into(),
 7491                                    }
 7492                                };
 7493
 7494                                Some(CoreSymbol {
 7495                                    source_language_server_id: result.server_id,
 7496                                    language_server_name: result.lsp_adapter.name.clone(),
 7497                                    source_worktree_id,
 7498                                    path,
 7499                                    kind: symbol_kind,
 7500                                    name: symbol_name,
 7501                                    range: range_from_lsp(symbol_location.range),
 7502                                })
 7503                            })
 7504                            .collect()
 7505                    })?;
 7506
 7507                    populate_labels_for_symbols(
 7508                        core_symbols,
 7509                        &language_registry,
 7510                        Some(result.lsp_adapter),
 7511                        &mut symbols,
 7512                    )
 7513                    .await;
 7514                }
 7515
 7516                Ok(symbols)
 7517            })
 7518        } else {
 7519            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7520        }
 7521    }
 7522
 7523    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7524        let mut summary = DiagnosticSummary::default();
 7525        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7526            summary.error_count += path_summary.error_count;
 7527            summary.warning_count += path_summary.warning_count;
 7528        }
 7529        summary
 7530    }
 7531
 7532    /// Returns the diagnostic summary for a specific project path.
 7533    pub fn diagnostic_summary_for_path(
 7534        &self,
 7535        project_path: &ProjectPath,
 7536        _: &App,
 7537    ) -> DiagnosticSummary {
 7538        if let Some(summaries) = self
 7539            .diagnostic_summaries
 7540            .get(&project_path.worktree_id)
 7541            .and_then(|map| map.get(&project_path.path))
 7542        {
 7543            let (error_count, warning_count) = summaries.iter().fold(
 7544                (0, 0),
 7545                |(error_count, warning_count), (_language_server_id, summary)| {
 7546                    (
 7547                        error_count + summary.error_count,
 7548                        warning_count + summary.warning_count,
 7549                    )
 7550                },
 7551            );
 7552
 7553            DiagnosticSummary {
 7554                error_count,
 7555                warning_count,
 7556            }
 7557        } else {
 7558            DiagnosticSummary::default()
 7559        }
 7560    }
 7561
 7562    pub fn diagnostic_summaries<'a>(
 7563        &'a self,
 7564        include_ignored: bool,
 7565        cx: &'a App,
 7566    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7567        self.worktree_store
 7568            .read(cx)
 7569            .visible_worktrees(cx)
 7570            .filter_map(|worktree| {
 7571                let worktree = worktree.read(cx);
 7572                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7573            })
 7574            .flat_map(move |(worktree, summaries)| {
 7575                let worktree_id = worktree.id();
 7576                summaries
 7577                    .iter()
 7578                    .filter(move |(path, _)| {
 7579                        include_ignored
 7580                            || worktree
 7581                                .entry_for_path(path.as_ref())
 7582                                .is_some_and(|entry| !entry.is_ignored)
 7583                    })
 7584                    .flat_map(move |(path, summaries)| {
 7585                        summaries.iter().map(move |(server_id, summary)| {
 7586                            (
 7587                                ProjectPath {
 7588                                    worktree_id,
 7589                                    path: path.clone(),
 7590                                },
 7591                                *server_id,
 7592                                *summary,
 7593                            )
 7594                        })
 7595                    })
 7596            })
 7597    }
 7598
 7599    pub fn on_buffer_edited(
 7600        &mut self,
 7601        buffer: Entity<Buffer>,
 7602        cx: &mut Context<Self>,
 7603    ) -> Option<()> {
 7604        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7605            Some(
 7606                self.as_local()?
 7607                    .language_servers_for_buffer(buffer, cx)
 7608                    .map(|i| i.1.clone())
 7609                    .collect(),
 7610            )
 7611        })?;
 7612
 7613        let buffer = buffer.read(cx);
 7614        let file = File::from_dyn(buffer.file())?;
 7615        let abs_path = file.as_local()?.abs_path(cx);
 7616        let uri = lsp::Uri::from_file_path(abs_path).unwrap();
 7617        let next_snapshot = buffer.text_snapshot();
 7618        for language_server in language_servers {
 7619            let language_server = language_server.clone();
 7620
 7621            let buffer_snapshots = self
 7622                .as_local_mut()
 7623                .unwrap()
 7624                .buffer_snapshots
 7625                .get_mut(&buffer.remote_id())
 7626                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7627            let previous_snapshot = buffer_snapshots.last()?;
 7628
 7629            let build_incremental_change = || {
 7630                buffer
 7631                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7632                        previous_snapshot.snapshot.version(),
 7633                    )
 7634                    .map(|edit| {
 7635                        let edit_start = edit.new.start.0;
 7636                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7637                        let new_text = next_snapshot
 7638                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7639                            .collect();
 7640                        lsp::TextDocumentContentChangeEvent {
 7641                            range: Some(lsp::Range::new(
 7642                                point_to_lsp(edit_start),
 7643                                point_to_lsp(edit_end),
 7644                            )),
 7645                            range_length: None,
 7646                            text: new_text,
 7647                        }
 7648                    })
 7649                    .collect()
 7650            };
 7651
 7652            let document_sync_kind = language_server
 7653                .capabilities()
 7654                .text_document_sync
 7655                .as_ref()
 7656                .and_then(|sync| match sync {
 7657                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7658                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7659                });
 7660
 7661            let content_changes: Vec<_> = match document_sync_kind {
 7662                Some(lsp::TextDocumentSyncKind::FULL) => {
 7663                    vec![lsp::TextDocumentContentChangeEvent {
 7664                        range: None,
 7665                        range_length: None,
 7666                        text: next_snapshot.text(),
 7667                    }]
 7668                }
 7669                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7670                _ => {
 7671                    #[cfg(any(test, feature = "test-support"))]
 7672                    {
 7673                        build_incremental_change()
 7674                    }
 7675
 7676                    #[cfg(not(any(test, feature = "test-support")))]
 7677                    {
 7678                        continue;
 7679                    }
 7680                }
 7681            };
 7682
 7683            let next_version = previous_snapshot.version + 1;
 7684            buffer_snapshots.push(LspBufferSnapshot {
 7685                version: next_version,
 7686                snapshot: next_snapshot.clone(),
 7687            });
 7688
 7689            language_server
 7690                .notify::<lsp::notification::DidChangeTextDocument>(
 7691                    lsp::DidChangeTextDocumentParams {
 7692                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7693                            uri.clone(),
 7694                            next_version,
 7695                        ),
 7696                        content_changes,
 7697                    },
 7698                )
 7699                .ok();
 7700            self.pull_workspace_diagnostics(language_server.server_id());
 7701        }
 7702
 7703        None
 7704    }
 7705
 7706    pub fn on_buffer_saved(
 7707        &mut self,
 7708        buffer: Entity<Buffer>,
 7709        cx: &mut Context<Self>,
 7710    ) -> Option<()> {
 7711        let file = File::from_dyn(buffer.read(cx).file())?;
 7712        let worktree_id = file.worktree_id(cx);
 7713        let abs_path = file.as_local()?.abs_path(cx);
 7714        let text_document = lsp::TextDocumentIdentifier {
 7715            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7716        };
 7717        let local = self.as_local()?;
 7718
 7719        for server in local.language_servers_for_worktree(worktree_id) {
 7720            if let Some(include_text) = include_text(server.as_ref()) {
 7721                let text = if include_text {
 7722                    Some(buffer.read(cx).text())
 7723                } else {
 7724                    None
 7725                };
 7726                server
 7727                    .notify::<lsp::notification::DidSaveTextDocument>(
 7728                        lsp::DidSaveTextDocumentParams {
 7729                            text_document: text_document.clone(),
 7730                            text,
 7731                        },
 7732                    )
 7733                    .ok();
 7734            }
 7735        }
 7736
 7737        let language_servers = buffer.update(cx, |buffer, cx| {
 7738            local.language_server_ids_for_buffer(buffer, cx)
 7739        });
 7740        for language_server_id in language_servers {
 7741            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7742        }
 7743
 7744        None
 7745    }
 7746
 7747    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 7748        maybe!(async move {
 7749            let mut refreshed_servers = HashSet::default();
 7750            let servers = lsp_store
 7751                .update(cx, |lsp_store, cx| {
 7752                    let local = lsp_store.as_local()?;
 7753
 7754                    let servers = local
 7755                        .language_server_ids
 7756                        .iter()
 7757                        .filter_map(|(seed, state)| {
 7758                            let worktree = lsp_store
 7759                                .worktree_store
 7760                                .read(cx)
 7761                                .worktree_for_id(seed.worktree_id, cx);
 7762                            let delegate: Arc<dyn LspAdapterDelegate> =
 7763                                worktree.map(|worktree| {
 7764                                    LocalLspAdapterDelegate::new(
 7765                                        local.languages.clone(),
 7766                                        &local.environment,
 7767                                        cx.weak_entity(),
 7768                                        &worktree,
 7769                                        local.http_client.clone(),
 7770                                        local.fs.clone(),
 7771                                        cx,
 7772                                    )
 7773                                })?;
 7774                            let server_id = state.id;
 7775
 7776                            let states = local.language_servers.get(&server_id)?;
 7777
 7778                            match states {
 7779                                LanguageServerState::Starting { .. } => None,
 7780                                LanguageServerState::Running {
 7781                                    adapter, server, ..
 7782                                } => {
 7783                                    let adapter = adapter.clone();
 7784                                    let server = server.clone();
 7785                                    refreshed_servers.insert(server.name());
 7786                                    let toolchain = seed.toolchain.clone();
 7787                                    Some(cx.spawn(async move |_, cx| {
 7788                                        let settings =
 7789                                            LocalLspStore::workspace_configuration_for_adapter(
 7790                                                adapter.adapter.clone(),
 7791                                                &delegate,
 7792                                                toolchain,
 7793                                                cx,
 7794                                            )
 7795                                            .await
 7796                                            .ok()?;
 7797                                        server
 7798                                            .notify::<lsp::notification::DidChangeConfiguration>(
 7799                                                lsp::DidChangeConfigurationParams { settings },
 7800                                            )
 7801                                            .ok()?;
 7802                                        Some(())
 7803                                    }))
 7804                                }
 7805                            }
 7806                        })
 7807                        .collect::<Vec<_>>();
 7808
 7809                    Some(servers)
 7810                })
 7811                .ok()
 7812                .flatten()?;
 7813
 7814            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 7815            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 7816            // to stop and unregister its language server wrapper.
 7817            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 7818            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 7819            let _: Vec<Option<()>> = join_all(servers).await;
 7820
 7821            Some(())
 7822        })
 7823        .await;
 7824    }
 7825
 7826    fn maintain_workspace_config(
 7827        external_refresh_requests: watch::Receiver<()>,
 7828        cx: &mut Context<Self>,
 7829    ) -> Task<Result<()>> {
 7830        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 7831        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 7832
 7833        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 7834            *settings_changed_tx.borrow_mut() = ();
 7835        });
 7836
 7837        let mut joint_future =
 7838            futures::stream::select(settings_changed_rx, external_refresh_requests);
 7839        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 7840        // - 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).
 7841        // - 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.
 7842        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 7843        // - 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,
 7844        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 7845        cx.spawn(async move |this, cx| {
 7846            while let Some(()) = joint_future.next().await {
 7847                this.update(cx, |this, cx| {
 7848                    this.refresh_server_tree(cx);
 7849                })
 7850                .ok();
 7851
 7852                Self::refresh_workspace_configurations(&this, cx).await;
 7853            }
 7854
 7855            drop(settings_observation);
 7856            anyhow::Ok(())
 7857        })
 7858    }
 7859
 7860    pub fn language_servers_for_local_buffer<'a>(
 7861        &'a self,
 7862        buffer: &Buffer,
 7863        cx: &mut App,
 7864    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7865        let local = self.as_local();
 7866        let language_server_ids = local
 7867            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 7868            .unwrap_or_default();
 7869
 7870        language_server_ids
 7871            .into_iter()
 7872            .filter_map(
 7873                move |server_id| match local?.language_servers.get(&server_id)? {
 7874                    LanguageServerState::Running {
 7875                        adapter, server, ..
 7876                    } => Some((adapter, server)),
 7877                    _ => None,
 7878                },
 7879            )
 7880    }
 7881
 7882    pub fn language_server_for_local_buffer<'a>(
 7883        &'a self,
 7884        buffer: &'a Buffer,
 7885        server_id: LanguageServerId,
 7886        cx: &'a mut App,
 7887    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7888        self.as_local()?
 7889            .language_servers_for_buffer(buffer, cx)
 7890            .find(|(_, s)| s.server_id() == server_id)
 7891    }
 7892
 7893    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 7894        self.diagnostic_summaries.remove(&id_to_remove);
 7895        if let Some(local) = self.as_local_mut() {
 7896            let to_remove = local.remove_worktree(id_to_remove, cx);
 7897            for server in to_remove {
 7898                self.language_server_statuses.remove(&server);
 7899            }
 7900        }
 7901    }
 7902
 7903    pub fn shared(
 7904        &mut self,
 7905        project_id: u64,
 7906        downstream_client: AnyProtoClient,
 7907        _: &mut Context<Self>,
 7908    ) {
 7909        self.downstream_client = Some((downstream_client.clone(), project_id));
 7910
 7911        for (server_id, status) in &self.language_server_statuses {
 7912            if let Some(server) = self.language_server_for_id(*server_id) {
 7913                downstream_client
 7914                    .send(proto::StartLanguageServer {
 7915                        project_id,
 7916                        server: Some(proto::LanguageServer {
 7917                            id: server_id.to_proto(),
 7918                            name: status.name.to_string(),
 7919                            worktree_id: status.worktree.map(|id| id.to_proto()),
 7920                        }),
 7921                        capabilities: serde_json::to_string(&server.capabilities())
 7922                            .expect("serializing server LSP capabilities"),
 7923                    })
 7924                    .log_err();
 7925            }
 7926        }
 7927    }
 7928
 7929    pub fn disconnected_from_host(&mut self) {
 7930        self.downstream_client.take();
 7931    }
 7932
 7933    pub fn disconnected_from_ssh_remote(&mut self) {
 7934        if let LspStoreMode::Remote(RemoteLspStore {
 7935            upstream_client, ..
 7936        }) = &mut self.mode
 7937        {
 7938            upstream_client.take();
 7939        }
 7940    }
 7941
 7942    pub(crate) fn set_language_server_statuses_from_proto(
 7943        &mut self,
 7944        project: WeakEntity<Project>,
 7945        language_servers: Vec<proto::LanguageServer>,
 7946        server_capabilities: Vec<String>,
 7947        cx: &mut Context<Self>,
 7948    ) {
 7949        let lsp_logs = cx
 7950            .try_global::<GlobalLogStore>()
 7951            .map(|lsp_store| lsp_store.0.clone());
 7952
 7953        self.language_server_statuses = language_servers
 7954            .into_iter()
 7955            .zip(server_capabilities)
 7956            .map(|(server, server_capabilities)| {
 7957                let server_id = LanguageServerId(server.id as usize);
 7958                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 7959                    self.lsp_server_capabilities
 7960                        .insert(server_id, server_capabilities);
 7961                }
 7962
 7963                let name = LanguageServerName::from_proto(server.name);
 7964                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 7965
 7966                if let Some(lsp_logs) = &lsp_logs {
 7967                    lsp_logs.update(cx, |lsp_logs, cx| {
 7968                        lsp_logs.add_language_server(
 7969                            // Only remote clients get their language servers set from proto
 7970                            LanguageServerKind::Remote {
 7971                                project: project.clone(),
 7972                            },
 7973                            server_id,
 7974                            Some(name.clone()),
 7975                            worktree,
 7976                            None,
 7977                            cx,
 7978                        );
 7979                    });
 7980                }
 7981
 7982                (
 7983                    server_id,
 7984                    LanguageServerStatus {
 7985                        name,
 7986                        pending_work: Default::default(),
 7987                        has_pending_diagnostic_updates: false,
 7988                        progress_tokens: Default::default(),
 7989                        worktree,
 7990                    },
 7991                )
 7992            })
 7993            .collect();
 7994    }
 7995
 7996    #[cfg(test)]
 7997    pub fn update_diagnostic_entries(
 7998        &mut self,
 7999        server_id: LanguageServerId,
 8000        abs_path: PathBuf,
 8001        result_id: Option<String>,
 8002        version: Option<i32>,
 8003        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8004        cx: &mut Context<Self>,
 8005    ) -> anyhow::Result<()> {
 8006        self.merge_diagnostic_entries(
 8007            vec![DocumentDiagnosticsUpdate {
 8008                diagnostics: DocumentDiagnostics {
 8009                    diagnostics,
 8010                    document_abs_path: abs_path,
 8011                    version,
 8012                },
 8013                result_id,
 8014                server_id,
 8015                disk_based_sources: Cow::Borrowed(&[]),
 8016            }],
 8017            |_, _, _| false,
 8018            cx,
 8019        )?;
 8020        Ok(())
 8021    }
 8022
 8023    pub fn merge_diagnostic_entries<'a>(
 8024        &mut self,
 8025        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8026        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
 8027        cx: &mut Context<Self>,
 8028    ) -> anyhow::Result<()> {
 8029        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8030        let mut updated_diagnostics_paths = HashMap::default();
 8031        for mut update in diagnostic_updates {
 8032            let abs_path = &update.diagnostics.document_abs_path;
 8033            let server_id = update.server_id;
 8034            let Some((worktree, relative_path)) =
 8035                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8036            else {
 8037                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8038                return Ok(());
 8039            };
 8040
 8041            let worktree_id = worktree.read(cx).id();
 8042            let project_path = ProjectPath {
 8043                worktree_id,
 8044                path: relative_path,
 8045            };
 8046
 8047            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8048                let snapshot = buffer_handle.read(cx).snapshot();
 8049                let buffer = buffer_handle.read(cx);
 8050                let reused_diagnostics = buffer
 8051                    .buffer_diagnostics(Some(server_id))
 8052                    .iter()
 8053                    .filter(|v| merge(buffer, &v.diagnostic, cx))
 8054                    .map(|v| {
 8055                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8056                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8057                        DiagnosticEntry {
 8058                            range: start..end,
 8059                            diagnostic: v.diagnostic.clone(),
 8060                        }
 8061                    })
 8062                    .collect::<Vec<_>>();
 8063
 8064                self.as_local_mut()
 8065                    .context("cannot merge diagnostics on a remote LspStore")?
 8066                    .update_buffer_diagnostics(
 8067                        &buffer_handle,
 8068                        server_id,
 8069                        update.result_id,
 8070                        update.diagnostics.version,
 8071                        update.diagnostics.diagnostics.clone(),
 8072                        reused_diagnostics.clone(),
 8073                        cx,
 8074                    )?;
 8075
 8076                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8077            }
 8078
 8079            let updated = worktree.update(cx, |worktree, cx| {
 8080                self.update_worktree_diagnostics(
 8081                    worktree.id(),
 8082                    server_id,
 8083                    project_path.path.clone(),
 8084                    update.diagnostics.diagnostics,
 8085                    cx,
 8086                )
 8087            })?;
 8088            match updated {
 8089                ControlFlow::Continue(new_summary) => {
 8090                    if let Some((project_id, new_summary)) = new_summary {
 8091                        match &mut diagnostics_summary {
 8092                            Some(diagnostics_summary) => {
 8093                                diagnostics_summary
 8094                                    .more_summaries
 8095                                    .push(proto::DiagnosticSummary {
 8096                                        path: project_path.path.as_ref().to_proto(),
 8097                                        language_server_id: server_id.0 as u64,
 8098                                        error_count: new_summary.error_count,
 8099                                        warning_count: new_summary.warning_count,
 8100                                    })
 8101                            }
 8102                            None => {
 8103                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8104                                    project_id,
 8105                                    worktree_id: worktree_id.to_proto(),
 8106                                    summary: Some(proto::DiagnosticSummary {
 8107                                        path: project_path.path.as_ref().to_proto(),
 8108                                        language_server_id: server_id.0 as u64,
 8109                                        error_count: new_summary.error_count,
 8110                                        warning_count: new_summary.warning_count,
 8111                                    }),
 8112                                    more_summaries: Vec::new(),
 8113                                })
 8114                            }
 8115                        }
 8116                    }
 8117                    updated_diagnostics_paths
 8118                        .entry(server_id)
 8119                        .or_insert_with(Vec::new)
 8120                        .push(project_path);
 8121                }
 8122                ControlFlow::Break(()) => {}
 8123            }
 8124        }
 8125
 8126        if let Some((diagnostics_summary, (downstream_client, _))) =
 8127            diagnostics_summary.zip(self.downstream_client.as_ref())
 8128        {
 8129            downstream_client.send(diagnostics_summary).log_err();
 8130        }
 8131        for (server_id, paths) in updated_diagnostics_paths {
 8132            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8133        }
 8134        Ok(())
 8135    }
 8136
 8137    fn update_worktree_diagnostics(
 8138        &mut self,
 8139        worktree_id: WorktreeId,
 8140        server_id: LanguageServerId,
 8141        path_in_worktree: Arc<RelPath>,
 8142        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8143        _: &mut Context<Worktree>,
 8144    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8145        let local = match &mut self.mode {
 8146            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8147            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8148        };
 8149
 8150        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8151        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8152        let summaries_by_server_id = summaries_for_tree
 8153            .entry(path_in_worktree.clone())
 8154            .or_default();
 8155
 8156        let old_summary = summaries_by_server_id
 8157            .remove(&server_id)
 8158            .unwrap_or_default();
 8159
 8160        let new_summary = DiagnosticSummary::new(&diagnostics);
 8161        if new_summary.is_empty() {
 8162            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8163            {
 8164                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8165                    diagnostics_by_server_id.remove(ix);
 8166                }
 8167                if diagnostics_by_server_id.is_empty() {
 8168                    diagnostics_for_tree.remove(&path_in_worktree);
 8169                }
 8170            }
 8171        } else {
 8172            summaries_by_server_id.insert(server_id, new_summary);
 8173            let diagnostics_by_server_id = diagnostics_for_tree
 8174                .entry(path_in_worktree.clone())
 8175                .or_default();
 8176            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8177                Ok(ix) => {
 8178                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8179                }
 8180                Err(ix) => {
 8181                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8182                }
 8183            }
 8184        }
 8185
 8186        if !old_summary.is_empty() || !new_summary.is_empty() {
 8187            if let Some((_, project_id)) = &self.downstream_client {
 8188                Ok(ControlFlow::Continue(Some((
 8189                    *project_id,
 8190                    proto::DiagnosticSummary {
 8191                        path: path_in_worktree.to_proto(),
 8192                        language_server_id: server_id.0 as u64,
 8193                        error_count: new_summary.error_count as u32,
 8194                        warning_count: new_summary.warning_count as u32,
 8195                    },
 8196                ))))
 8197            } else {
 8198                Ok(ControlFlow::Continue(None))
 8199            }
 8200        } else {
 8201            Ok(ControlFlow::Break(()))
 8202        }
 8203    }
 8204
 8205    pub fn open_buffer_for_symbol(
 8206        &mut self,
 8207        symbol: &Symbol,
 8208        cx: &mut Context<Self>,
 8209    ) -> Task<Result<Entity<Buffer>>> {
 8210        if let Some((client, project_id)) = self.upstream_client() {
 8211            let request = client.request(proto::OpenBufferForSymbol {
 8212                project_id,
 8213                symbol: Some(Self::serialize_symbol(symbol)),
 8214            });
 8215            cx.spawn(async move |this, cx| {
 8216                let response = request.await?;
 8217                let buffer_id = BufferId::new(response.buffer_id)?;
 8218                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8219                    .await
 8220            })
 8221        } else if let Some(local) = self.as_local() {
 8222            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8223                seed.worktree_id == symbol.source_worktree_id
 8224                    && state.id == symbol.source_language_server_id
 8225                    && symbol.language_server_name == seed.name
 8226            });
 8227            if !is_valid {
 8228                return Task::ready(Err(anyhow!(
 8229                    "language server for worktree and language not found"
 8230                )));
 8231            };
 8232
 8233            let symbol_abs_path = match &symbol.path {
 8234                SymbolLocation::InProject(project_path) => self
 8235                    .worktree_store
 8236                    .read(cx)
 8237                    .absolutize(&project_path, cx)
 8238                    .context("no such worktree"),
 8239                SymbolLocation::OutsideProject {
 8240                    abs_path,
 8241                    signature: _,
 8242                } => Ok(abs_path.to_path_buf()),
 8243            };
 8244            let symbol_abs_path = match symbol_abs_path {
 8245                Ok(abs_path) => abs_path,
 8246                Err(err) => return Task::ready(Err(err)),
 8247            };
 8248            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8249                uri
 8250            } else {
 8251                return Task::ready(Err(anyhow!("invalid symbol path")));
 8252            };
 8253
 8254            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8255        } else {
 8256            Task::ready(Err(anyhow!("no upstream client or local store")))
 8257        }
 8258    }
 8259
 8260    pub(crate) fn open_local_buffer_via_lsp(
 8261        &mut self,
 8262        abs_path: lsp::Uri,
 8263        language_server_id: LanguageServerId,
 8264        cx: &mut Context<Self>,
 8265    ) -> Task<Result<Entity<Buffer>>> {
 8266        cx.spawn(async move |lsp_store, cx| {
 8267            // Escape percent-encoded string.
 8268            let current_scheme = abs_path.scheme().to_owned();
 8269            // Uri is immutable, so we can't modify the scheme
 8270
 8271            let abs_path = abs_path
 8272                .to_file_path()
 8273                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8274            let p = abs_path.clone();
 8275            let yarn_worktree = lsp_store
 8276                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8277                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8278                        cx.spawn(async move |this, cx| {
 8279                            let t = this
 8280                                .update(cx, |this, cx| this.process_path(&p, ¤t_scheme, cx))
 8281                                .ok()?;
 8282                            t.await
 8283                        })
 8284                    }),
 8285                    None => Task::ready(None),
 8286                })?
 8287                .await;
 8288            let (worktree_root_target, known_relative_path) =
 8289                if let Some((zip_root, relative_path)) = yarn_worktree {
 8290                    (zip_root, Some(relative_path))
 8291                } else {
 8292                    (Arc::<Path>::from(abs_path.as_path()), None)
 8293                };
 8294            let (worktree, relative_path) = if let Some(result) =
 8295                lsp_store.update(cx, |lsp_store, cx| {
 8296                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8297                        worktree_store.find_worktree(&worktree_root_target, cx)
 8298                    })
 8299                })? {
 8300                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8301                (result.0, relative_path)
 8302            } else {
 8303                let worktree = lsp_store
 8304                    .update(cx, |lsp_store, cx| {
 8305                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8306                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8307                        })
 8308                    })?
 8309                    .await?;
 8310                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8311                    lsp_store
 8312                        .update(cx, |lsp_store, cx| {
 8313                            if let Some(local) = lsp_store.as_local_mut() {
 8314                                local.register_language_server_for_invisible_worktree(
 8315                                    &worktree,
 8316                                    language_server_id,
 8317                                    cx,
 8318                                )
 8319                            }
 8320                        })
 8321                        .ok();
 8322                }
 8323                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8324                let relative_path = if let Some(known_path) = known_relative_path {
 8325                    known_path
 8326                } else {
 8327                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8328                        .into_arc()
 8329                };
 8330                (worktree, relative_path)
 8331            };
 8332            let project_path = ProjectPath {
 8333                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8334                path: relative_path,
 8335            };
 8336            lsp_store
 8337                .update(cx, |lsp_store, cx| {
 8338                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8339                        buffer_store.open_buffer(project_path, cx)
 8340                    })
 8341                })?
 8342                .await
 8343        })
 8344    }
 8345
 8346    fn request_multiple_lsp_locally<P, R>(
 8347        &mut self,
 8348        buffer: &Entity<Buffer>,
 8349        position: Option<P>,
 8350        request: R,
 8351        cx: &mut Context<Self>,
 8352    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8353    where
 8354        P: ToOffset,
 8355        R: LspCommand + Clone,
 8356        <R::LspRequest as lsp::request::Request>::Result: Send,
 8357        <R::LspRequest as lsp::request::Request>::Params: Send,
 8358    {
 8359        let Some(local) = self.as_local() else {
 8360            return Task::ready(Vec::new());
 8361        };
 8362
 8363        let snapshot = buffer.read(cx).snapshot();
 8364        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8365
 8366        let server_ids = buffer.update(cx, |buffer, cx| {
 8367            local
 8368                .language_servers_for_buffer(buffer, cx)
 8369                .filter(|(adapter, _)| {
 8370                    scope
 8371                        .as_ref()
 8372                        .map(|scope| scope.language_allowed(&adapter.name))
 8373                        .unwrap_or(true)
 8374                })
 8375                .map(|(_, server)| server.server_id())
 8376                .filter(|server_id| {
 8377                    self.as_local().is_none_or(|local| {
 8378                        local
 8379                            .buffers_opened_in_servers
 8380                            .get(&snapshot.remote_id())
 8381                            .is_some_and(|servers| servers.contains(server_id))
 8382                    })
 8383                })
 8384                .collect::<Vec<_>>()
 8385        });
 8386
 8387        let mut response_results = server_ids
 8388            .into_iter()
 8389            .map(|server_id| {
 8390                let task = self.request_lsp(
 8391                    buffer.clone(),
 8392                    LanguageServerToQuery::Other(server_id),
 8393                    request.clone(),
 8394                    cx,
 8395                );
 8396                async move { (server_id, task.await) }
 8397            })
 8398            .collect::<FuturesUnordered<_>>();
 8399
 8400        cx.background_spawn(async move {
 8401            let mut responses = Vec::with_capacity(response_results.len());
 8402            while let Some((server_id, response_result)) = response_results.next().await {
 8403                match response_result {
 8404                    Ok(response) => responses.push((server_id, response)),
 8405                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8406                }
 8407            }
 8408            responses
 8409        })
 8410    }
 8411
 8412    async fn handle_lsp_command<T: LspCommand>(
 8413        this: Entity<Self>,
 8414        envelope: TypedEnvelope<T::ProtoRequest>,
 8415        mut cx: AsyncApp,
 8416    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8417    where
 8418        <T::LspRequest as lsp::request::Request>::Params: Send,
 8419        <T::LspRequest as lsp::request::Request>::Result: Send,
 8420    {
 8421        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8422        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8423        let buffer_handle = this.update(&mut cx, |this, cx| {
 8424            this.buffer_store.read(cx).get_existing(buffer_id)
 8425        })??;
 8426        let request = T::from_proto(
 8427            envelope.payload,
 8428            this.clone(),
 8429            buffer_handle.clone(),
 8430            cx.clone(),
 8431        )
 8432        .await?;
 8433        let response = this
 8434            .update(&mut cx, |this, cx| {
 8435                this.request_lsp(
 8436                    buffer_handle.clone(),
 8437                    LanguageServerToQuery::FirstCapable,
 8438                    request,
 8439                    cx,
 8440                )
 8441            })?
 8442            .await?;
 8443        this.update(&mut cx, |this, cx| {
 8444            Ok(T::response_to_proto(
 8445                response,
 8446                this,
 8447                sender_id,
 8448                &buffer_handle.read(cx).version(),
 8449                cx,
 8450            ))
 8451        })?
 8452    }
 8453
 8454    async fn handle_lsp_query(
 8455        lsp_store: Entity<Self>,
 8456        envelope: TypedEnvelope<proto::LspQuery>,
 8457        mut cx: AsyncApp,
 8458    ) -> Result<proto::Ack> {
 8459        use proto::lsp_query::Request;
 8460        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8461        let lsp_query = envelope.payload;
 8462        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8463        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8464        match lsp_query.request.context("invalid LSP query request")? {
 8465            Request::GetReferences(get_references) => {
 8466                let position = get_references.position.clone().and_then(deserialize_anchor);
 8467                Self::query_lsp_locally::<GetReferences>(
 8468                    lsp_store,
 8469                    server_id,
 8470                    sender_id,
 8471                    lsp_request_id,
 8472                    get_references,
 8473                    position,
 8474                    &mut cx,
 8475                )
 8476                .await?;
 8477            }
 8478            Request::GetDocumentColor(get_document_color) => {
 8479                Self::query_lsp_locally::<GetDocumentColor>(
 8480                    lsp_store,
 8481                    server_id,
 8482                    sender_id,
 8483                    lsp_request_id,
 8484                    get_document_color,
 8485                    None,
 8486                    &mut cx,
 8487                )
 8488                .await?;
 8489            }
 8490            Request::GetHover(get_hover) => {
 8491                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8492                Self::query_lsp_locally::<GetHover>(
 8493                    lsp_store,
 8494                    server_id,
 8495                    sender_id,
 8496                    lsp_request_id,
 8497                    get_hover,
 8498                    position,
 8499                    &mut cx,
 8500                )
 8501                .await?;
 8502            }
 8503            Request::GetCodeActions(get_code_actions) => {
 8504                Self::query_lsp_locally::<GetCodeActions>(
 8505                    lsp_store,
 8506                    server_id,
 8507                    sender_id,
 8508                    lsp_request_id,
 8509                    get_code_actions,
 8510                    None,
 8511                    &mut cx,
 8512                )
 8513                .await?;
 8514            }
 8515            Request::GetSignatureHelp(get_signature_help) => {
 8516                let position = get_signature_help
 8517                    .position
 8518                    .clone()
 8519                    .and_then(deserialize_anchor);
 8520                Self::query_lsp_locally::<GetSignatureHelp>(
 8521                    lsp_store,
 8522                    server_id,
 8523                    sender_id,
 8524                    lsp_request_id,
 8525                    get_signature_help,
 8526                    position,
 8527                    &mut cx,
 8528                )
 8529                .await?;
 8530            }
 8531            Request::GetCodeLens(get_code_lens) => {
 8532                Self::query_lsp_locally::<GetCodeLens>(
 8533                    lsp_store,
 8534                    server_id,
 8535                    sender_id,
 8536                    lsp_request_id,
 8537                    get_code_lens,
 8538                    None,
 8539                    &mut cx,
 8540                )
 8541                .await?;
 8542            }
 8543            Request::GetDefinition(get_definition) => {
 8544                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8545                Self::query_lsp_locally::<GetDefinitions>(
 8546                    lsp_store,
 8547                    server_id,
 8548                    sender_id,
 8549                    lsp_request_id,
 8550                    get_definition,
 8551                    position,
 8552                    &mut cx,
 8553                )
 8554                .await?;
 8555            }
 8556            Request::GetDeclaration(get_declaration) => {
 8557                let position = get_declaration
 8558                    .position
 8559                    .clone()
 8560                    .and_then(deserialize_anchor);
 8561                Self::query_lsp_locally::<GetDeclarations>(
 8562                    lsp_store,
 8563                    server_id,
 8564                    sender_id,
 8565                    lsp_request_id,
 8566                    get_declaration,
 8567                    position,
 8568                    &mut cx,
 8569                )
 8570                .await?;
 8571            }
 8572            Request::GetTypeDefinition(get_type_definition) => {
 8573                let position = get_type_definition
 8574                    .position
 8575                    .clone()
 8576                    .and_then(deserialize_anchor);
 8577                Self::query_lsp_locally::<GetTypeDefinitions>(
 8578                    lsp_store,
 8579                    server_id,
 8580                    sender_id,
 8581                    lsp_request_id,
 8582                    get_type_definition,
 8583                    position,
 8584                    &mut cx,
 8585                )
 8586                .await?;
 8587            }
 8588            Request::GetImplementation(get_implementation) => {
 8589                let position = get_implementation
 8590                    .position
 8591                    .clone()
 8592                    .and_then(deserialize_anchor);
 8593                Self::query_lsp_locally::<GetImplementations>(
 8594                    lsp_store,
 8595                    server_id,
 8596                    sender_id,
 8597                    lsp_request_id,
 8598                    get_implementation,
 8599                    position,
 8600                    &mut cx,
 8601                )
 8602                .await?;
 8603            }
 8604            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 8605                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 8606                let version = deserialize_version(get_document_diagnostics.buffer_version());
 8607                let buffer = lsp_store.update(&mut cx, |this, cx| {
 8608                    this.buffer_store.read(cx).get_existing(buffer_id)
 8609                })??;
 8610                buffer
 8611                    .update(&mut cx, |buffer, _| {
 8612                        buffer.wait_for_version(version.clone())
 8613                    })?
 8614                    .await?;
 8615                lsp_store.update(&mut cx, |lsp_store, cx| {
 8616                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 8617                    let key = LspKey {
 8618                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 8619                        server_queried: server_id,
 8620                    };
 8621                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 8622                    ) {
 8623                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 8624                            lsp_requests.clear();
 8625                        };
 8626                    }
 8627
 8628                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 8629                    existing_queries.insert(
 8630                        lsp_request_id,
 8631                        cx.spawn(async move |lsp_store, cx| {
 8632                            let diagnostics_pull = lsp_store
 8633                                .update(cx, |lsp_store, cx| {
 8634                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8635                                })
 8636                                .ok();
 8637                            if let Some(diagnostics_pull) = diagnostics_pull {
 8638                                match diagnostics_pull.await {
 8639                                    Ok(()) => {}
 8640                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 8641                                };
 8642                            }
 8643                        }),
 8644                    );
 8645                })?;
 8646            }
 8647            Request::InlayHints(inlay_hints) => {
 8648                let query_start = inlay_hints
 8649                    .start
 8650                    .clone()
 8651                    .and_then(deserialize_anchor)
 8652                    .context("invalid inlay hints range start")?;
 8653                let query_end = inlay_hints
 8654                    .end
 8655                    .clone()
 8656                    .and_then(deserialize_anchor)
 8657                    .context("invalid inlay hints range end")?;
 8658                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 8659                    &lsp_store,
 8660                    server_id,
 8661                    lsp_request_id,
 8662                    &inlay_hints,
 8663                    query_start..query_end,
 8664                    &mut cx,
 8665                )
 8666                .await
 8667                .context("preparing inlay hints request")?;
 8668                Self::query_lsp_locally::<InlayHints>(
 8669                    lsp_store,
 8670                    server_id,
 8671                    sender_id,
 8672                    lsp_request_id,
 8673                    inlay_hints,
 8674                    None,
 8675                    &mut cx,
 8676                )
 8677                .await
 8678                .context("querying for inlay hints")?
 8679            }
 8680        }
 8681        Ok(proto::Ack {})
 8682    }
 8683
 8684    async fn handle_lsp_query_response(
 8685        lsp_store: Entity<Self>,
 8686        envelope: TypedEnvelope<proto::LspQueryResponse>,
 8687        cx: AsyncApp,
 8688    ) -> Result<()> {
 8689        lsp_store.read_with(&cx, |lsp_store, _| {
 8690            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 8691                upstream_client.handle_lsp_response(envelope.clone());
 8692            }
 8693        })?;
 8694        Ok(())
 8695    }
 8696
 8697    async fn handle_apply_code_action(
 8698        this: Entity<Self>,
 8699        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 8700        mut cx: AsyncApp,
 8701    ) -> Result<proto::ApplyCodeActionResponse> {
 8702        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8703        let action =
 8704            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 8705        let apply_code_action = this.update(&mut cx, |this, cx| {
 8706            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8707            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 8708            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 8709        })??;
 8710
 8711        let project_transaction = apply_code_action.await?;
 8712        let project_transaction = this.update(&mut cx, |this, cx| {
 8713            this.buffer_store.update(cx, |buffer_store, cx| {
 8714                buffer_store.serialize_project_transaction_for_peer(
 8715                    project_transaction,
 8716                    sender_id,
 8717                    cx,
 8718                )
 8719            })
 8720        })?;
 8721        Ok(proto::ApplyCodeActionResponse {
 8722            transaction: Some(project_transaction),
 8723        })
 8724    }
 8725
 8726    async fn handle_register_buffer_with_language_servers(
 8727        this: Entity<Self>,
 8728        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 8729        mut cx: AsyncApp,
 8730    ) -> Result<proto::Ack> {
 8731        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8732        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 8733        this.update(&mut cx, |this, cx| {
 8734            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 8735                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 8736                    project_id: upstream_project_id,
 8737                    buffer_id: buffer_id.to_proto(),
 8738                    only_servers: envelope.payload.only_servers,
 8739                });
 8740            }
 8741
 8742            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 8743                anyhow::bail!("buffer is not open");
 8744            };
 8745
 8746            let handle = this.register_buffer_with_language_servers(
 8747                &buffer,
 8748                envelope
 8749                    .payload
 8750                    .only_servers
 8751                    .into_iter()
 8752                    .filter_map(|selector| {
 8753                        Some(match selector.selector? {
 8754                            proto::language_server_selector::Selector::ServerId(server_id) => {
 8755                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 8756                            }
 8757                            proto::language_server_selector::Selector::Name(name) => {
 8758                                LanguageServerSelector::Name(LanguageServerName(
 8759                                    SharedString::from(name),
 8760                                ))
 8761                            }
 8762                        })
 8763                    })
 8764                    .collect(),
 8765                false,
 8766                cx,
 8767            );
 8768            this.buffer_store().update(cx, |buffer_store, _| {
 8769                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 8770            });
 8771
 8772            Ok(())
 8773        })??;
 8774        Ok(proto::Ack {})
 8775    }
 8776
 8777    async fn handle_rename_project_entry(
 8778        this: Entity<Self>,
 8779        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 8780        mut cx: AsyncApp,
 8781    ) -> Result<proto::ProjectEntryResponse> {
 8782        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 8783        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 8784        let new_path =
 8785            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 8786
 8787        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 8788            .update(&mut cx, |this, cx| {
 8789                let (worktree, entry) = this
 8790                    .worktree_store
 8791                    .read(cx)
 8792                    .worktree_and_entry_for_id(entry_id, cx)?;
 8793                let new_worktree = this
 8794                    .worktree_store
 8795                    .read(cx)
 8796                    .worktree_for_id(new_worktree_id, cx)?;
 8797                Some((
 8798                    this.worktree_store.clone(),
 8799                    worktree,
 8800                    new_worktree,
 8801                    entry.clone(),
 8802                ))
 8803            })?
 8804            .context("worktree not found")?;
 8805        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 8806            (worktree.absolutize(&old_entry.path), worktree.id())
 8807        })?;
 8808        let new_abs_path =
 8809            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 8810
 8811        let _transaction = Self::will_rename_entry(
 8812            this.downgrade(),
 8813            old_worktree_id,
 8814            &old_abs_path,
 8815            &new_abs_path,
 8816            old_entry.is_dir(),
 8817            cx.clone(),
 8818        )
 8819        .await;
 8820        let response = WorktreeStore::handle_rename_project_entry(
 8821            worktree_store,
 8822            envelope.payload,
 8823            cx.clone(),
 8824        )
 8825        .await;
 8826        this.read_with(&cx, |this, _| {
 8827            this.did_rename_entry(
 8828                old_worktree_id,
 8829                &old_abs_path,
 8830                &new_abs_path,
 8831                old_entry.is_dir(),
 8832            );
 8833        })
 8834        .ok();
 8835        response
 8836    }
 8837
 8838    async fn handle_update_diagnostic_summary(
 8839        this: Entity<Self>,
 8840        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 8841        mut cx: AsyncApp,
 8842    ) -> Result<()> {
 8843        this.update(&mut cx, |lsp_store, cx| {
 8844            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 8845            let mut updated_diagnostics_paths = HashMap::default();
 8846            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8847            for message_summary in envelope
 8848                .payload
 8849                .summary
 8850                .into_iter()
 8851                .chain(envelope.payload.more_summaries)
 8852            {
 8853                let project_path = ProjectPath {
 8854                    worktree_id,
 8855                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 8856                };
 8857                let path = project_path.path.clone();
 8858                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 8859                let summary = DiagnosticSummary {
 8860                    error_count: message_summary.error_count as usize,
 8861                    warning_count: message_summary.warning_count as usize,
 8862                };
 8863
 8864                if summary.is_empty() {
 8865                    if let Some(worktree_summaries) =
 8866                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 8867                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 8868                    {
 8869                        summaries.remove(&server_id);
 8870                        if summaries.is_empty() {
 8871                            worktree_summaries.remove(&path);
 8872                        }
 8873                    }
 8874                } else {
 8875                    lsp_store
 8876                        .diagnostic_summaries
 8877                        .entry(worktree_id)
 8878                        .or_default()
 8879                        .entry(path)
 8880                        .or_default()
 8881                        .insert(server_id, summary);
 8882                }
 8883
 8884                if let Some((_, project_id)) = &lsp_store.downstream_client {
 8885                    match &mut diagnostics_summary {
 8886                        Some(diagnostics_summary) => {
 8887                            diagnostics_summary
 8888                                .more_summaries
 8889                                .push(proto::DiagnosticSummary {
 8890                                    path: project_path.path.as_ref().to_proto(),
 8891                                    language_server_id: server_id.0 as u64,
 8892                                    error_count: summary.error_count as u32,
 8893                                    warning_count: summary.warning_count as u32,
 8894                                })
 8895                        }
 8896                        None => {
 8897                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8898                                project_id: *project_id,
 8899                                worktree_id: worktree_id.to_proto(),
 8900                                summary: Some(proto::DiagnosticSummary {
 8901                                    path: project_path.path.as_ref().to_proto(),
 8902                                    language_server_id: server_id.0 as u64,
 8903                                    error_count: summary.error_count as u32,
 8904                                    warning_count: summary.warning_count as u32,
 8905                                }),
 8906                                more_summaries: Vec::new(),
 8907                            })
 8908                        }
 8909                    }
 8910                }
 8911                updated_diagnostics_paths
 8912                    .entry(server_id)
 8913                    .or_insert_with(Vec::new)
 8914                    .push(project_path);
 8915            }
 8916
 8917            if let Some((diagnostics_summary, (downstream_client, _))) =
 8918                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 8919            {
 8920                downstream_client.send(diagnostics_summary).log_err();
 8921            }
 8922            for (server_id, paths) in updated_diagnostics_paths {
 8923                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8924            }
 8925            Ok(())
 8926        })?
 8927    }
 8928
 8929    async fn handle_start_language_server(
 8930        lsp_store: Entity<Self>,
 8931        envelope: TypedEnvelope<proto::StartLanguageServer>,
 8932        mut cx: AsyncApp,
 8933    ) -> Result<()> {
 8934        let server = envelope.payload.server.context("invalid server")?;
 8935        let server_capabilities =
 8936            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 8937                .with_context(|| {
 8938                    format!(
 8939                        "incorrect server capabilities {}",
 8940                        envelope.payload.capabilities
 8941                    )
 8942                })?;
 8943        lsp_store.update(&mut cx, |lsp_store, cx| {
 8944            let server_id = LanguageServerId(server.id as usize);
 8945            let server_name = LanguageServerName::from_proto(server.name.clone());
 8946            lsp_store
 8947                .lsp_server_capabilities
 8948                .insert(server_id, server_capabilities);
 8949            lsp_store.language_server_statuses.insert(
 8950                server_id,
 8951                LanguageServerStatus {
 8952                    name: server_name.clone(),
 8953                    pending_work: Default::default(),
 8954                    has_pending_diagnostic_updates: false,
 8955                    progress_tokens: Default::default(),
 8956                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 8957                },
 8958            );
 8959            cx.emit(LspStoreEvent::LanguageServerAdded(
 8960                server_id,
 8961                server_name,
 8962                server.worktree_id.map(WorktreeId::from_proto),
 8963            ));
 8964            cx.notify();
 8965        })?;
 8966        Ok(())
 8967    }
 8968
 8969    async fn handle_update_language_server(
 8970        lsp_store: Entity<Self>,
 8971        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 8972        mut cx: AsyncApp,
 8973    ) -> Result<()> {
 8974        lsp_store.update(&mut cx, |lsp_store, cx| {
 8975            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 8976
 8977            match envelope.payload.variant.context("invalid variant")? {
 8978                proto::update_language_server::Variant::WorkStart(payload) => {
 8979                    lsp_store.on_lsp_work_start(
 8980                        language_server_id,
 8981                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 8982                            .context("invalid progress token value")?,
 8983                        LanguageServerProgress {
 8984                            title: payload.title,
 8985                            is_disk_based_diagnostics_progress: false,
 8986                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 8987                            message: payload.message,
 8988                            percentage: payload.percentage.map(|p| p as usize),
 8989                            last_update_at: cx.background_executor().now(),
 8990                        },
 8991                        cx,
 8992                    );
 8993                }
 8994                proto::update_language_server::Variant::WorkProgress(payload) => {
 8995                    lsp_store.on_lsp_work_progress(
 8996                        language_server_id,
 8997                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 8998                            .context("invalid progress token value")?,
 8999                        LanguageServerProgress {
 9000                            title: None,
 9001                            is_disk_based_diagnostics_progress: false,
 9002                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9003                            message: payload.message,
 9004                            percentage: payload.percentage.map(|p| p as usize),
 9005                            last_update_at: cx.background_executor().now(),
 9006                        },
 9007                        cx,
 9008                    );
 9009                }
 9010
 9011                proto::update_language_server::Variant::WorkEnd(payload) => {
 9012                    lsp_store.on_lsp_work_end(
 9013                        language_server_id,
 9014                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9015                            .context("invalid progress token value")?,
 9016                        cx,
 9017                    );
 9018                }
 9019
 9020                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9021                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9022                }
 9023
 9024                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9025                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9026                }
 9027
 9028                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9029                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9030                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9031                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9032                        language_server_id,
 9033                        name: envelope
 9034                            .payload
 9035                            .server_name
 9036                            .map(SharedString::new)
 9037                            .map(LanguageServerName),
 9038                        message: non_lsp,
 9039                    });
 9040                }
 9041            }
 9042
 9043            Ok(())
 9044        })?
 9045    }
 9046
 9047    async fn handle_language_server_log(
 9048        this: Entity<Self>,
 9049        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9050        mut cx: AsyncApp,
 9051    ) -> Result<()> {
 9052        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9053        let log_type = envelope
 9054            .payload
 9055            .log_type
 9056            .map(LanguageServerLogType::from_proto)
 9057            .context("invalid language server log type")?;
 9058
 9059        let message = envelope.payload.message;
 9060
 9061        this.update(&mut cx, |_, cx| {
 9062            cx.emit(LspStoreEvent::LanguageServerLog(
 9063                language_server_id,
 9064                log_type,
 9065                message,
 9066            ));
 9067        })
 9068    }
 9069
 9070    async fn handle_lsp_ext_cancel_flycheck(
 9071        lsp_store: Entity<Self>,
 9072        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9073        cx: AsyncApp,
 9074    ) -> Result<proto::Ack> {
 9075        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9076        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9077            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9078                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9079            } else {
 9080                None
 9081            }
 9082        })?;
 9083        if let Some(task) = task {
 9084            task.context("handling lsp ext cancel flycheck")?;
 9085        }
 9086
 9087        Ok(proto::Ack {})
 9088    }
 9089
 9090    async fn handle_lsp_ext_run_flycheck(
 9091        lsp_store: Entity<Self>,
 9092        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9093        mut cx: AsyncApp,
 9094    ) -> Result<proto::Ack> {
 9095        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9096        lsp_store.update(&mut cx, |lsp_store, cx| {
 9097            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9098                let text_document = if envelope.payload.current_file_only {
 9099                    let buffer_id = envelope
 9100                        .payload
 9101                        .buffer_id
 9102                        .map(|id| BufferId::new(id))
 9103                        .transpose()?;
 9104                    buffer_id
 9105                        .and_then(|buffer_id| {
 9106                            lsp_store
 9107                                .buffer_store()
 9108                                .read(cx)
 9109                                .get(buffer_id)
 9110                                .and_then(|buffer| {
 9111                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9112                                })
 9113                                .map(|path| make_text_document_identifier(&path))
 9114                        })
 9115                        .transpose()?
 9116                } else {
 9117                    None
 9118                };
 9119                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9120                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9121                )?;
 9122            }
 9123            anyhow::Ok(())
 9124        })??;
 9125
 9126        Ok(proto::Ack {})
 9127    }
 9128
 9129    async fn handle_lsp_ext_clear_flycheck(
 9130        lsp_store: Entity<Self>,
 9131        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9132        cx: AsyncApp,
 9133    ) -> Result<proto::Ack> {
 9134        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9135        lsp_store
 9136            .read_with(&cx, |lsp_store, _| {
 9137                if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9138                    Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9139                } else {
 9140                    None
 9141                }
 9142            })
 9143            .context("handling lsp ext clear flycheck")?;
 9144
 9145        Ok(proto::Ack {})
 9146    }
 9147
 9148    pub fn disk_based_diagnostics_started(
 9149        &mut self,
 9150        language_server_id: LanguageServerId,
 9151        cx: &mut Context<Self>,
 9152    ) {
 9153        if let Some(language_server_status) =
 9154            self.language_server_statuses.get_mut(&language_server_id)
 9155        {
 9156            language_server_status.has_pending_diagnostic_updates = true;
 9157        }
 9158
 9159        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9160        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9161            language_server_id,
 9162            name: self
 9163                .language_server_adapter_for_id(language_server_id)
 9164                .map(|adapter| adapter.name()),
 9165            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9166                Default::default(),
 9167            ),
 9168        })
 9169    }
 9170
 9171    pub fn disk_based_diagnostics_finished(
 9172        &mut self,
 9173        language_server_id: LanguageServerId,
 9174        cx: &mut Context<Self>,
 9175    ) {
 9176        if let Some(language_server_status) =
 9177            self.language_server_statuses.get_mut(&language_server_id)
 9178        {
 9179            language_server_status.has_pending_diagnostic_updates = false;
 9180        }
 9181
 9182        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9183        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9184            language_server_id,
 9185            name: self
 9186                .language_server_adapter_for_id(language_server_id)
 9187                .map(|adapter| adapter.name()),
 9188            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9189                Default::default(),
 9190            ),
 9191        })
 9192    }
 9193
 9194    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9195    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9196    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9197    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9198    // the language server might take some time to publish diagnostics.
 9199    fn simulate_disk_based_diagnostics_events_if_needed(
 9200        &mut self,
 9201        language_server_id: LanguageServerId,
 9202        cx: &mut Context<Self>,
 9203    ) {
 9204        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9205
 9206        let Some(LanguageServerState::Running {
 9207            simulate_disk_based_diagnostics_completion,
 9208            adapter,
 9209            ..
 9210        }) = self
 9211            .as_local_mut()
 9212            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9213        else {
 9214            return;
 9215        };
 9216
 9217        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9218            return;
 9219        }
 9220
 9221        let prev_task =
 9222            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9223                cx.background_executor()
 9224                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9225                    .await;
 9226
 9227                this.update(cx, |this, cx| {
 9228                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9229
 9230                    if let Some(LanguageServerState::Running {
 9231                        simulate_disk_based_diagnostics_completion,
 9232                        ..
 9233                    }) = this.as_local_mut().and_then(|local_store| {
 9234                        local_store.language_servers.get_mut(&language_server_id)
 9235                    }) {
 9236                        *simulate_disk_based_diagnostics_completion = None;
 9237                    }
 9238                })
 9239                .ok();
 9240            }));
 9241
 9242        if prev_task.is_none() {
 9243            self.disk_based_diagnostics_started(language_server_id, cx);
 9244        }
 9245    }
 9246
 9247    pub fn language_server_statuses(
 9248        &self,
 9249    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9250        self.language_server_statuses
 9251            .iter()
 9252            .map(|(key, value)| (*key, value))
 9253    }
 9254
 9255    pub(super) fn did_rename_entry(
 9256        &self,
 9257        worktree_id: WorktreeId,
 9258        old_path: &Path,
 9259        new_path: &Path,
 9260        is_dir: bool,
 9261    ) {
 9262        maybe!({
 9263            let local_store = self.as_local()?;
 9264
 9265            let old_uri = lsp::Uri::from_file_path(old_path)
 9266                .ok()
 9267                .map(|uri| uri.to_string())?;
 9268            let new_uri = lsp::Uri::from_file_path(new_path)
 9269                .ok()
 9270                .map(|uri| uri.to_string())?;
 9271
 9272            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9273                let Some(filter) = local_store
 9274                    .language_server_paths_watched_for_rename
 9275                    .get(&language_server.server_id())
 9276                else {
 9277                    continue;
 9278                };
 9279
 9280                if filter.should_send_did_rename(&old_uri, is_dir) {
 9281                    language_server
 9282                        .notify::<DidRenameFiles>(RenameFilesParams {
 9283                            files: vec![FileRename {
 9284                                old_uri: old_uri.clone(),
 9285                                new_uri: new_uri.clone(),
 9286                            }],
 9287                        })
 9288                        .ok();
 9289                }
 9290            }
 9291            Some(())
 9292        });
 9293    }
 9294
 9295    pub(super) fn will_rename_entry(
 9296        this: WeakEntity<Self>,
 9297        worktree_id: WorktreeId,
 9298        old_path: &Path,
 9299        new_path: &Path,
 9300        is_dir: bool,
 9301        cx: AsyncApp,
 9302    ) -> Task<ProjectTransaction> {
 9303        let old_uri = lsp::Uri::from_file_path(old_path)
 9304            .ok()
 9305            .map(|uri| uri.to_string());
 9306        let new_uri = lsp::Uri::from_file_path(new_path)
 9307            .ok()
 9308            .map(|uri| uri.to_string());
 9309        cx.spawn(async move |cx| {
 9310            let mut tasks = vec![];
 9311            this.update(cx, |this, cx| {
 9312                let local_store = this.as_local()?;
 9313                let old_uri = old_uri?;
 9314                let new_uri = new_uri?;
 9315                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9316                    let Some(filter) = local_store
 9317                        .language_server_paths_watched_for_rename
 9318                        .get(&language_server.server_id())
 9319                    else {
 9320                        continue;
 9321                    };
 9322
 9323                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9324                        let apply_edit = cx.spawn({
 9325                            let old_uri = old_uri.clone();
 9326                            let new_uri = new_uri.clone();
 9327                            let language_server = language_server.clone();
 9328                            async move |this, cx| {
 9329                                let edit = language_server
 9330                                    .request::<WillRenameFiles>(RenameFilesParams {
 9331                                        files: vec![FileRename { old_uri, new_uri }],
 9332                                    })
 9333                                    .await
 9334                                    .into_response()
 9335                                    .context("will rename files")
 9336                                    .log_err()
 9337                                    .flatten()?;
 9338
 9339                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9340                                    this.upgrade()?,
 9341                                    edit,
 9342                                    false,
 9343                                    language_server.clone(),
 9344                                    cx,
 9345                                )
 9346                                .await
 9347                                .ok()?;
 9348                                Some(transaction)
 9349                            }
 9350                        });
 9351                        tasks.push(apply_edit);
 9352                    }
 9353                }
 9354                Some(())
 9355            })
 9356            .ok()
 9357            .flatten();
 9358            let mut merged_transaction = ProjectTransaction::default();
 9359            for task in tasks {
 9360                // Await on tasks sequentially so that the order of application of edits is deterministic
 9361                // (at least with regards to the order of registration of language servers)
 9362                if let Some(transaction) = task.await {
 9363                    for (buffer, buffer_transaction) in transaction.0 {
 9364                        merged_transaction.0.insert(buffer, buffer_transaction);
 9365                    }
 9366                }
 9367            }
 9368            merged_transaction
 9369        })
 9370    }
 9371
 9372    fn lsp_notify_abs_paths_changed(
 9373        &mut self,
 9374        server_id: LanguageServerId,
 9375        changes: Vec<PathEvent>,
 9376    ) {
 9377        maybe!({
 9378            let server = self.language_server_for_id(server_id)?;
 9379            let changes = changes
 9380                .into_iter()
 9381                .filter_map(|event| {
 9382                    let typ = match event.kind? {
 9383                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9384                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9385                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9386                    };
 9387                    Some(lsp::FileEvent {
 9388                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9389                        typ,
 9390                    })
 9391                })
 9392                .collect::<Vec<_>>();
 9393            if !changes.is_empty() {
 9394                server
 9395                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9396                        lsp::DidChangeWatchedFilesParams { changes },
 9397                    )
 9398                    .ok();
 9399            }
 9400            Some(())
 9401        });
 9402    }
 9403
 9404    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9405        self.as_local()?.language_server_for_id(id)
 9406    }
 9407
 9408    fn on_lsp_progress(
 9409        &mut self,
 9410        progress_params: lsp::ProgressParams,
 9411        language_server_id: LanguageServerId,
 9412        disk_based_diagnostics_progress_token: Option<String>,
 9413        cx: &mut Context<Self>,
 9414    ) {
 9415        match progress_params.value {
 9416            lsp::ProgressParamsValue::WorkDone(progress) => {
 9417                self.handle_work_done_progress(
 9418                    progress,
 9419                    language_server_id,
 9420                    disk_based_diagnostics_progress_token,
 9421                    ProgressToken::from_lsp(progress_params.token),
 9422                    cx,
 9423                );
 9424            }
 9425            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9426                let identifier = match progress_params.token {
 9427                    lsp::NumberOrString::Number(_) => None,
 9428                    lsp::NumberOrString::String(token) => token
 9429                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9430                        .map(|(_, id)| id.to_owned()),
 9431                };
 9432                if let Some(LanguageServerState::Running {
 9433                    workspace_diagnostics_refresh_tasks,
 9434                    ..
 9435                }) = self
 9436                    .as_local_mut()
 9437                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9438                    && let Some(workspace_diagnostics) =
 9439                        workspace_diagnostics_refresh_tasks.get_mut(&identifier)
 9440                {
 9441                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9442                    self.apply_workspace_diagnostic_report(language_server_id, report, cx)
 9443                }
 9444            }
 9445        }
 9446    }
 9447
 9448    fn handle_work_done_progress(
 9449        &mut self,
 9450        progress: lsp::WorkDoneProgress,
 9451        language_server_id: LanguageServerId,
 9452        disk_based_diagnostics_progress_token: Option<String>,
 9453        token: ProgressToken,
 9454        cx: &mut Context<Self>,
 9455    ) {
 9456        let language_server_status =
 9457            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9458                status
 9459            } else {
 9460                return;
 9461            };
 9462
 9463        if !language_server_status.progress_tokens.contains(&token) {
 9464            return;
 9465        }
 9466
 9467        let is_disk_based_diagnostics_progress =
 9468            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9469                (&disk_based_diagnostics_progress_token, &token)
 9470            {
 9471                token.starts_with(disk_based_token)
 9472            } else {
 9473                false
 9474            };
 9475
 9476        match progress {
 9477            lsp::WorkDoneProgress::Begin(report) => {
 9478                if is_disk_based_diagnostics_progress {
 9479                    self.disk_based_diagnostics_started(language_server_id, cx);
 9480                }
 9481                self.on_lsp_work_start(
 9482                    language_server_id,
 9483                    token.clone(),
 9484                    LanguageServerProgress {
 9485                        title: Some(report.title),
 9486                        is_disk_based_diagnostics_progress,
 9487                        is_cancellable: report.cancellable.unwrap_or(false),
 9488                        message: report.message.clone(),
 9489                        percentage: report.percentage.map(|p| p as usize),
 9490                        last_update_at: cx.background_executor().now(),
 9491                    },
 9492                    cx,
 9493                );
 9494            }
 9495            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9496                language_server_id,
 9497                token,
 9498                LanguageServerProgress {
 9499                    title: None,
 9500                    is_disk_based_diagnostics_progress,
 9501                    is_cancellable: report.cancellable.unwrap_or(false),
 9502                    message: report.message,
 9503                    percentage: report.percentage.map(|p| p as usize),
 9504                    last_update_at: cx.background_executor().now(),
 9505                },
 9506                cx,
 9507            ),
 9508            lsp::WorkDoneProgress::End(_) => {
 9509                language_server_status.progress_tokens.remove(&token);
 9510                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9511                if is_disk_based_diagnostics_progress {
 9512                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9513                }
 9514            }
 9515        }
 9516    }
 9517
 9518    fn on_lsp_work_start(
 9519        &mut self,
 9520        language_server_id: LanguageServerId,
 9521        token: ProgressToken,
 9522        progress: LanguageServerProgress,
 9523        cx: &mut Context<Self>,
 9524    ) {
 9525        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9526            status.pending_work.insert(token.clone(), progress.clone());
 9527            cx.notify();
 9528        }
 9529        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9530            language_server_id,
 9531            name: self
 9532                .language_server_adapter_for_id(language_server_id)
 9533                .map(|adapter| adapter.name()),
 9534            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9535                token: Some(token.to_proto()),
 9536                title: progress.title,
 9537                message: progress.message,
 9538                percentage: progress.percentage.map(|p| p as u32),
 9539                is_cancellable: Some(progress.is_cancellable),
 9540            }),
 9541        })
 9542    }
 9543
 9544    fn on_lsp_work_progress(
 9545        &mut self,
 9546        language_server_id: LanguageServerId,
 9547        token: ProgressToken,
 9548        progress: LanguageServerProgress,
 9549        cx: &mut Context<Self>,
 9550    ) {
 9551        let mut did_update = false;
 9552        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9553            match status.pending_work.entry(token.clone()) {
 9554                btree_map::Entry::Vacant(entry) => {
 9555                    entry.insert(progress.clone());
 9556                    did_update = true;
 9557                }
 9558                btree_map::Entry::Occupied(mut entry) => {
 9559                    let entry = entry.get_mut();
 9560                    if (progress.last_update_at - entry.last_update_at)
 9561                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9562                    {
 9563                        entry.last_update_at = progress.last_update_at;
 9564                        if progress.message.is_some() {
 9565                            entry.message = progress.message.clone();
 9566                        }
 9567                        if progress.percentage.is_some() {
 9568                            entry.percentage = progress.percentage;
 9569                        }
 9570                        if progress.is_cancellable != entry.is_cancellable {
 9571                            entry.is_cancellable = progress.is_cancellable;
 9572                        }
 9573                        did_update = true;
 9574                    }
 9575                }
 9576            }
 9577        }
 9578
 9579        if did_update {
 9580            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9581                language_server_id,
 9582                name: self
 9583                    .language_server_adapter_for_id(language_server_id)
 9584                    .map(|adapter| adapter.name()),
 9585                message: proto::update_language_server::Variant::WorkProgress(
 9586                    proto::LspWorkProgress {
 9587                        token: Some(token.to_proto()),
 9588                        message: progress.message,
 9589                        percentage: progress.percentage.map(|p| p as u32),
 9590                        is_cancellable: Some(progress.is_cancellable),
 9591                    },
 9592                ),
 9593            })
 9594        }
 9595    }
 9596
 9597    fn on_lsp_work_end(
 9598        &mut self,
 9599        language_server_id: LanguageServerId,
 9600        token: ProgressToken,
 9601        cx: &mut Context<Self>,
 9602    ) {
 9603        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9604            if let Some(work) = status.pending_work.remove(&token)
 9605                && !work.is_disk_based_diagnostics_progress
 9606            {
 9607                cx.emit(LspStoreEvent::RefreshInlayHints(language_server_id));
 9608            }
 9609            cx.notify();
 9610        }
 9611
 9612        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9613            language_server_id,
 9614            name: self
 9615                .language_server_adapter_for_id(language_server_id)
 9616                .map(|adapter| adapter.name()),
 9617            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
 9618                token: Some(token.to_proto()),
 9619            }),
 9620        })
 9621    }
 9622
 9623    pub async fn handle_resolve_completion_documentation(
 9624        this: Entity<Self>,
 9625        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
 9626        mut cx: AsyncApp,
 9627    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
 9628        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
 9629
 9630        let completion = this
 9631            .read_with(&cx, |this, cx| {
 9632                let id = LanguageServerId(envelope.payload.language_server_id as usize);
 9633                let server = this
 9634                    .language_server_for_id(id)
 9635                    .with_context(|| format!("No language server {id}"))?;
 9636
 9637                anyhow::Ok(cx.background_spawn(async move {
 9638                    let can_resolve = server
 9639                        .capabilities()
 9640                        .completion_provider
 9641                        .as_ref()
 9642                        .and_then(|options| options.resolve_provider)
 9643                        .unwrap_or(false);
 9644                    if can_resolve {
 9645                        server
 9646                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
 9647                            .await
 9648                            .into_response()
 9649                            .context("resolve completion item")
 9650                    } else {
 9651                        anyhow::Ok(lsp_completion)
 9652                    }
 9653                }))
 9654            })??
 9655            .await?;
 9656
 9657        let mut documentation_is_markdown = false;
 9658        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
 9659        let documentation = match completion.documentation {
 9660            Some(lsp::Documentation::String(text)) => text,
 9661
 9662            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
 9663                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
 9664                value
 9665            }
 9666
 9667            _ => String::new(),
 9668        };
 9669
 9670        // If we have a new buffer_id, that means we're talking to a new client
 9671        // and want to check for new text_edits in the completion too.
 9672        let mut old_replace_start = None;
 9673        let mut old_replace_end = None;
 9674        let mut old_insert_start = None;
 9675        let mut old_insert_end = None;
 9676        let mut new_text = String::default();
 9677        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
 9678            let buffer_snapshot = this.update(&mut cx, |this, cx| {
 9679                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9680                anyhow::Ok(buffer.read(cx).snapshot())
 9681            })??;
 9682
 9683            if let Some(text_edit) = completion.text_edit.as_ref() {
 9684                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
 9685
 9686                if let Some(mut edit) = edit {
 9687                    LineEnding::normalize(&mut edit.new_text);
 9688
 9689                    new_text = edit.new_text;
 9690                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
 9691                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
 9692                    if let Some(insert_range) = edit.insert_range {
 9693                        old_insert_start = Some(serialize_anchor(&insert_range.start));
 9694                        old_insert_end = Some(serialize_anchor(&insert_range.end));
 9695                    }
 9696                }
 9697            }
 9698        }
 9699
 9700        Ok(proto::ResolveCompletionDocumentationResponse {
 9701            documentation,
 9702            documentation_is_markdown,
 9703            old_replace_start,
 9704            old_replace_end,
 9705            new_text,
 9706            lsp_completion,
 9707            old_insert_start,
 9708            old_insert_end,
 9709        })
 9710    }
 9711
 9712    async fn handle_on_type_formatting(
 9713        this: Entity<Self>,
 9714        envelope: TypedEnvelope<proto::OnTypeFormatting>,
 9715        mut cx: AsyncApp,
 9716    ) -> Result<proto::OnTypeFormattingResponse> {
 9717        let on_type_formatting = this.update(&mut cx, |this, cx| {
 9718            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9719            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9720            let position = envelope
 9721                .payload
 9722                .position
 9723                .and_then(deserialize_anchor)
 9724                .context("invalid position")?;
 9725            anyhow::Ok(this.apply_on_type_formatting(
 9726                buffer,
 9727                position,
 9728                envelope.payload.trigger.clone(),
 9729                cx,
 9730            ))
 9731        })??;
 9732
 9733        let transaction = on_type_formatting
 9734            .await?
 9735            .as_ref()
 9736            .map(language::proto::serialize_transaction);
 9737        Ok(proto::OnTypeFormattingResponse { transaction })
 9738    }
 9739
 9740    async fn handle_refresh_inlay_hints(
 9741        lsp_store: Entity<Self>,
 9742        envelope: TypedEnvelope<proto::RefreshInlayHints>,
 9743        mut cx: AsyncApp,
 9744    ) -> Result<proto::Ack> {
 9745        lsp_store.update(&mut cx, |_, cx| {
 9746            cx.emit(LspStoreEvent::RefreshInlayHints(
 9747                LanguageServerId::from_proto(envelope.payload.server_id),
 9748            ));
 9749        })?;
 9750        Ok(proto::Ack {})
 9751    }
 9752
 9753    async fn handle_pull_workspace_diagnostics(
 9754        lsp_store: Entity<Self>,
 9755        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
 9756        mut cx: AsyncApp,
 9757    ) -> Result<proto::Ack> {
 9758        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
 9759        lsp_store.update(&mut cx, |lsp_store, _| {
 9760            lsp_store.pull_workspace_diagnostics(server_id);
 9761        })?;
 9762        Ok(proto::Ack {})
 9763    }
 9764
 9765    async fn handle_get_color_presentation(
 9766        lsp_store: Entity<Self>,
 9767        envelope: TypedEnvelope<proto::GetColorPresentation>,
 9768        mut cx: AsyncApp,
 9769    ) -> Result<proto::GetColorPresentationResponse> {
 9770        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9771        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9772            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9773        })??;
 9774
 9775        let color = envelope
 9776            .payload
 9777            .color
 9778            .context("invalid color resolve request")?;
 9779        let start = color
 9780            .lsp_range_start
 9781            .context("invalid color resolve request")?;
 9782        let end = color
 9783            .lsp_range_end
 9784            .context("invalid color resolve request")?;
 9785
 9786        let color = DocumentColor {
 9787            lsp_range: lsp::Range {
 9788                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
 9789                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
 9790            },
 9791            color: lsp::Color {
 9792                red: color.red,
 9793                green: color.green,
 9794                blue: color.blue,
 9795                alpha: color.alpha,
 9796            },
 9797            resolved: false,
 9798            color_presentations: Vec::new(),
 9799        };
 9800        let resolved_color = lsp_store
 9801            .update(&mut cx, |lsp_store, cx| {
 9802                lsp_store.resolve_color_presentation(
 9803                    color,
 9804                    buffer.clone(),
 9805                    LanguageServerId(envelope.payload.server_id as usize),
 9806                    cx,
 9807                )
 9808            })?
 9809            .await
 9810            .context("resolving color presentation")?;
 9811
 9812        Ok(proto::GetColorPresentationResponse {
 9813            presentations: resolved_color
 9814                .color_presentations
 9815                .into_iter()
 9816                .map(|presentation| proto::ColorPresentation {
 9817                    label: presentation.label.to_string(),
 9818                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
 9819                    additional_text_edits: presentation
 9820                        .additional_text_edits
 9821                        .into_iter()
 9822                        .map(serialize_lsp_edit)
 9823                        .collect(),
 9824                })
 9825                .collect(),
 9826        })
 9827    }
 9828
 9829    async fn handle_resolve_inlay_hint(
 9830        lsp_store: Entity<Self>,
 9831        envelope: TypedEnvelope<proto::ResolveInlayHint>,
 9832        mut cx: AsyncApp,
 9833    ) -> Result<proto::ResolveInlayHintResponse> {
 9834        let proto_hint = envelope
 9835            .payload
 9836            .hint
 9837            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
 9838        let hint = InlayHints::proto_to_project_hint(proto_hint)
 9839            .context("resolved proto inlay hint conversion")?;
 9840        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9841            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9842            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9843        })??;
 9844        let response_hint = lsp_store
 9845            .update(&mut cx, |lsp_store, cx| {
 9846                lsp_store.resolve_inlay_hint(
 9847                    hint,
 9848                    buffer,
 9849                    LanguageServerId(envelope.payload.language_server_id as usize),
 9850                    cx,
 9851                )
 9852            })?
 9853            .await
 9854            .context("inlay hints fetch")?;
 9855        Ok(proto::ResolveInlayHintResponse {
 9856            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
 9857        })
 9858    }
 9859
 9860    async fn handle_refresh_code_lens(
 9861        this: Entity<Self>,
 9862        _: TypedEnvelope<proto::RefreshCodeLens>,
 9863        mut cx: AsyncApp,
 9864    ) -> Result<proto::Ack> {
 9865        this.update(&mut cx, |_, cx| {
 9866            cx.emit(LspStoreEvent::RefreshCodeLens);
 9867        })?;
 9868        Ok(proto::Ack {})
 9869    }
 9870
 9871    async fn handle_open_buffer_for_symbol(
 9872        this: Entity<Self>,
 9873        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
 9874        mut cx: AsyncApp,
 9875    ) -> Result<proto::OpenBufferForSymbolResponse> {
 9876        let peer_id = envelope.original_sender_id().unwrap_or_default();
 9877        let symbol = envelope.payload.symbol.context("invalid symbol")?;
 9878        let symbol = Self::deserialize_symbol(symbol)?;
 9879        this.read_with(&cx, |this, _| {
 9880            if let SymbolLocation::OutsideProject {
 9881                abs_path,
 9882                signature,
 9883            } = &symbol.path
 9884            {
 9885                let new_signature = this.symbol_signature(&abs_path);
 9886                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
 9887            }
 9888            Ok(())
 9889        })??;
 9890        let buffer = this
 9891            .update(&mut cx, |this, cx| {
 9892                this.open_buffer_for_symbol(
 9893                    &Symbol {
 9894                        language_server_name: symbol.language_server_name,
 9895                        source_worktree_id: symbol.source_worktree_id,
 9896                        source_language_server_id: symbol.source_language_server_id,
 9897                        path: symbol.path,
 9898                        name: symbol.name,
 9899                        kind: symbol.kind,
 9900                        range: symbol.range,
 9901                        label: CodeLabel::default(),
 9902                    },
 9903                    cx,
 9904                )
 9905            })?
 9906            .await?;
 9907
 9908        this.update(&mut cx, |this, cx| {
 9909            let is_private = buffer
 9910                .read(cx)
 9911                .file()
 9912                .map(|f| f.is_private())
 9913                .unwrap_or_default();
 9914            if is_private {
 9915                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
 9916            } else {
 9917                this.buffer_store
 9918                    .update(cx, |buffer_store, cx| {
 9919                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
 9920                    })
 9921                    .detach_and_log_err(cx);
 9922                let buffer_id = buffer.read(cx).remote_id().to_proto();
 9923                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
 9924            }
 9925        })?
 9926    }
 9927
 9928    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
 9929        let mut hasher = Sha256::new();
 9930        hasher.update(abs_path.to_string_lossy().as_bytes());
 9931        hasher.update(self.nonce.to_be_bytes());
 9932        hasher.finalize().as_slice().try_into().unwrap()
 9933    }
 9934
 9935    pub async fn handle_get_project_symbols(
 9936        this: Entity<Self>,
 9937        envelope: TypedEnvelope<proto::GetProjectSymbols>,
 9938        mut cx: AsyncApp,
 9939    ) -> Result<proto::GetProjectSymbolsResponse> {
 9940        let symbols = this
 9941            .update(&mut cx, |this, cx| {
 9942                this.symbols(&envelope.payload.query, cx)
 9943            })?
 9944            .await?;
 9945
 9946        Ok(proto::GetProjectSymbolsResponse {
 9947            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
 9948        })
 9949    }
 9950
 9951    pub async fn handle_restart_language_servers(
 9952        this: Entity<Self>,
 9953        envelope: TypedEnvelope<proto::RestartLanguageServers>,
 9954        mut cx: AsyncApp,
 9955    ) -> Result<proto::Ack> {
 9956        this.update(&mut cx, |lsp_store, cx| {
 9957            let buffers =
 9958                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9959            lsp_store.restart_language_servers_for_buffers(
 9960                buffers,
 9961                envelope
 9962                    .payload
 9963                    .only_servers
 9964                    .into_iter()
 9965                    .filter_map(|selector| {
 9966                        Some(match selector.selector? {
 9967                            proto::language_server_selector::Selector::ServerId(server_id) => {
 9968                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 9969                            }
 9970                            proto::language_server_selector::Selector::Name(name) => {
 9971                                LanguageServerSelector::Name(LanguageServerName(
 9972                                    SharedString::from(name),
 9973                                ))
 9974                            }
 9975                        })
 9976                    })
 9977                    .collect(),
 9978                cx,
 9979            );
 9980        })?;
 9981
 9982        Ok(proto::Ack {})
 9983    }
 9984
 9985    pub async fn handle_stop_language_servers(
 9986        lsp_store: Entity<Self>,
 9987        envelope: TypedEnvelope<proto::StopLanguageServers>,
 9988        mut cx: AsyncApp,
 9989    ) -> Result<proto::Ack> {
 9990        lsp_store.update(&mut cx, |lsp_store, cx| {
 9991            if envelope.payload.all
 9992                && envelope.payload.also_servers.is_empty()
 9993                && envelope.payload.buffer_ids.is_empty()
 9994            {
 9995                lsp_store.stop_all_language_servers(cx);
 9996            } else {
 9997                let buffers =
 9998                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
 9999                lsp_store
10000                    .stop_language_servers_for_buffers(
10001                        buffers,
10002                        envelope
10003                            .payload
10004                            .also_servers
10005                            .into_iter()
10006                            .filter_map(|selector| {
10007                                Some(match selector.selector? {
10008                                    proto::language_server_selector::Selector::ServerId(
10009                                        server_id,
10010                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10011                                        server_id,
10012                                    )),
10013                                    proto::language_server_selector::Selector::Name(name) => {
10014                                        LanguageServerSelector::Name(LanguageServerName(
10015                                            SharedString::from(name),
10016                                        ))
10017                                    }
10018                                })
10019                            })
10020                            .collect(),
10021                        cx,
10022                    )
10023                    .detach_and_log_err(cx);
10024            }
10025        })?;
10026
10027        Ok(proto::Ack {})
10028    }
10029
10030    pub async fn handle_cancel_language_server_work(
10031        lsp_store: Entity<Self>,
10032        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10033        mut cx: AsyncApp,
10034    ) -> Result<proto::Ack> {
10035        lsp_store.update(&mut cx, |lsp_store, cx| {
10036            if let Some(work) = envelope.payload.work {
10037                match work {
10038                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10039                        let buffers =
10040                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10041                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10042                    }
10043                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10044                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10045                        let token = work
10046                            .token
10047                            .map(|token| {
10048                                ProgressToken::from_proto(token)
10049                                    .context("invalid work progress token")
10050                            })
10051                            .transpose()?;
10052                        lsp_store.cancel_language_server_work(server_id, token, cx);
10053                    }
10054                }
10055            }
10056            anyhow::Ok(())
10057        })??;
10058
10059        Ok(proto::Ack {})
10060    }
10061
10062    fn buffer_ids_to_buffers(
10063        &mut self,
10064        buffer_ids: impl Iterator<Item = u64>,
10065        cx: &mut Context<Self>,
10066    ) -> Vec<Entity<Buffer>> {
10067        buffer_ids
10068            .into_iter()
10069            .flat_map(|buffer_id| {
10070                self.buffer_store
10071                    .read(cx)
10072                    .get(BufferId::new(buffer_id).log_err()?)
10073            })
10074            .collect::<Vec<_>>()
10075    }
10076
10077    async fn handle_apply_additional_edits_for_completion(
10078        this: Entity<Self>,
10079        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10080        mut cx: AsyncApp,
10081    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10082        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10083            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10084            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10085            let completion = Self::deserialize_completion(
10086                envelope.payload.completion.context("invalid completion")?,
10087            )?;
10088            anyhow::Ok((buffer, completion))
10089        })??;
10090
10091        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10092            this.apply_additional_edits_for_completion(
10093                buffer,
10094                Rc::new(RefCell::new(Box::new([Completion {
10095                    replace_range: completion.replace_range,
10096                    new_text: completion.new_text,
10097                    source: completion.source,
10098                    documentation: None,
10099                    label: CodeLabel::default(),
10100                    insert_text_mode: None,
10101                    icon_path: None,
10102                    confirm: None,
10103                }]))),
10104                0,
10105                false,
10106                cx,
10107            )
10108        })?;
10109
10110        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10111            transaction: apply_additional_edits
10112                .await?
10113                .as_ref()
10114                .map(language::proto::serialize_transaction),
10115        })
10116    }
10117
10118    pub fn last_formatting_failure(&self) -> Option<&str> {
10119        self.last_formatting_failure.as_deref()
10120    }
10121
10122    pub fn reset_last_formatting_failure(&mut self) {
10123        self.last_formatting_failure = None;
10124    }
10125
10126    pub fn environment_for_buffer(
10127        &self,
10128        buffer: &Entity<Buffer>,
10129        cx: &mut Context<Self>,
10130    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10131        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10132            environment.update(cx, |env, cx| {
10133                env.get_buffer_environment(buffer, &self.worktree_store, cx)
10134            })
10135        } else {
10136            Task::ready(None).shared()
10137        }
10138    }
10139
10140    pub fn format(
10141        &mut self,
10142        buffers: HashSet<Entity<Buffer>>,
10143        target: LspFormatTarget,
10144        push_to_history: bool,
10145        trigger: FormatTrigger,
10146        cx: &mut Context<Self>,
10147    ) -> Task<anyhow::Result<ProjectTransaction>> {
10148        let logger = zlog::scoped!("format");
10149        if self.as_local().is_some() {
10150            zlog::trace!(logger => "Formatting locally");
10151            let logger = zlog::scoped!(logger => "local");
10152            let buffers = buffers
10153                .into_iter()
10154                .map(|buffer_handle| {
10155                    let buffer = buffer_handle.read(cx);
10156                    let buffer_abs_path = File::from_dyn(buffer.file())
10157                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10158
10159                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10160                })
10161                .collect::<Vec<_>>();
10162
10163            cx.spawn(async move |lsp_store, cx| {
10164                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10165
10166                for (handle, abs_path, id) in buffers {
10167                    let env = lsp_store
10168                        .update(cx, |lsp_store, cx| {
10169                            lsp_store.environment_for_buffer(&handle, cx)
10170                        })?
10171                        .await;
10172
10173                    let ranges = match &target {
10174                        LspFormatTarget::Buffers => None,
10175                        LspFormatTarget::Ranges(ranges) => {
10176                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10177                        }
10178                    };
10179
10180                    formattable_buffers.push(FormattableBuffer {
10181                        handle,
10182                        abs_path,
10183                        env,
10184                        ranges,
10185                    });
10186                }
10187                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10188
10189                let format_timer = zlog::time!(logger => "Formatting buffers");
10190                let result = LocalLspStore::format_locally(
10191                    lsp_store.clone(),
10192                    formattable_buffers,
10193                    push_to_history,
10194                    trigger,
10195                    logger,
10196                    cx,
10197                )
10198                .await;
10199                format_timer.end();
10200
10201                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10202
10203                lsp_store.update(cx, |lsp_store, _| {
10204                    lsp_store.update_last_formatting_failure(&result);
10205                })?;
10206
10207                result
10208            })
10209        } else if let Some((client, project_id)) = self.upstream_client() {
10210            zlog::trace!(logger => "Formatting remotely");
10211            let logger = zlog::scoped!(logger => "remote");
10212            // Don't support formatting ranges via remote
10213            match target {
10214                LspFormatTarget::Buffers => {}
10215                LspFormatTarget::Ranges(_) => {
10216                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10217                    return Task::ready(Ok(ProjectTransaction::default()));
10218                }
10219            }
10220
10221            let buffer_store = self.buffer_store();
10222            cx.spawn(async move |lsp_store, cx| {
10223                zlog::trace!(logger => "Sending remote format request");
10224                let request_timer = zlog::time!(logger => "remote format request");
10225                let result = client
10226                    .request(proto::FormatBuffers {
10227                        project_id,
10228                        trigger: trigger as i32,
10229                        buffer_ids: buffers
10230                            .iter()
10231                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10232                            .collect::<Result<_>>()?,
10233                    })
10234                    .await
10235                    .and_then(|result| result.transaction.context("missing transaction"));
10236                request_timer.end();
10237
10238                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10239
10240                lsp_store.update(cx, |lsp_store, _| {
10241                    lsp_store.update_last_formatting_failure(&result);
10242                })?;
10243
10244                let transaction_response = result?;
10245                let _timer = zlog::time!(logger => "deserializing project transaction");
10246                buffer_store
10247                    .update(cx, |buffer_store, cx| {
10248                        buffer_store.deserialize_project_transaction(
10249                            transaction_response,
10250                            push_to_history,
10251                            cx,
10252                        )
10253                    })?
10254                    .await
10255            })
10256        } else {
10257            zlog::trace!(logger => "Not formatting");
10258            Task::ready(Ok(ProjectTransaction::default()))
10259        }
10260    }
10261
10262    async fn handle_format_buffers(
10263        this: Entity<Self>,
10264        envelope: TypedEnvelope<proto::FormatBuffers>,
10265        mut cx: AsyncApp,
10266    ) -> Result<proto::FormatBuffersResponse> {
10267        let sender_id = envelope.original_sender_id().unwrap_or_default();
10268        let format = this.update(&mut cx, |this, cx| {
10269            let mut buffers = HashSet::default();
10270            for buffer_id in &envelope.payload.buffer_ids {
10271                let buffer_id = BufferId::new(*buffer_id)?;
10272                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10273            }
10274            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10275            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10276        })??;
10277
10278        let project_transaction = format.await?;
10279        let project_transaction = this.update(&mut cx, |this, cx| {
10280            this.buffer_store.update(cx, |buffer_store, cx| {
10281                buffer_store.serialize_project_transaction_for_peer(
10282                    project_transaction,
10283                    sender_id,
10284                    cx,
10285                )
10286            })
10287        })?;
10288        Ok(proto::FormatBuffersResponse {
10289            transaction: Some(project_transaction),
10290        })
10291    }
10292
10293    async fn handle_apply_code_action_kind(
10294        this: Entity<Self>,
10295        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10296        mut cx: AsyncApp,
10297    ) -> Result<proto::ApplyCodeActionKindResponse> {
10298        let sender_id = envelope.original_sender_id().unwrap_or_default();
10299        let format = this.update(&mut cx, |this, cx| {
10300            let mut buffers = HashSet::default();
10301            for buffer_id in &envelope.payload.buffer_ids {
10302                let buffer_id = BufferId::new(*buffer_id)?;
10303                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10304            }
10305            let kind = match envelope.payload.kind.as_str() {
10306                "" => CodeActionKind::EMPTY,
10307                "quickfix" => CodeActionKind::QUICKFIX,
10308                "refactor" => CodeActionKind::REFACTOR,
10309                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10310                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10311                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10312                "source" => CodeActionKind::SOURCE,
10313                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10314                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10315                _ => anyhow::bail!(
10316                    "Invalid code action kind {}",
10317                    envelope.payload.kind.as_str()
10318                ),
10319            };
10320            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10321        })??;
10322
10323        let project_transaction = format.await?;
10324        let project_transaction = this.update(&mut cx, |this, cx| {
10325            this.buffer_store.update(cx, |buffer_store, cx| {
10326                buffer_store.serialize_project_transaction_for_peer(
10327                    project_transaction,
10328                    sender_id,
10329                    cx,
10330                )
10331            })
10332        })?;
10333        Ok(proto::ApplyCodeActionKindResponse {
10334            transaction: Some(project_transaction),
10335        })
10336    }
10337
10338    async fn shutdown_language_server(
10339        server_state: Option<LanguageServerState>,
10340        name: LanguageServerName,
10341        cx: &mut AsyncApp,
10342    ) {
10343        let server = match server_state {
10344            Some(LanguageServerState::Starting { startup, .. }) => {
10345                let mut timer = cx
10346                    .background_executor()
10347                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10348                    .fuse();
10349
10350                select! {
10351                    server = startup.fuse() => server,
10352                    () = timer => {
10353                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10354                        None
10355                    },
10356                }
10357            }
10358
10359            Some(LanguageServerState::Running { server, .. }) => Some(server),
10360
10361            None => None,
10362        };
10363
10364        if let Some(server) = server
10365            && let Some(shutdown) = server.shutdown()
10366        {
10367            shutdown.await;
10368        }
10369    }
10370
10371    // Returns a list of all of the worktrees which no longer have a language server and the root path
10372    // for the stopped server
10373    fn stop_local_language_server(
10374        &mut self,
10375        server_id: LanguageServerId,
10376        cx: &mut Context<Self>,
10377    ) -> Task<()> {
10378        let local = match &mut self.mode {
10379            LspStoreMode::Local(local) => local,
10380            _ => {
10381                return Task::ready(());
10382            }
10383        };
10384
10385        // Remove this server ID from all entries in the given worktree.
10386        local
10387            .language_server_ids
10388            .retain(|_, state| state.id != server_id);
10389        self.buffer_store.update(cx, |buffer_store, cx| {
10390            for buffer in buffer_store.buffers() {
10391                buffer.update(cx, |buffer, cx| {
10392                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10393                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10394                });
10395            }
10396        });
10397
10398        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10399            summaries.retain(|path, summaries_by_server_id| {
10400                if summaries_by_server_id.remove(&server_id).is_some() {
10401                    if let Some((client, project_id)) = self.downstream_client.clone() {
10402                        client
10403                            .send(proto::UpdateDiagnosticSummary {
10404                                project_id,
10405                                worktree_id: worktree_id.to_proto(),
10406                                summary: Some(proto::DiagnosticSummary {
10407                                    path: path.as_ref().to_proto(),
10408                                    language_server_id: server_id.0 as u64,
10409                                    error_count: 0,
10410                                    warning_count: 0,
10411                                }),
10412                                more_summaries: Vec::new(),
10413                            })
10414                            .log_err();
10415                    }
10416                    !summaries_by_server_id.is_empty()
10417                } else {
10418                    true
10419                }
10420            });
10421        }
10422
10423        let local = self.as_local_mut().unwrap();
10424        for diagnostics in local.diagnostics.values_mut() {
10425            diagnostics.retain(|_, diagnostics_by_server_id| {
10426                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10427                    diagnostics_by_server_id.remove(ix);
10428                    !diagnostics_by_server_id.is_empty()
10429                } else {
10430                    true
10431                }
10432            });
10433        }
10434        local.language_server_watched_paths.remove(&server_id);
10435
10436        let server_state = local.language_servers.remove(&server_id);
10437        self.cleanup_lsp_data(server_id);
10438        let name = self
10439            .language_server_statuses
10440            .remove(&server_id)
10441            .map(|status| status.name)
10442            .or_else(|| {
10443                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10444                    Some(adapter.name())
10445                } else {
10446                    None
10447                }
10448            });
10449
10450        if let Some(name) = name {
10451            log::info!("stopping language server {name}");
10452            self.languages
10453                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10454            cx.notify();
10455
10456            return cx.spawn(async move |lsp_store, cx| {
10457                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10458                lsp_store
10459                    .update(cx, |lsp_store, cx| {
10460                        lsp_store
10461                            .languages
10462                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10463                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10464                        cx.notify();
10465                    })
10466                    .ok();
10467            });
10468        }
10469
10470        if server_state.is_some() {
10471            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10472        }
10473        Task::ready(())
10474    }
10475
10476    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10477        if let Some((client, project_id)) = self.upstream_client() {
10478            let request = client.request(proto::StopLanguageServers {
10479                project_id,
10480                buffer_ids: Vec::new(),
10481                also_servers: Vec::new(),
10482                all: true,
10483            });
10484            cx.background_spawn(request).detach_and_log_err(cx);
10485        } else {
10486            let Some(local) = self.as_local_mut() else {
10487                return;
10488            };
10489            let language_servers_to_stop = local
10490                .language_server_ids
10491                .values()
10492                .map(|state| state.id)
10493                .collect();
10494            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10495            let tasks = language_servers_to_stop
10496                .into_iter()
10497                .map(|server| self.stop_local_language_server(server, cx))
10498                .collect::<Vec<_>>();
10499            cx.background_spawn(async move {
10500                futures::future::join_all(tasks).await;
10501            })
10502            .detach();
10503        }
10504    }
10505
10506    pub fn restart_language_servers_for_buffers(
10507        &mut self,
10508        buffers: Vec<Entity<Buffer>>,
10509        only_restart_servers: HashSet<LanguageServerSelector>,
10510        cx: &mut Context<Self>,
10511    ) {
10512        if let Some((client, project_id)) = self.upstream_client() {
10513            let request = client.request(proto::RestartLanguageServers {
10514                project_id,
10515                buffer_ids: buffers
10516                    .into_iter()
10517                    .map(|b| b.read(cx).remote_id().to_proto())
10518                    .collect(),
10519                only_servers: only_restart_servers
10520                    .into_iter()
10521                    .map(|selector| {
10522                        let selector = match selector {
10523                            LanguageServerSelector::Id(language_server_id) => {
10524                                proto::language_server_selector::Selector::ServerId(
10525                                    language_server_id.to_proto(),
10526                                )
10527                            }
10528                            LanguageServerSelector::Name(language_server_name) => {
10529                                proto::language_server_selector::Selector::Name(
10530                                    language_server_name.to_string(),
10531                                )
10532                            }
10533                        };
10534                        proto::LanguageServerSelector {
10535                            selector: Some(selector),
10536                        }
10537                    })
10538                    .collect(),
10539                all: false,
10540            });
10541            cx.background_spawn(request).detach_and_log_err(cx);
10542        } else {
10543            let stop_task = if only_restart_servers.is_empty() {
10544                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10545            } else {
10546                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10547            };
10548            cx.spawn(async move |lsp_store, cx| {
10549                stop_task.await;
10550                lsp_store
10551                    .update(cx, |lsp_store, cx| {
10552                        for buffer in buffers {
10553                            lsp_store.register_buffer_with_language_servers(
10554                                &buffer,
10555                                only_restart_servers.clone(),
10556                                true,
10557                                cx,
10558                            );
10559                        }
10560                    })
10561                    .ok()
10562            })
10563            .detach();
10564        }
10565    }
10566
10567    pub fn stop_language_servers_for_buffers(
10568        &mut self,
10569        buffers: Vec<Entity<Buffer>>,
10570        also_stop_servers: HashSet<LanguageServerSelector>,
10571        cx: &mut Context<Self>,
10572    ) -> Task<Result<()>> {
10573        if let Some((client, project_id)) = self.upstream_client() {
10574            let request = client.request(proto::StopLanguageServers {
10575                project_id,
10576                buffer_ids: buffers
10577                    .into_iter()
10578                    .map(|b| b.read(cx).remote_id().to_proto())
10579                    .collect(),
10580                also_servers: also_stop_servers
10581                    .into_iter()
10582                    .map(|selector| {
10583                        let selector = match selector {
10584                            LanguageServerSelector::Id(language_server_id) => {
10585                                proto::language_server_selector::Selector::ServerId(
10586                                    language_server_id.to_proto(),
10587                                )
10588                            }
10589                            LanguageServerSelector::Name(language_server_name) => {
10590                                proto::language_server_selector::Selector::Name(
10591                                    language_server_name.to_string(),
10592                                )
10593                            }
10594                        };
10595                        proto::LanguageServerSelector {
10596                            selector: Some(selector),
10597                        }
10598                    })
10599                    .collect(),
10600                all: false,
10601            });
10602            cx.background_spawn(async move {
10603                let _ = request.await?;
10604                Ok(())
10605            })
10606        } else {
10607            let task =
10608                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10609            cx.background_spawn(async move {
10610                task.await;
10611                Ok(())
10612            })
10613        }
10614    }
10615
10616    fn stop_local_language_servers_for_buffers(
10617        &mut self,
10618        buffers: &[Entity<Buffer>],
10619        also_stop_servers: HashSet<LanguageServerSelector>,
10620        cx: &mut Context<Self>,
10621    ) -> Task<()> {
10622        let Some(local) = self.as_local_mut() else {
10623            return Task::ready(());
10624        };
10625        let mut language_server_names_to_stop = BTreeSet::default();
10626        let mut language_servers_to_stop = also_stop_servers
10627            .into_iter()
10628            .flat_map(|selector| match selector {
10629                LanguageServerSelector::Id(id) => Some(id),
10630                LanguageServerSelector::Name(name) => {
10631                    language_server_names_to_stop.insert(name);
10632                    None
10633                }
10634            })
10635            .collect::<BTreeSet<_>>();
10636
10637        let mut covered_worktrees = HashSet::default();
10638        for buffer in buffers {
10639            buffer.update(cx, |buffer, cx| {
10640                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
10641                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
10642                    && covered_worktrees.insert(worktree_id)
10643                {
10644                    language_server_names_to_stop.retain(|name| {
10645                        let old_ids_count = language_servers_to_stop.len();
10646                        let all_language_servers_with_this_name = local
10647                            .language_server_ids
10648                            .iter()
10649                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
10650                        language_servers_to_stop.extend(all_language_servers_with_this_name);
10651                        old_ids_count == language_servers_to_stop.len()
10652                    });
10653                }
10654            });
10655        }
10656        for name in language_server_names_to_stop {
10657            language_servers_to_stop.extend(
10658                local
10659                    .language_server_ids
10660                    .iter()
10661                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
10662            );
10663        }
10664
10665        local.lsp_tree.remove_nodes(&language_servers_to_stop);
10666        let tasks = language_servers_to_stop
10667            .into_iter()
10668            .map(|server| self.stop_local_language_server(server, cx))
10669            .collect::<Vec<_>>();
10670
10671        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
10672    }
10673
10674    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
10675        let (worktree, relative_path) =
10676            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
10677
10678        let project_path = ProjectPath {
10679            worktree_id: worktree.read(cx).id(),
10680            path: relative_path,
10681        };
10682
10683        Some(
10684            self.buffer_store()
10685                .read(cx)
10686                .get_by_path(&project_path)?
10687                .read(cx),
10688        )
10689    }
10690
10691    #[cfg(any(test, feature = "test-support"))]
10692    pub fn update_diagnostics(
10693        &mut self,
10694        server_id: LanguageServerId,
10695        diagnostics: lsp::PublishDiagnosticsParams,
10696        result_id: Option<String>,
10697        source_kind: DiagnosticSourceKind,
10698        disk_based_sources: &[String],
10699        cx: &mut Context<Self>,
10700    ) -> Result<()> {
10701        self.merge_lsp_diagnostics(
10702            source_kind,
10703            vec![DocumentDiagnosticsUpdate {
10704                diagnostics,
10705                result_id,
10706                server_id,
10707                disk_based_sources: Cow::Borrowed(disk_based_sources),
10708            }],
10709            |_, _, _| false,
10710            cx,
10711        )
10712    }
10713
10714    pub fn merge_lsp_diagnostics(
10715        &mut self,
10716        source_kind: DiagnosticSourceKind,
10717        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
10718        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
10719        cx: &mut Context<Self>,
10720    ) -> Result<()> {
10721        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
10722        let updates = lsp_diagnostics
10723            .into_iter()
10724            .filter_map(|update| {
10725                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
10726                Some(DocumentDiagnosticsUpdate {
10727                    diagnostics: self.lsp_to_document_diagnostics(
10728                        abs_path,
10729                        source_kind,
10730                        update.server_id,
10731                        update.diagnostics,
10732                        &update.disk_based_sources,
10733                    ),
10734                    result_id: update.result_id,
10735                    server_id: update.server_id,
10736                    disk_based_sources: update.disk_based_sources,
10737                })
10738            })
10739            .collect();
10740        self.merge_diagnostic_entries(updates, merge, cx)?;
10741        Ok(())
10742    }
10743
10744    fn lsp_to_document_diagnostics(
10745        &mut self,
10746        document_abs_path: PathBuf,
10747        source_kind: DiagnosticSourceKind,
10748        server_id: LanguageServerId,
10749        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
10750        disk_based_sources: &[String],
10751    ) -> DocumentDiagnostics {
10752        let mut diagnostics = Vec::default();
10753        let mut primary_diagnostic_group_ids = HashMap::default();
10754        let mut sources_by_group_id = HashMap::default();
10755        let mut supporting_diagnostics = HashMap::default();
10756
10757        let adapter = self.language_server_adapter_for_id(server_id);
10758
10759        // Ensure that primary diagnostics are always the most severe
10760        lsp_diagnostics
10761            .diagnostics
10762            .sort_by_key(|item| item.severity);
10763
10764        for diagnostic in &lsp_diagnostics.diagnostics {
10765            let source = diagnostic.source.as_ref();
10766            let range = range_from_lsp(diagnostic.range);
10767            let is_supporting = diagnostic
10768                .related_information
10769                .as_ref()
10770                .is_some_and(|infos| {
10771                    infos.iter().any(|info| {
10772                        primary_diagnostic_group_ids.contains_key(&(
10773                            source,
10774                            diagnostic.code.clone(),
10775                            range_from_lsp(info.location.range),
10776                        ))
10777                    })
10778                });
10779
10780            let is_unnecessary = diagnostic
10781                .tags
10782                .as_ref()
10783                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
10784
10785            let underline = self
10786                .language_server_adapter_for_id(server_id)
10787                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
10788
10789            if is_supporting {
10790                supporting_diagnostics.insert(
10791                    (source, diagnostic.code.clone(), range),
10792                    (diagnostic.severity, is_unnecessary),
10793                );
10794            } else {
10795                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
10796                let is_disk_based =
10797                    source.is_some_and(|source| disk_based_sources.contains(source));
10798
10799                sources_by_group_id.insert(group_id, source);
10800                primary_diagnostic_group_ids
10801                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
10802
10803                diagnostics.push(DiagnosticEntry {
10804                    range,
10805                    diagnostic: Diagnostic {
10806                        source: diagnostic.source.clone(),
10807                        source_kind,
10808                        code: diagnostic.code.clone(),
10809                        code_description: diagnostic
10810                            .code_description
10811                            .as_ref()
10812                            .and_then(|d| d.href.clone()),
10813                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
10814                        markdown: adapter.as_ref().and_then(|adapter| {
10815                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
10816                        }),
10817                        message: diagnostic.message.trim().to_string(),
10818                        group_id,
10819                        is_primary: true,
10820                        is_disk_based,
10821                        is_unnecessary,
10822                        underline,
10823                        data: diagnostic.data.clone(),
10824                    },
10825                });
10826                if let Some(infos) = &diagnostic.related_information {
10827                    for info in infos {
10828                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
10829                            let range = range_from_lsp(info.location.range);
10830                            diagnostics.push(DiagnosticEntry {
10831                                range,
10832                                diagnostic: Diagnostic {
10833                                    source: diagnostic.source.clone(),
10834                                    source_kind,
10835                                    code: diagnostic.code.clone(),
10836                                    code_description: diagnostic
10837                                        .code_description
10838                                        .as_ref()
10839                                        .and_then(|d| d.href.clone()),
10840                                    severity: DiagnosticSeverity::INFORMATION,
10841                                    markdown: adapter.as_ref().and_then(|adapter| {
10842                                        adapter.diagnostic_message_to_markdown(&info.message)
10843                                    }),
10844                                    message: info.message.trim().to_string(),
10845                                    group_id,
10846                                    is_primary: false,
10847                                    is_disk_based,
10848                                    is_unnecessary: false,
10849                                    underline,
10850                                    data: diagnostic.data.clone(),
10851                                },
10852                            });
10853                        }
10854                    }
10855                }
10856            }
10857        }
10858
10859        for entry in &mut diagnostics {
10860            let diagnostic = &mut entry.diagnostic;
10861            if !diagnostic.is_primary {
10862                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
10863                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
10864                    source,
10865                    diagnostic.code.clone(),
10866                    entry.range.clone(),
10867                )) {
10868                    if let Some(severity) = severity {
10869                        diagnostic.severity = severity;
10870                    }
10871                    diagnostic.is_unnecessary = is_unnecessary;
10872                }
10873            }
10874        }
10875
10876        DocumentDiagnostics {
10877            diagnostics,
10878            document_abs_path,
10879            version: lsp_diagnostics.version,
10880        }
10881    }
10882
10883    fn insert_newly_running_language_server(
10884        &mut self,
10885        adapter: Arc<CachedLspAdapter>,
10886        language_server: Arc<LanguageServer>,
10887        server_id: LanguageServerId,
10888        key: LanguageServerSeed,
10889        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
10890        cx: &mut Context<Self>,
10891    ) {
10892        let Some(local) = self.as_local_mut() else {
10893            return;
10894        };
10895        // If the language server for this key doesn't match the server id, don't store the
10896        // server. Which will cause it to be dropped, killing the process
10897        if local
10898            .language_server_ids
10899            .get(&key)
10900            .map(|state| state.id != server_id)
10901            .unwrap_or(false)
10902        {
10903            return;
10904        }
10905
10906        // Update language_servers collection with Running variant of LanguageServerState
10907        // indicating that the server is up and running and ready
10908        let workspace_folders = workspace_folders.lock().clone();
10909        language_server.set_workspace_folders(workspace_folders);
10910
10911        let workspace_diagnostics_refresh_tasks = language_server
10912            .capabilities()
10913            .diagnostic_provider
10914            .and_then(|provider| {
10915                local
10916                    .language_server_dynamic_registrations
10917                    .entry(server_id)
10918                    .or_default()
10919                    .diagnostics
10920                    .entry(None)
10921                    .or_insert(provider.clone());
10922                let workspace_refresher =
10923                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
10924
10925                Some((None, workspace_refresher))
10926            })
10927            .into_iter()
10928            .collect();
10929        local.language_servers.insert(
10930            server_id,
10931            LanguageServerState::Running {
10932                workspace_diagnostics_refresh_tasks,
10933                adapter: adapter.clone(),
10934                server: language_server.clone(),
10935                simulate_disk_based_diagnostics_completion: None,
10936            },
10937        );
10938        local
10939            .languages
10940            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
10941        if let Some(file_ops_caps) = language_server
10942            .capabilities()
10943            .workspace
10944            .as_ref()
10945            .and_then(|ws| ws.file_operations.as_ref())
10946        {
10947            let did_rename_caps = file_ops_caps.did_rename.as_ref();
10948            let will_rename_caps = file_ops_caps.will_rename.as_ref();
10949            if did_rename_caps.or(will_rename_caps).is_some() {
10950                let watcher = RenamePathsWatchedForServer::default()
10951                    .with_did_rename_patterns(did_rename_caps)
10952                    .with_will_rename_patterns(will_rename_caps);
10953                local
10954                    .language_server_paths_watched_for_rename
10955                    .insert(server_id, watcher);
10956            }
10957        }
10958
10959        self.language_server_statuses.insert(
10960            server_id,
10961            LanguageServerStatus {
10962                name: language_server.name(),
10963                pending_work: Default::default(),
10964                has_pending_diagnostic_updates: false,
10965                progress_tokens: Default::default(),
10966                worktree: Some(key.worktree_id),
10967            },
10968        );
10969
10970        cx.emit(LspStoreEvent::LanguageServerAdded(
10971            server_id,
10972            language_server.name(),
10973            Some(key.worktree_id),
10974        ));
10975        cx.emit(LspStoreEvent::RefreshInlayHints(server_id));
10976
10977        let server_capabilities = language_server.capabilities();
10978        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
10979            downstream_client
10980                .send(proto::StartLanguageServer {
10981                    project_id: *project_id,
10982                    server: Some(proto::LanguageServer {
10983                        id: server_id.to_proto(),
10984                        name: language_server.name().to_string(),
10985                        worktree_id: Some(key.worktree_id.to_proto()),
10986                    }),
10987                    capabilities: serde_json::to_string(&server_capabilities)
10988                        .expect("serializing server LSP capabilities"),
10989                })
10990                .log_err();
10991        }
10992        self.lsp_server_capabilities
10993            .insert(server_id, server_capabilities);
10994
10995        // Tell the language server about every open buffer in the worktree that matches the language.
10996        // Also check for buffers in worktrees that reused this server
10997        let mut worktrees_using_server = vec![key.worktree_id];
10998        if let Some(local) = self.as_local() {
10999            // Find all worktrees that have this server in their language server tree
11000            for (worktree_id, servers) in &local.lsp_tree.instances {
11001                if *worktree_id != key.worktree_id {
11002                    for server_map in servers.roots.values() {
11003                        if server_map
11004                            .values()
11005                            .any(|(node, _)| node.id() == Some(server_id))
11006                        {
11007                            worktrees_using_server.push(*worktree_id);
11008                        }
11009                    }
11010                }
11011            }
11012        }
11013
11014        let mut buffer_paths_registered = Vec::new();
11015        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11016            let mut lsp_adapters = HashMap::default();
11017            for buffer_handle in buffer_store.buffers() {
11018                let buffer = buffer_handle.read(cx);
11019                let file = match File::from_dyn(buffer.file()) {
11020                    Some(file) => file,
11021                    None => continue,
11022                };
11023                let language = match buffer.language() {
11024                    Some(language) => language,
11025                    None => continue,
11026                };
11027
11028                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11029                    || !lsp_adapters
11030                        .entry(language.name())
11031                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11032                        .iter()
11033                        .any(|a| a.name == key.name)
11034                {
11035                    continue;
11036                }
11037                // didOpen
11038                let file = match file.as_local() {
11039                    Some(file) => file,
11040                    None => continue,
11041                };
11042
11043                let local = self.as_local_mut().unwrap();
11044
11045                let buffer_id = buffer.remote_id();
11046                if local.registered_buffers.contains_key(&buffer_id) {
11047                    let versions = local
11048                        .buffer_snapshots
11049                        .entry(buffer_id)
11050                        .or_default()
11051                        .entry(server_id)
11052                        .and_modify(|_| {
11053                            assert!(
11054                            false,
11055                            "There should not be an existing snapshot for a newly inserted buffer"
11056                        )
11057                        })
11058                        .or_insert_with(|| {
11059                            vec![LspBufferSnapshot {
11060                                version: 0,
11061                                snapshot: buffer.text_snapshot(),
11062                            }]
11063                        });
11064
11065                    let snapshot = versions.last().unwrap();
11066                    let version = snapshot.version;
11067                    let initial_snapshot = &snapshot.snapshot;
11068                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11069                    language_server.register_buffer(
11070                        uri,
11071                        adapter.language_id(&language.name()),
11072                        version,
11073                        initial_snapshot.text(),
11074                    );
11075                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11076                    local
11077                        .buffers_opened_in_servers
11078                        .entry(buffer_id)
11079                        .or_default()
11080                        .insert(server_id);
11081                }
11082                buffer_handle.update(cx, |buffer, cx| {
11083                    buffer.set_completion_triggers(
11084                        server_id,
11085                        language_server
11086                            .capabilities()
11087                            .completion_provider
11088                            .as_ref()
11089                            .and_then(|provider| {
11090                                provider
11091                                    .trigger_characters
11092                                    .as_ref()
11093                                    .map(|characters| characters.iter().cloned().collect())
11094                            })
11095                            .unwrap_or_default(),
11096                        cx,
11097                    )
11098                });
11099            }
11100        });
11101
11102        for (buffer_id, abs_path) in buffer_paths_registered {
11103            cx.emit(LspStoreEvent::LanguageServerUpdate {
11104                language_server_id: server_id,
11105                name: Some(adapter.name()),
11106                message: proto::update_language_server::Variant::RegisteredForBuffer(
11107                    proto::RegisteredForBuffer {
11108                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11109                        buffer_id: buffer_id.to_proto(),
11110                    },
11111                ),
11112            });
11113        }
11114
11115        cx.notify();
11116    }
11117
11118    pub fn language_servers_running_disk_based_diagnostics(
11119        &self,
11120    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11121        self.language_server_statuses
11122            .iter()
11123            .filter_map(|(id, status)| {
11124                if status.has_pending_diagnostic_updates {
11125                    Some(*id)
11126                } else {
11127                    None
11128                }
11129            })
11130    }
11131
11132    pub(crate) fn cancel_language_server_work_for_buffers(
11133        &mut self,
11134        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11135        cx: &mut Context<Self>,
11136    ) {
11137        if let Some((client, project_id)) = self.upstream_client() {
11138            let request = client.request(proto::CancelLanguageServerWork {
11139                project_id,
11140                work: Some(proto::cancel_language_server_work::Work::Buffers(
11141                    proto::cancel_language_server_work::Buffers {
11142                        buffer_ids: buffers
11143                            .into_iter()
11144                            .map(|b| b.read(cx).remote_id().to_proto())
11145                            .collect(),
11146                    },
11147                )),
11148            });
11149            cx.background_spawn(request).detach_and_log_err(cx);
11150        } else if let Some(local) = self.as_local() {
11151            let servers = buffers
11152                .into_iter()
11153                .flat_map(|buffer| {
11154                    buffer.update(cx, |buffer, cx| {
11155                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11156                    })
11157                })
11158                .collect::<HashSet<_>>();
11159            for server_id in servers {
11160                self.cancel_language_server_work(server_id, None, cx);
11161            }
11162        }
11163    }
11164
11165    pub(crate) fn cancel_language_server_work(
11166        &mut self,
11167        server_id: LanguageServerId,
11168        token_to_cancel: Option<ProgressToken>,
11169        cx: &mut Context<Self>,
11170    ) {
11171        if let Some(local) = self.as_local() {
11172            let status = self.language_server_statuses.get(&server_id);
11173            let server = local.language_servers.get(&server_id);
11174            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11175            {
11176                for (token, progress) in &status.pending_work {
11177                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11178                        && token != token_to_cancel
11179                    {
11180                        continue;
11181                    }
11182                    if progress.is_cancellable {
11183                        server
11184                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11185                                WorkDoneProgressCancelParams {
11186                                    token: token.to_lsp(),
11187                                },
11188                            )
11189                            .ok();
11190                    }
11191                }
11192            }
11193        } else if let Some((client, project_id)) = self.upstream_client() {
11194            let request = client.request(proto::CancelLanguageServerWork {
11195                project_id,
11196                work: Some(
11197                    proto::cancel_language_server_work::Work::LanguageServerWork(
11198                        proto::cancel_language_server_work::LanguageServerWork {
11199                            language_server_id: server_id.to_proto(),
11200                            token: token_to_cancel.map(|token| token.to_proto()),
11201                        },
11202                    ),
11203                ),
11204            });
11205            cx.background_spawn(request).detach_and_log_err(cx);
11206        }
11207    }
11208
11209    fn register_supplementary_language_server(
11210        &mut self,
11211        id: LanguageServerId,
11212        name: LanguageServerName,
11213        server: Arc<LanguageServer>,
11214        cx: &mut Context<Self>,
11215    ) {
11216        if let Some(local) = self.as_local_mut() {
11217            local
11218                .supplementary_language_servers
11219                .insert(id, (name.clone(), server));
11220            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11221        }
11222    }
11223
11224    fn unregister_supplementary_language_server(
11225        &mut self,
11226        id: LanguageServerId,
11227        cx: &mut Context<Self>,
11228    ) {
11229        if let Some(local) = self.as_local_mut() {
11230            local.supplementary_language_servers.remove(&id);
11231            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11232        }
11233    }
11234
11235    pub(crate) fn supplementary_language_servers(
11236        &self,
11237    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11238        self.as_local().into_iter().flat_map(|local| {
11239            local
11240                .supplementary_language_servers
11241                .iter()
11242                .map(|(id, (name, _))| (*id, name.clone()))
11243        })
11244    }
11245
11246    pub fn language_server_adapter_for_id(
11247        &self,
11248        id: LanguageServerId,
11249    ) -> Option<Arc<CachedLspAdapter>> {
11250        self.as_local()
11251            .and_then(|local| local.language_servers.get(&id))
11252            .and_then(|language_server_state| match language_server_state {
11253                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11254                _ => None,
11255            })
11256    }
11257
11258    pub(super) fn update_local_worktree_language_servers(
11259        &mut self,
11260        worktree_handle: &Entity<Worktree>,
11261        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11262        cx: &mut Context<Self>,
11263    ) {
11264        if changes.is_empty() {
11265            return;
11266        }
11267
11268        let Some(local) = self.as_local() else { return };
11269
11270        local.prettier_store.update(cx, |prettier_store, cx| {
11271            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11272        });
11273
11274        let worktree_id = worktree_handle.read(cx).id();
11275        let mut language_server_ids = local
11276            .language_server_ids
11277            .iter()
11278            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11279            .collect::<Vec<_>>();
11280        language_server_ids.sort();
11281        language_server_ids.dedup();
11282
11283        // let abs_path = worktree_handle.read(cx).abs_path();
11284        for server_id in &language_server_ids {
11285            if let Some(LanguageServerState::Running { server, .. }) =
11286                local.language_servers.get(server_id)
11287                && let Some(watched_paths) = local
11288                    .language_server_watched_paths
11289                    .get(server_id)
11290                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11291            {
11292                let params = lsp::DidChangeWatchedFilesParams {
11293                    changes: changes
11294                        .iter()
11295                        .filter_map(|(path, _, change)| {
11296                            if !watched_paths.is_match(path.as_std_path()) {
11297                                return None;
11298                            }
11299                            let typ = match change {
11300                                PathChange::Loaded => return None,
11301                                PathChange::Added => lsp::FileChangeType::CREATED,
11302                                PathChange::Removed => lsp::FileChangeType::DELETED,
11303                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11304                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11305                            };
11306                            let uri = lsp::Uri::from_file_path(
11307                                worktree_handle.read(cx).absolutize(&path),
11308                            )
11309                            .ok()?;
11310                            Some(lsp::FileEvent { uri, typ })
11311                        })
11312                        .collect(),
11313                };
11314                if !params.changes.is_empty() {
11315                    server
11316                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11317                        .ok();
11318                }
11319            }
11320        }
11321        for (path, _, _) in changes {
11322            if let Some(file_name) = path.file_name()
11323                && local.watched_manifest_filenames.contains(file_name)
11324            {
11325                self.request_workspace_config_refresh();
11326                break;
11327            }
11328        }
11329    }
11330
11331    pub fn wait_for_remote_buffer(
11332        &mut self,
11333        id: BufferId,
11334        cx: &mut Context<Self>,
11335    ) -> Task<Result<Entity<Buffer>>> {
11336        self.buffer_store.update(cx, |buffer_store, cx| {
11337            buffer_store.wait_for_remote_buffer(id, cx)
11338        })
11339    }
11340
11341    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11342        let mut result = proto::Symbol {
11343            language_server_name: symbol.language_server_name.0.to_string(),
11344            source_worktree_id: symbol.source_worktree_id.to_proto(),
11345            language_server_id: symbol.source_language_server_id.to_proto(),
11346            name: symbol.name.clone(),
11347            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11348            start: Some(proto::PointUtf16 {
11349                row: symbol.range.start.0.row,
11350                column: symbol.range.start.0.column,
11351            }),
11352            end: Some(proto::PointUtf16 {
11353                row: symbol.range.end.0.row,
11354                column: symbol.range.end.0.column,
11355            }),
11356            worktree_id: Default::default(),
11357            path: Default::default(),
11358            signature: Default::default(),
11359        };
11360        match &symbol.path {
11361            SymbolLocation::InProject(path) => {
11362                result.worktree_id = path.worktree_id.to_proto();
11363                result.path = path.path.to_proto();
11364            }
11365            SymbolLocation::OutsideProject {
11366                abs_path,
11367                signature,
11368            } => {
11369                result.path = abs_path.to_string_lossy().into_owned();
11370                result.signature = signature.to_vec();
11371            }
11372        }
11373        result
11374    }
11375
11376    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11377        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11378        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11379        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11380
11381        let path = if serialized_symbol.signature.is_empty() {
11382            SymbolLocation::InProject(ProjectPath {
11383                worktree_id,
11384                path: RelPath::from_proto(&serialized_symbol.path)
11385                    .context("invalid symbol path")?,
11386            })
11387        } else {
11388            SymbolLocation::OutsideProject {
11389                abs_path: Path::new(&serialized_symbol.path).into(),
11390                signature: serialized_symbol
11391                    .signature
11392                    .try_into()
11393                    .map_err(|_| anyhow!("invalid signature"))?,
11394            }
11395        };
11396
11397        let start = serialized_symbol.start.context("invalid start")?;
11398        let end = serialized_symbol.end.context("invalid end")?;
11399        Ok(CoreSymbol {
11400            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11401            source_worktree_id,
11402            source_language_server_id: LanguageServerId::from_proto(
11403                serialized_symbol.language_server_id,
11404            ),
11405            path,
11406            name: serialized_symbol.name,
11407            range: Unclipped(PointUtf16::new(start.row, start.column))
11408                ..Unclipped(PointUtf16::new(end.row, end.column)),
11409            kind,
11410        })
11411    }
11412
11413    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11414        let mut serialized_completion = proto::Completion {
11415            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11416            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11417            new_text: completion.new_text.clone(),
11418            ..proto::Completion::default()
11419        };
11420        match &completion.source {
11421            CompletionSource::Lsp {
11422                insert_range,
11423                server_id,
11424                lsp_completion,
11425                lsp_defaults,
11426                resolved,
11427            } => {
11428                let (old_insert_start, old_insert_end) = insert_range
11429                    .as_ref()
11430                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11431                    .unzip();
11432
11433                serialized_completion.old_insert_start = old_insert_start;
11434                serialized_completion.old_insert_end = old_insert_end;
11435                serialized_completion.source = proto::completion::Source::Lsp as i32;
11436                serialized_completion.server_id = server_id.0 as u64;
11437                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11438                serialized_completion.lsp_defaults = lsp_defaults
11439                    .as_deref()
11440                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11441                serialized_completion.resolved = *resolved;
11442            }
11443            CompletionSource::BufferWord {
11444                word_range,
11445                resolved,
11446            } => {
11447                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11448                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11449                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11450                serialized_completion.resolved = *resolved;
11451            }
11452            CompletionSource::Custom => {
11453                serialized_completion.source = proto::completion::Source::Custom as i32;
11454                serialized_completion.resolved = true;
11455            }
11456            CompletionSource::Dap { sort_text } => {
11457                serialized_completion.source = proto::completion::Source::Dap as i32;
11458                serialized_completion.sort_text = Some(sort_text.clone());
11459            }
11460        }
11461
11462        serialized_completion
11463    }
11464
11465    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11466        let old_replace_start = completion
11467            .old_replace_start
11468            .and_then(deserialize_anchor)
11469            .context("invalid old start")?;
11470        let old_replace_end = completion
11471            .old_replace_end
11472            .and_then(deserialize_anchor)
11473            .context("invalid old end")?;
11474        let insert_range = {
11475            match completion.old_insert_start.zip(completion.old_insert_end) {
11476                Some((start, end)) => {
11477                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11478                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11479                    Some(start..end)
11480                }
11481                None => None,
11482            }
11483        };
11484        Ok(CoreCompletion {
11485            replace_range: old_replace_start..old_replace_end,
11486            new_text: completion.new_text,
11487            source: match proto::completion::Source::from_i32(completion.source) {
11488                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11489                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11490                    insert_range,
11491                    server_id: LanguageServerId::from_proto(completion.server_id),
11492                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11493                    lsp_defaults: completion
11494                        .lsp_defaults
11495                        .as_deref()
11496                        .map(serde_json::from_slice)
11497                        .transpose()?,
11498                    resolved: completion.resolved,
11499                },
11500                Some(proto::completion::Source::BufferWord) => {
11501                    let word_range = completion
11502                        .buffer_word_start
11503                        .and_then(deserialize_anchor)
11504                        .context("invalid buffer word start")?
11505                        ..completion
11506                            .buffer_word_end
11507                            .and_then(deserialize_anchor)
11508                            .context("invalid buffer word end")?;
11509                    CompletionSource::BufferWord {
11510                        word_range,
11511                        resolved: completion.resolved,
11512                    }
11513                }
11514                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11515                    sort_text: completion
11516                        .sort_text
11517                        .context("expected sort text to exist")?,
11518                },
11519                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11520            },
11521        })
11522    }
11523
11524    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11525        let (kind, lsp_action) = match &action.lsp_action {
11526            LspAction::Action(code_action) => (
11527                proto::code_action::Kind::Action as i32,
11528                serde_json::to_vec(code_action).unwrap(),
11529            ),
11530            LspAction::Command(command) => (
11531                proto::code_action::Kind::Command as i32,
11532                serde_json::to_vec(command).unwrap(),
11533            ),
11534            LspAction::CodeLens(code_lens) => (
11535                proto::code_action::Kind::CodeLens as i32,
11536                serde_json::to_vec(code_lens).unwrap(),
11537            ),
11538        };
11539
11540        proto::CodeAction {
11541            server_id: action.server_id.0 as u64,
11542            start: Some(serialize_anchor(&action.range.start)),
11543            end: Some(serialize_anchor(&action.range.end)),
11544            lsp_action,
11545            kind,
11546            resolved: action.resolved,
11547        }
11548    }
11549
11550    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11551        let start = action
11552            .start
11553            .and_then(deserialize_anchor)
11554            .context("invalid start")?;
11555        let end = action
11556            .end
11557            .and_then(deserialize_anchor)
11558            .context("invalid end")?;
11559        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11560            Some(proto::code_action::Kind::Action) => {
11561                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11562            }
11563            Some(proto::code_action::Kind::Command) => {
11564                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11565            }
11566            Some(proto::code_action::Kind::CodeLens) => {
11567                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11568            }
11569            None => anyhow::bail!("Unknown action kind {}", action.kind),
11570        };
11571        Ok(CodeAction {
11572            server_id: LanguageServerId(action.server_id as usize),
11573            range: start..end,
11574            resolved: action.resolved,
11575            lsp_action,
11576        })
11577    }
11578
11579    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11580        match &formatting_result {
11581            Ok(_) => self.last_formatting_failure = None,
11582            Err(error) => {
11583                let error_string = format!("{error:#}");
11584                log::error!("Formatting failed: {error_string}");
11585                self.last_formatting_failure
11586                    .replace(error_string.lines().join(" "));
11587            }
11588        }
11589    }
11590
11591    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11592        self.lsp_server_capabilities.remove(&for_server);
11593        for lsp_data in self.lsp_data.values_mut() {
11594            lsp_data.remove_server_data(for_server);
11595        }
11596        if let Some(local) = self.as_local_mut() {
11597            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11598            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11599                buffer_servers.remove(&for_server);
11600            }
11601        }
11602    }
11603
11604    pub fn result_id(
11605        &self,
11606        server_id: LanguageServerId,
11607        buffer_id: BufferId,
11608        cx: &App,
11609    ) -> Option<String> {
11610        let abs_path = self
11611            .buffer_store
11612            .read(cx)
11613            .get(buffer_id)
11614            .and_then(|b| File::from_dyn(b.read(cx).file()))
11615            .map(|f| f.abs_path(cx))?;
11616        self.as_local()?
11617            .buffer_pull_diagnostics_result_ids
11618            .get(&server_id)?
11619            .get(&abs_path)?
11620            .clone()
11621    }
11622
11623    pub fn all_result_ids(&self, server_id: LanguageServerId) -> HashMap<PathBuf, String> {
11624        let Some(local) = self.as_local() else {
11625            return HashMap::default();
11626        };
11627        local
11628            .buffer_pull_diagnostics_result_ids
11629            .get(&server_id)
11630            .into_iter()
11631            .flatten()
11632            .filter_map(|(abs_path, result_id)| Some((abs_path.clone(), result_id.clone()?)))
11633            .collect()
11634    }
11635
11636    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
11637        if let Some(LanguageServerState::Running {
11638            workspace_diagnostics_refresh_tasks,
11639            ..
11640        }) = self
11641            .as_local_mut()
11642            .and_then(|local| local.language_servers.get_mut(&server_id))
11643        {
11644            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
11645                diagnostics.refresh_tx.try_send(()).ok();
11646            }
11647        }
11648    }
11649
11650    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
11651        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
11652            return;
11653        };
11654        let Some(local) = self.as_local_mut() else {
11655            return;
11656        };
11657
11658        for server_id in buffer.update(cx, |buffer, cx| {
11659            local.language_server_ids_for_buffer(buffer, cx)
11660        }) {
11661            if let Some(LanguageServerState::Running {
11662                workspace_diagnostics_refresh_tasks,
11663                ..
11664            }) = local.language_servers.get_mut(&server_id)
11665            {
11666                for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
11667                    diagnostics.refresh_tx.try_send(()).ok();
11668                }
11669            }
11670        }
11671    }
11672
11673    fn apply_workspace_diagnostic_report(
11674        &mut self,
11675        server_id: LanguageServerId,
11676        report: lsp::WorkspaceDiagnosticReportResult,
11677        cx: &mut Context<Self>,
11678    ) {
11679        let workspace_diagnostics =
11680            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(report, server_id);
11681        let mut unchanged_buffers = HashSet::default();
11682        let mut changed_buffers = HashSet::default();
11683        let workspace_diagnostics_updates = workspace_diagnostics
11684            .into_iter()
11685            .filter_map(
11686                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
11687                    LspPullDiagnostics::Response {
11688                        server_id,
11689                        uri,
11690                        diagnostics,
11691                    } => Some((server_id, uri, diagnostics, workspace_diagnostics.version)),
11692                    LspPullDiagnostics::Default => None,
11693                },
11694            )
11695            .fold(
11696                HashMap::default(),
11697                |mut acc, (server_id, uri, diagnostics, version)| {
11698                    let (result_id, diagnostics) = match diagnostics {
11699                        PulledDiagnostics::Unchanged { result_id } => {
11700                            unchanged_buffers.insert(uri.clone());
11701                            (Some(result_id), Vec::new())
11702                        }
11703                        PulledDiagnostics::Changed {
11704                            result_id,
11705                            diagnostics,
11706                        } => {
11707                            changed_buffers.insert(uri.clone());
11708                            (result_id, diagnostics)
11709                        }
11710                    };
11711                    let disk_based_sources = Cow::Owned(
11712                        self.language_server_adapter_for_id(server_id)
11713                            .as_ref()
11714                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
11715                            .unwrap_or(&[])
11716                            .to_vec(),
11717                    );
11718                    acc.entry(server_id)
11719                        .or_insert_with(Vec::new)
11720                        .push(DocumentDiagnosticsUpdate {
11721                            server_id,
11722                            diagnostics: lsp::PublishDiagnosticsParams {
11723                                uri,
11724                                diagnostics,
11725                                version,
11726                            },
11727                            result_id,
11728                            disk_based_sources,
11729                        });
11730                    acc
11731                },
11732            );
11733
11734        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
11735            self.merge_lsp_diagnostics(
11736                DiagnosticSourceKind::Pulled,
11737                diagnostic_updates,
11738                |buffer, old_diagnostic, cx| {
11739                    File::from_dyn(buffer.file())
11740                        .and_then(|file| {
11741                            let abs_path = file.as_local()?.abs_path(cx);
11742                            lsp::Uri::from_file_path(abs_path).ok()
11743                        })
11744                        .is_none_or(|buffer_uri| {
11745                            unchanged_buffers.contains(&buffer_uri)
11746                                || match old_diagnostic.source_kind {
11747                                    DiagnosticSourceKind::Pulled => {
11748                                        !changed_buffers.contains(&buffer_uri)
11749                                    }
11750                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
11751                                        true
11752                                    }
11753                                }
11754                        })
11755                },
11756                cx,
11757            )
11758            .log_err();
11759        }
11760    }
11761
11762    fn register_server_capabilities(
11763        &mut self,
11764        server_id: LanguageServerId,
11765        params: lsp::RegistrationParams,
11766        cx: &mut Context<Self>,
11767    ) -> anyhow::Result<()> {
11768        let server = self
11769            .language_server_for_id(server_id)
11770            .with_context(|| format!("no server {server_id} found"))?;
11771        for reg in params.registrations {
11772            match reg.method.as_str() {
11773                "workspace/didChangeWatchedFiles" => {
11774                    if let Some(options) = reg.register_options {
11775                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11776                            let caps = serde_json::from_value(options)?;
11777                            local_lsp_store
11778                                .on_lsp_did_change_watched_files(server_id, ®.id, caps, cx);
11779                            true
11780                        } else {
11781                            false
11782                        };
11783                        if notify {
11784                            notify_server_capabilities_updated(&server, cx);
11785                        }
11786                    }
11787                }
11788                "workspace/didChangeConfiguration" => {
11789                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11790                }
11791                "workspace/didChangeWorkspaceFolders" => {
11792                    // In this case register options is an empty object, we can ignore it
11793                    let caps = lsp::WorkspaceFoldersServerCapabilities {
11794                        supported: Some(true),
11795                        change_notifications: Some(OneOf::Right(reg.id)),
11796                    };
11797                    server.update_capabilities(|capabilities| {
11798                        capabilities
11799                            .workspace
11800                            .get_or_insert_default()
11801                            .workspace_folders = Some(caps);
11802                    });
11803                    notify_server_capabilities_updated(&server, cx);
11804                }
11805                "workspace/symbol" => {
11806                    let options = parse_register_capabilities(reg)?;
11807                    server.update_capabilities(|capabilities| {
11808                        capabilities.workspace_symbol_provider = Some(options);
11809                    });
11810                    notify_server_capabilities_updated(&server, cx);
11811                }
11812                "workspace/fileOperations" => {
11813                    if let Some(options) = reg.register_options {
11814                        let caps = serde_json::from_value(options)?;
11815                        server.update_capabilities(|capabilities| {
11816                            capabilities
11817                                .workspace
11818                                .get_or_insert_default()
11819                                .file_operations = Some(caps);
11820                        });
11821                        notify_server_capabilities_updated(&server, cx);
11822                    }
11823                }
11824                "workspace/executeCommand" => {
11825                    if let Some(options) = reg.register_options {
11826                        let options = serde_json::from_value(options)?;
11827                        server.update_capabilities(|capabilities| {
11828                            capabilities.execute_command_provider = Some(options);
11829                        });
11830                        notify_server_capabilities_updated(&server, cx);
11831                    }
11832                }
11833                "textDocument/rangeFormatting" => {
11834                    let options = parse_register_capabilities(reg)?;
11835                    server.update_capabilities(|capabilities| {
11836                        capabilities.document_range_formatting_provider = Some(options);
11837                    });
11838                    notify_server_capabilities_updated(&server, cx);
11839                }
11840                "textDocument/onTypeFormatting" => {
11841                    if let Some(options) = reg
11842                        .register_options
11843                        .map(serde_json::from_value)
11844                        .transpose()?
11845                    {
11846                        server.update_capabilities(|capabilities| {
11847                            capabilities.document_on_type_formatting_provider = Some(options);
11848                        });
11849                        notify_server_capabilities_updated(&server, cx);
11850                    }
11851                }
11852                "textDocument/formatting" => {
11853                    let options = parse_register_capabilities(reg)?;
11854                    server.update_capabilities(|capabilities| {
11855                        capabilities.document_formatting_provider = Some(options);
11856                    });
11857                    notify_server_capabilities_updated(&server, cx);
11858                }
11859                "textDocument/rename" => {
11860                    let options = parse_register_capabilities(reg)?;
11861                    server.update_capabilities(|capabilities| {
11862                        capabilities.rename_provider = Some(options);
11863                    });
11864                    notify_server_capabilities_updated(&server, cx);
11865                }
11866                "textDocument/inlayHint" => {
11867                    let options = parse_register_capabilities(reg)?;
11868                    server.update_capabilities(|capabilities| {
11869                        capabilities.inlay_hint_provider = Some(options);
11870                    });
11871                    notify_server_capabilities_updated(&server, cx);
11872                }
11873                "textDocument/documentSymbol" => {
11874                    let options = parse_register_capabilities(reg)?;
11875                    server.update_capabilities(|capabilities| {
11876                        capabilities.document_symbol_provider = Some(options);
11877                    });
11878                    notify_server_capabilities_updated(&server, cx);
11879                }
11880                "textDocument/codeAction" => {
11881                    let options = parse_register_capabilities(reg)?;
11882                    let provider = match options {
11883                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
11884                        OneOf::Right(caps) => caps,
11885                    };
11886                    server.update_capabilities(|capabilities| {
11887                        capabilities.code_action_provider = Some(provider);
11888                    });
11889                    notify_server_capabilities_updated(&server, cx);
11890                }
11891                "textDocument/definition" => {
11892                    let options = parse_register_capabilities(reg)?;
11893                    server.update_capabilities(|capabilities| {
11894                        capabilities.definition_provider = Some(options);
11895                    });
11896                    notify_server_capabilities_updated(&server, cx);
11897                }
11898                "textDocument/completion" => {
11899                    if let Some(caps) = reg
11900                        .register_options
11901                        .map(serde_json::from_value)
11902                        .transpose()?
11903                    {
11904                        server.update_capabilities(|capabilities| {
11905                            capabilities.completion_provider = Some(caps);
11906                        });
11907                        notify_server_capabilities_updated(&server, cx);
11908                    }
11909                }
11910                "textDocument/hover" => {
11911                    let options = parse_register_capabilities(reg)?;
11912                    let provider = match options {
11913                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
11914                        OneOf::Right(caps) => caps,
11915                    };
11916                    server.update_capabilities(|capabilities| {
11917                        capabilities.hover_provider = Some(provider);
11918                    });
11919                    notify_server_capabilities_updated(&server, cx);
11920                }
11921                "textDocument/signatureHelp" => {
11922                    if let Some(caps) = reg
11923                        .register_options
11924                        .map(serde_json::from_value)
11925                        .transpose()?
11926                    {
11927                        server.update_capabilities(|capabilities| {
11928                            capabilities.signature_help_provider = Some(caps);
11929                        });
11930                        notify_server_capabilities_updated(&server, cx);
11931                    }
11932                }
11933                "textDocument/didChange" => {
11934                    if let Some(sync_kind) = reg
11935                        .register_options
11936                        .and_then(|opts| opts.get("syncKind").cloned())
11937                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
11938                        .transpose()?
11939                    {
11940                        server.update_capabilities(|capabilities| {
11941                            let mut sync_options =
11942                                Self::take_text_document_sync_options(capabilities);
11943                            sync_options.change = Some(sync_kind);
11944                            capabilities.text_document_sync =
11945                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11946                        });
11947                        notify_server_capabilities_updated(&server, cx);
11948                    }
11949                }
11950                "textDocument/didSave" => {
11951                    if let Some(include_text) = reg
11952                        .register_options
11953                        .map(|opts| {
11954                            let transpose = opts
11955                                .get("includeText")
11956                                .cloned()
11957                                .map(serde_json::from_value::<Option<bool>>)
11958                                .transpose();
11959                            match transpose {
11960                                Ok(value) => Ok(value.flatten()),
11961                                Err(e) => Err(e),
11962                            }
11963                        })
11964                        .transpose()?
11965                    {
11966                        server.update_capabilities(|capabilities| {
11967                            let mut sync_options =
11968                                Self::take_text_document_sync_options(capabilities);
11969                            sync_options.save =
11970                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
11971                                    include_text,
11972                                }));
11973                            capabilities.text_document_sync =
11974                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
11975                        });
11976                        notify_server_capabilities_updated(&server, cx);
11977                    }
11978                }
11979                "textDocument/codeLens" => {
11980                    if let Some(caps) = reg
11981                        .register_options
11982                        .map(serde_json::from_value)
11983                        .transpose()?
11984                    {
11985                        server.update_capabilities(|capabilities| {
11986                            capabilities.code_lens_provider = Some(caps);
11987                        });
11988                        notify_server_capabilities_updated(&server, cx);
11989                    }
11990                }
11991                "textDocument/diagnostic" => {
11992                    if let Some(caps) = reg
11993                        .register_options
11994                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
11995                        .transpose()?
11996                    {
11997                        let local = self
11998                            .as_local_mut()
11999                            .context("Expected LSP Store to be local")?;
12000                        let state = local
12001                            .language_servers
12002                            .get_mut(&server_id)
12003                            .context("Could not obtain Language Servers state")?;
12004                        local
12005                            .language_server_dynamic_registrations
12006                            .get_mut(&server_id)
12007                            .and_then(|registrations| {
12008                                registrations
12009                                    .diagnostics
12010                                    .insert(Some(reg.id.clone()), caps.clone())
12011                            });
12012
12013                        let mut can_now_provide_diagnostics = false;
12014                        if let LanguageServerState::Running {
12015                            workspace_diagnostics_refresh_tasks,
12016                            ..
12017                        } = state
12018                            && let Some(task) = lsp_workspace_diagnostics_refresh(
12019                                Some(reg.id.clone()),
12020                                caps.clone(),
12021                                server.clone(),
12022                                cx,
12023                            )
12024                        {
12025                            workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12026                            can_now_provide_diagnostics = true;
12027                        }
12028
12029                        // We don't actually care about capabilities.diagnostic_provider, but it IS relevant for the remote peer
12030                        // to know that there's at least one provider. Otherwise, it will never ask us to issue documentdiagnostic calls on their behalf,
12031                        // as it'll think that they're not supported.
12032                        if can_now_provide_diagnostics {
12033                            server.update_capabilities(|capabilities| {
12034                                debug_assert!(capabilities.diagnostic_provider.is_none());
12035                                capabilities.diagnostic_provider = Some(caps);
12036                            });
12037                        }
12038
12039                        notify_server_capabilities_updated(&server, cx);
12040                    }
12041                }
12042                "textDocument/documentColor" => {
12043                    let options = parse_register_capabilities(reg)?;
12044                    let provider = match options {
12045                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12046                        OneOf::Right(caps) => caps,
12047                    };
12048                    server.update_capabilities(|capabilities| {
12049                        capabilities.color_provider = Some(provider);
12050                    });
12051                    notify_server_capabilities_updated(&server, cx);
12052                }
12053                _ => log::warn!("unhandled capability registration: {reg:?}"),
12054            }
12055        }
12056
12057        Ok(())
12058    }
12059
12060    fn unregister_server_capabilities(
12061        &mut self,
12062        server_id: LanguageServerId,
12063        params: lsp::UnregistrationParams,
12064        cx: &mut Context<Self>,
12065    ) -> anyhow::Result<()> {
12066        let server = self
12067            .language_server_for_id(server_id)
12068            .with_context(|| format!("no server {server_id} found"))?;
12069        for unreg in params.unregisterations.iter() {
12070            match unreg.method.as_str() {
12071                "workspace/didChangeWatchedFiles" => {
12072                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12073                        local_lsp_store
12074                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12075                        true
12076                    } else {
12077                        false
12078                    };
12079                    if notify {
12080                        notify_server_capabilities_updated(&server, cx);
12081                    }
12082                }
12083                "workspace/didChangeConfiguration" => {
12084                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12085                }
12086                "workspace/didChangeWorkspaceFolders" => {
12087                    server.update_capabilities(|capabilities| {
12088                        capabilities
12089                            .workspace
12090                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12091                                workspace_folders: None,
12092                                file_operations: None,
12093                            })
12094                            .workspace_folders = None;
12095                    });
12096                    notify_server_capabilities_updated(&server, cx);
12097                }
12098                "workspace/symbol" => {
12099                    server.update_capabilities(|capabilities| {
12100                        capabilities.workspace_symbol_provider = None
12101                    });
12102                    notify_server_capabilities_updated(&server, cx);
12103                }
12104                "workspace/fileOperations" => {
12105                    server.update_capabilities(|capabilities| {
12106                        capabilities
12107                            .workspace
12108                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12109                                workspace_folders: None,
12110                                file_operations: None,
12111                            })
12112                            .file_operations = None;
12113                    });
12114                    notify_server_capabilities_updated(&server, cx);
12115                }
12116                "workspace/executeCommand" => {
12117                    server.update_capabilities(|capabilities| {
12118                        capabilities.execute_command_provider = None;
12119                    });
12120                    notify_server_capabilities_updated(&server, cx);
12121                }
12122                "textDocument/rangeFormatting" => {
12123                    server.update_capabilities(|capabilities| {
12124                        capabilities.document_range_formatting_provider = None
12125                    });
12126                    notify_server_capabilities_updated(&server, cx);
12127                }
12128                "textDocument/onTypeFormatting" => {
12129                    server.update_capabilities(|capabilities| {
12130                        capabilities.document_on_type_formatting_provider = None;
12131                    });
12132                    notify_server_capabilities_updated(&server, cx);
12133                }
12134                "textDocument/formatting" => {
12135                    server.update_capabilities(|capabilities| {
12136                        capabilities.document_formatting_provider = None;
12137                    });
12138                    notify_server_capabilities_updated(&server, cx);
12139                }
12140                "textDocument/rename" => {
12141                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12142                    notify_server_capabilities_updated(&server, cx);
12143                }
12144                "textDocument/codeAction" => {
12145                    server.update_capabilities(|capabilities| {
12146                        capabilities.code_action_provider = None;
12147                    });
12148                    notify_server_capabilities_updated(&server, cx);
12149                }
12150                "textDocument/definition" => {
12151                    server.update_capabilities(|capabilities| {
12152                        capabilities.definition_provider = None;
12153                    });
12154                    notify_server_capabilities_updated(&server, cx);
12155                }
12156                "textDocument/completion" => {
12157                    server.update_capabilities(|capabilities| {
12158                        capabilities.completion_provider = None;
12159                    });
12160                    notify_server_capabilities_updated(&server, cx);
12161                }
12162                "textDocument/hover" => {
12163                    server.update_capabilities(|capabilities| {
12164                        capabilities.hover_provider = None;
12165                    });
12166                    notify_server_capabilities_updated(&server, cx);
12167                }
12168                "textDocument/signatureHelp" => {
12169                    server.update_capabilities(|capabilities| {
12170                        capabilities.signature_help_provider = None;
12171                    });
12172                    notify_server_capabilities_updated(&server, cx);
12173                }
12174                "textDocument/didChange" => {
12175                    server.update_capabilities(|capabilities| {
12176                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12177                        sync_options.change = None;
12178                        capabilities.text_document_sync =
12179                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12180                    });
12181                    notify_server_capabilities_updated(&server, cx);
12182                }
12183                "textDocument/didSave" => {
12184                    server.update_capabilities(|capabilities| {
12185                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12186                        sync_options.save = None;
12187                        capabilities.text_document_sync =
12188                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12189                    });
12190                    notify_server_capabilities_updated(&server, cx);
12191                }
12192                "textDocument/codeLens" => {
12193                    server.update_capabilities(|capabilities| {
12194                        capabilities.code_lens_provider = None;
12195                    });
12196                    notify_server_capabilities_updated(&server, cx);
12197                }
12198                "textDocument/diagnostic" => {
12199                    let local = self
12200                        .as_local_mut()
12201                        .context("Expected LSP Store to be local")?;
12202
12203                    let state = local
12204                        .language_servers
12205                        .get_mut(&server_id)
12206                        .context("Could not obtain Language Servers state")?;
12207                    let options = local
12208                        .language_server_dynamic_registrations
12209                        .get_mut(&server_id)
12210                        .with_context(|| {
12211                            format!("Expected dynamic registration to exist for server {server_id}")
12212                        })?.diagnostics
12213                        .remove(&Some(unreg.id.clone()))
12214                        .with_context(|| format!(
12215                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12216                            unreg.id)
12217                        )?;
12218
12219                    let mut has_any_diagnostic_providers_still = true;
12220                    if let Some(identifier) = diagnostic_identifier(&options)
12221                        && let LanguageServerState::Running {
12222                            workspace_diagnostics_refresh_tasks,
12223                            ..
12224                        } = state
12225                    {
12226                        workspace_diagnostics_refresh_tasks.remove(&identifier);
12227                        has_any_diagnostic_providers_still =
12228                            !workspace_diagnostics_refresh_tasks.is_empty();
12229                    }
12230
12231                    if !has_any_diagnostic_providers_still {
12232                        server.update_capabilities(|capabilities| {
12233                            debug_assert!(capabilities.diagnostic_provider.is_some());
12234                            capabilities.diagnostic_provider = None;
12235                        });
12236                    }
12237
12238                    notify_server_capabilities_updated(&server, cx);
12239                }
12240                "textDocument/documentColor" => {
12241                    server.update_capabilities(|capabilities| {
12242                        capabilities.color_provider = None;
12243                    });
12244                    notify_server_capabilities_updated(&server, cx);
12245                }
12246                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12247            }
12248        }
12249
12250        Ok(())
12251    }
12252
12253    async fn deduplicate_range_based_lsp_requests<T>(
12254        lsp_store: &Entity<Self>,
12255        server_id: Option<LanguageServerId>,
12256        lsp_request_id: LspRequestId,
12257        proto_request: &T::ProtoRequest,
12258        range: Range<Anchor>,
12259        cx: &mut AsyncApp,
12260    ) -> Result<()>
12261    where
12262        T: LspCommand,
12263        T::ProtoRequest: proto::LspRequestMessage,
12264    {
12265        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12266        let version = deserialize_version(proto_request.buffer_version());
12267        let buffer = lsp_store.update(cx, |this, cx| {
12268            this.buffer_store.read(cx).get_existing(buffer_id)
12269        })??;
12270        buffer
12271            .update(cx, |buffer, _| buffer.wait_for_version(version))?
12272            .await?;
12273        lsp_store.update(cx, |lsp_store, cx| {
12274            let lsp_data = lsp_store
12275                .lsp_data
12276                .entry(buffer_id)
12277                .or_insert_with(|| BufferLspData::new(&buffer, cx));
12278            let chunks_queried_for = lsp_data
12279                .inlay_hints
12280                .applicable_chunks(&[range])
12281                .collect::<Vec<_>>();
12282            match chunks_queried_for.as_slice() {
12283                &[chunk] => {
12284                    let key = LspKey {
12285                        request_type: TypeId::of::<T>(),
12286                        server_queried: server_id,
12287                    };
12288                    let previous_request = lsp_data
12289                        .chunk_lsp_requests
12290                        .entry(key)
12291                        .or_default()
12292                        .insert(chunk, lsp_request_id);
12293                    if let Some((previous_request, running_requests)) =
12294                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12295                    {
12296                        running_requests.remove(&previous_request);
12297                    }
12298                }
12299                _ambiguous_chunks => {
12300                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12301                    // there, a buffer version-based check will be performed and outdated requests discarded.
12302                }
12303            }
12304            anyhow::Ok(())
12305        })??;
12306
12307        Ok(())
12308    }
12309
12310    async fn query_lsp_locally<T>(
12311        lsp_store: Entity<Self>,
12312        for_server_id: Option<LanguageServerId>,
12313        sender_id: proto::PeerId,
12314        lsp_request_id: LspRequestId,
12315        proto_request: T::ProtoRequest,
12316        position: Option<Anchor>,
12317        cx: &mut AsyncApp,
12318    ) -> Result<()>
12319    where
12320        T: LspCommand + Clone,
12321        T::ProtoRequest: proto::LspRequestMessage,
12322        <T::ProtoRequest as proto::RequestMessage>::Response:
12323            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12324    {
12325        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12326        let version = deserialize_version(proto_request.buffer_version());
12327        let buffer = lsp_store.update(cx, |this, cx| {
12328            this.buffer_store.read(cx).get_existing(buffer_id)
12329        })??;
12330        buffer
12331            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))?
12332            .await?;
12333        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version())?;
12334        let request =
12335            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12336        let key = LspKey {
12337            request_type: TypeId::of::<T>(),
12338            server_queried: for_server_id,
12339        };
12340        lsp_store.update(cx, |lsp_store, cx| {
12341            let request_task = match for_server_id {
12342                Some(server_id) => {
12343                    let server_task = lsp_store.request_lsp(
12344                        buffer.clone(),
12345                        LanguageServerToQuery::Other(server_id),
12346                        request.clone(),
12347                        cx,
12348                    );
12349                    cx.background_spawn(async move {
12350                        let mut responses = Vec::new();
12351                        match server_task.await {
12352                            Ok(response) => responses.push((server_id, response)),
12353                            Err(e) => log::error!(
12354                                "Error handling response for request {request:?}: {e:#}"
12355                            ),
12356                        }
12357                        responses
12358                    })
12359                }
12360                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12361            };
12362            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12363            if T::ProtoRequest::stop_previous_requests() {
12364                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12365                    lsp_requests.clear();
12366                }
12367            }
12368            lsp_data.lsp_requests.entry(key).or_default().insert(
12369                lsp_request_id,
12370                cx.spawn(async move |lsp_store, cx| {
12371                    let response = request_task.await;
12372                    lsp_store
12373                        .update(cx, |lsp_store, cx| {
12374                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12375                            {
12376                                let response = response
12377                                    .into_iter()
12378                                    .map(|(server_id, response)| {
12379                                        (
12380                                            server_id.to_proto(),
12381                                            T::response_to_proto(
12382                                                response,
12383                                                lsp_store,
12384                                                sender_id,
12385                                                &buffer_version,
12386                                                cx,
12387                                            )
12388                                            .into(),
12389                                        )
12390                                    })
12391                                    .collect::<HashMap<_, _>>();
12392                                match client.send_lsp_response::<T::ProtoRequest>(
12393                                    project_id,
12394                                    lsp_request_id,
12395                                    response,
12396                                ) {
12397                                    Ok(()) => {}
12398                                    Err(e) => {
12399                                        log::error!("Failed to send LSP response: {e:#}",)
12400                                    }
12401                                }
12402                            }
12403                        })
12404                        .ok();
12405                }),
12406            );
12407        })?;
12408        Ok(())
12409    }
12410
12411    fn take_text_document_sync_options(
12412        capabilities: &mut lsp::ServerCapabilities,
12413    ) -> lsp::TextDocumentSyncOptions {
12414        match capabilities.text_document_sync.take() {
12415            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12416            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12417                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12418                sync_options.change = Some(sync_kind);
12419                sync_options
12420            }
12421            None => lsp::TextDocumentSyncOptions::default(),
12422        }
12423    }
12424
12425    #[cfg(any(test, feature = "test-support"))]
12426    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
12427        Some(
12428            self.lsp_data
12429                .get_mut(&buffer_id)?
12430                .code_lens
12431                .take()?
12432                .update
12433                .take()?
12434                .1,
12435        )
12436    }
12437
12438    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
12439        self.downstream_client.clone()
12440    }
12441
12442    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
12443        self.worktree_store.clone()
12444    }
12445
12446    /// Gets what's stored in the LSP data for the given buffer.
12447    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
12448        self.lsp_data.get_mut(&buffer_id)
12449    }
12450
12451    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
12452    /// new [`BufferLspData`] will be created to replace the previous state.
12453    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
12454        let (buffer_id, buffer_version) =
12455            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
12456        let lsp_data = self
12457            .lsp_data
12458            .entry(buffer_id)
12459            .or_insert_with(|| BufferLspData::new(buffer, cx));
12460        if buffer_version.changed_since(&lsp_data.buffer_version) {
12461            *lsp_data = BufferLspData::new(buffer, cx);
12462        }
12463        lsp_data
12464    }
12465}
12466
12467// Registration with registerOptions as null, should fallback to true.
12468// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
12469fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
12470    reg: lsp::Registration,
12471) -> Result<OneOf<bool, T>> {
12472    Ok(match reg.register_options {
12473        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
12474        None => OneOf::Left(true),
12475    })
12476}
12477
12478fn subscribe_to_binary_statuses(
12479    languages: &Arc<LanguageRegistry>,
12480    cx: &mut Context<'_, LspStore>,
12481) -> Task<()> {
12482    let mut server_statuses = languages.language_server_binary_statuses();
12483    cx.spawn(async move |lsp_store, cx| {
12484        while let Some((server_name, binary_status)) = server_statuses.next().await {
12485            if lsp_store
12486                .update(cx, |_, cx| {
12487                    let mut message = None;
12488                    let binary_status = match binary_status {
12489                        BinaryStatus::None => proto::ServerBinaryStatus::None,
12490                        BinaryStatus::CheckingForUpdate => {
12491                            proto::ServerBinaryStatus::CheckingForUpdate
12492                        }
12493                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
12494                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
12495                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
12496                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
12497                        BinaryStatus::Failed { error } => {
12498                            message = Some(error);
12499                            proto::ServerBinaryStatus::Failed
12500                        }
12501                    };
12502                    cx.emit(LspStoreEvent::LanguageServerUpdate {
12503                        // Binary updates are about the binary that might not have any language server id at that point.
12504                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
12505                        language_server_id: LanguageServerId(0),
12506                        name: Some(server_name),
12507                        message: proto::update_language_server::Variant::StatusUpdate(
12508                            proto::StatusUpdate {
12509                                message,
12510                                status: Some(proto::status_update::Status::Binary(
12511                                    binary_status as i32,
12512                                )),
12513                            },
12514                        ),
12515                    });
12516                })
12517                .is_err()
12518            {
12519                break;
12520            }
12521        }
12522    })
12523}
12524
12525fn lsp_workspace_diagnostics_refresh(
12526    registration_id: Option<String>,
12527    options: DiagnosticServerCapabilities,
12528    server: Arc<LanguageServer>,
12529    cx: &mut Context<'_, LspStore>,
12530) -> Option<WorkspaceRefreshTask> {
12531    let identifier = diagnostic_identifier(&options)?;
12532
12533    let (progress_tx, mut progress_rx) = mpsc::channel(1);
12534    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
12535    refresh_tx.try_send(()).ok();
12536
12537    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
12538        let mut attempts = 0;
12539        let max_attempts = 50;
12540        let mut requests = 0;
12541
12542        loop {
12543            let Some(()) = refresh_rx.recv().await else {
12544                return;
12545            };
12546
12547            'request: loop {
12548                requests += 1;
12549                if attempts > max_attempts {
12550                    log::error!(
12551                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
12552                    );
12553                    return;
12554                }
12555                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
12556                cx.background_executor()
12557                    .timer(Duration::from_millis(backoff_millis))
12558                    .await;
12559                attempts += 1;
12560
12561                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
12562                    lsp_store
12563                        .all_result_ids(server.server_id())
12564                        .into_iter()
12565                        .filter_map(|(abs_path, result_id)| {
12566                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
12567                            Some(lsp::PreviousResultId {
12568                                uri,
12569                                value: result_id,
12570                            })
12571                        })
12572                        .collect()
12573                }) else {
12574                    return;
12575                };
12576
12577                let token = if let Some(identifier) = ®istration_id {
12578                    format!(
12579                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{identifier}",
12580                        server.server_id(),
12581                    )
12582                } else {
12583                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
12584                };
12585
12586                progress_rx.try_recv().ok();
12587                let timer =
12588                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
12589                let progress = pin!(progress_rx.recv().fuse());
12590                let response_result = server
12591                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
12592                        lsp::WorkspaceDiagnosticParams {
12593                            previous_result_ids,
12594                            identifier: identifier.clone(),
12595                            work_done_progress_params: Default::default(),
12596                            partial_result_params: lsp::PartialResultParams {
12597                                partial_result_token: Some(lsp::ProgressToken::String(token)),
12598                            },
12599                        },
12600                        select(timer, progress).then(|either| match either {
12601                            Either::Left((message, ..)) => ready(message).left_future(),
12602                            Either::Right(..) => pending::<String>().right_future(),
12603                        }),
12604                    )
12605                    .await;
12606
12607                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
12608                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
12609                match response_result {
12610                    ConnectionResult::Timeout => {
12611                        log::error!("Timeout during workspace diagnostics pull");
12612                        continue 'request;
12613                    }
12614                    ConnectionResult::ConnectionReset => {
12615                        log::error!("Server closed a workspace diagnostics pull request");
12616                        continue 'request;
12617                    }
12618                    ConnectionResult::Result(Err(e)) => {
12619                        log::error!("Error during workspace diagnostics pull: {e:#}");
12620                        break 'request;
12621                    }
12622                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
12623                        attempts = 0;
12624                        if lsp_store
12625                            .update(cx, |lsp_store, cx| {
12626                                lsp_store.apply_workspace_diagnostic_report(
12627                                    server.server_id(),
12628                                    pulled_diagnostics,
12629                                    cx,
12630                                )
12631                            })
12632                            .is_err()
12633                        {
12634                            return;
12635                        }
12636                        break 'request;
12637                    }
12638                }
12639            }
12640        }
12641    });
12642
12643    Some(WorkspaceRefreshTask {
12644        refresh_tx,
12645        progress_tx,
12646        task: workspace_query_language_server,
12647    })
12648}
12649
12650fn diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<Option<String>> {
12651    match &options {
12652        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
12653            if !diagnostic_options.workspace_diagnostics {
12654                return None;
12655            }
12656            Some(diagnostic_options.identifier.clone())
12657        }
12658        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
12659            let diagnostic_options = ®istration_options.diagnostic_options;
12660            if !diagnostic_options.workspace_diagnostics {
12661                return None;
12662            }
12663            Some(diagnostic_options.identifier.clone())
12664        }
12665    }
12666}
12667
12668fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
12669    let CompletionSource::BufferWord {
12670        word_range,
12671        resolved,
12672    } = &mut completion.source
12673    else {
12674        return;
12675    };
12676    if *resolved {
12677        return;
12678    }
12679
12680    if completion.new_text
12681        != snapshot
12682            .text_for_range(word_range.clone())
12683            .collect::<String>()
12684    {
12685        return;
12686    }
12687
12688    let mut offset = 0;
12689    for chunk in snapshot.chunks(word_range.clone(), true) {
12690        let end_offset = offset + chunk.text.len();
12691        if let Some(highlight_id) = chunk.syntax_highlight_id {
12692            completion
12693                .label
12694                .runs
12695                .push((offset..end_offset, highlight_id));
12696        }
12697        offset = end_offset;
12698    }
12699    *resolved = true;
12700}
12701
12702impl EventEmitter<LspStoreEvent> for LspStore {}
12703
12704fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
12705    hover
12706        .contents
12707        .retain(|hover_block| !hover_block.text.trim().is_empty());
12708    if hover.contents.is_empty() {
12709        None
12710    } else {
12711        Some(hover)
12712    }
12713}
12714
12715async fn populate_labels_for_completions(
12716    new_completions: Vec<CoreCompletion>,
12717    language: Option<Arc<Language>>,
12718    lsp_adapter: Option<Arc<CachedLspAdapter>>,
12719) -> Vec<Completion> {
12720    let lsp_completions = new_completions
12721        .iter()
12722        .filter_map(|new_completion| {
12723            new_completion
12724                .source
12725                .lsp_completion(true)
12726                .map(|lsp_completion| lsp_completion.into_owned())
12727        })
12728        .collect::<Vec<_>>();
12729
12730    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
12731        lsp_adapter
12732            .labels_for_completions(&lsp_completions, language)
12733            .await
12734            .log_err()
12735            .unwrap_or_default()
12736    } else {
12737        Vec::new()
12738    }
12739    .into_iter()
12740    .fuse();
12741
12742    let mut completions = Vec::new();
12743    for completion in new_completions {
12744        match completion.source.lsp_completion(true) {
12745            Some(lsp_completion) => {
12746                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
12747
12748                let mut label = labels.next().flatten().unwrap_or_else(|| {
12749                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
12750                });
12751                ensure_uniform_list_compatible_label(&mut label);
12752                completions.push(Completion {
12753                    label,
12754                    documentation,
12755                    replace_range: completion.replace_range,
12756                    new_text: completion.new_text,
12757                    insert_text_mode: lsp_completion.insert_text_mode,
12758                    source: completion.source,
12759                    icon_path: None,
12760                    confirm: None,
12761                });
12762            }
12763            None => {
12764                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
12765                ensure_uniform_list_compatible_label(&mut label);
12766                completions.push(Completion {
12767                    label,
12768                    documentation: None,
12769                    replace_range: completion.replace_range,
12770                    new_text: completion.new_text,
12771                    source: completion.source,
12772                    insert_text_mode: None,
12773                    icon_path: None,
12774                    confirm: None,
12775                });
12776            }
12777        }
12778    }
12779    completions
12780}
12781
12782#[derive(Debug)]
12783pub enum LanguageServerToQuery {
12784    /// Query language servers in order of users preference, up until one capable of handling the request is found.
12785    FirstCapable,
12786    /// Query a specific language server.
12787    Other(LanguageServerId),
12788}
12789
12790#[derive(Default)]
12791struct RenamePathsWatchedForServer {
12792    did_rename: Vec<RenameActionPredicate>,
12793    will_rename: Vec<RenameActionPredicate>,
12794}
12795
12796impl RenamePathsWatchedForServer {
12797    fn with_did_rename_patterns(
12798        mut self,
12799        did_rename: Option<&FileOperationRegistrationOptions>,
12800    ) -> Self {
12801        if let Some(did_rename) = did_rename {
12802            self.did_rename = did_rename
12803                .filters
12804                .iter()
12805                .filter_map(|filter| filter.try_into().log_err())
12806                .collect();
12807        }
12808        self
12809    }
12810    fn with_will_rename_patterns(
12811        mut self,
12812        will_rename: Option<&FileOperationRegistrationOptions>,
12813    ) -> Self {
12814        if let Some(will_rename) = will_rename {
12815            self.will_rename = will_rename
12816                .filters
12817                .iter()
12818                .filter_map(|filter| filter.try_into().log_err())
12819                .collect();
12820        }
12821        self
12822    }
12823
12824    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
12825        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
12826    }
12827    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
12828        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
12829    }
12830}
12831
12832impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
12833    type Error = globset::Error;
12834    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
12835        Ok(Self {
12836            kind: ops.pattern.matches.clone(),
12837            glob: GlobBuilder::new(&ops.pattern.glob)
12838                .case_insensitive(
12839                    ops.pattern
12840                        .options
12841                        .as_ref()
12842                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
12843                )
12844                .build()?
12845                .compile_matcher(),
12846        })
12847    }
12848}
12849struct RenameActionPredicate {
12850    glob: GlobMatcher,
12851    kind: Option<FileOperationPatternKind>,
12852}
12853
12854impl RenameActionPredicate {
12855    // Returns true if language server should be notified
12856    fn eval(&self, path: &str, is_dir: bool) -> bool {
12857        self.kind.as_ref().is_none_or(|kind| {
12858            let expected_kind = if is_dir {
12859                FileOperationPatternKind::Folder
12860            } else {
12861                FileOperationPatternKind::File
12862            };
12863            kind == &expected_kind
12864        }) && self.glob.is_match(path)
12865    }
12866}
12867
12868#[derive(Default)]
12869struct LanguageServerWatchedPaths {
12870    worktree_paths: HashMap<WorktreeId, GlobSet>,
12871    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
12872}
12873
12874#[derive(Default)]
12875struct LanguageServerWatchedPathsBuilder {
12876    worktree_paths: HashMap<WorktreeId, GlobSet>,
12877    abs_paths: HashMap<Arc<Path>, GlobSet>,
12878}
12879
12880impl LanguageServerWatchedPathsBuilder {
12881    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
12882        self.worktree_paths.insert(worktree_id, glob_set);
12883    }
12884    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
12885        self.abs_paths.insert(path, glob_set);
12886    }
12887    fn build(
12888        self,
12889        fs: Arc<dyn Fs>,
12890        language_server_id: LanguageServerId,
12891        cx: &mut Context<LspStore>,
12892    ) -> LanguageServerWatchedPaths {
12893        let project = cx.weak_entity();
12894
12895        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
12896        let abs_paths = self
12897            .abs_paths
12898            .into_iter()
12899            .map(|(abs_path, globset)| {
12900                let task = cx.spawn({
12901                    let abs_path = abs_path.clone();
12902                    let fs = fs.clone();
12903
12904                    let lsp_store = project.clone();
12905                    async move |_, cx| {
12906                        maybe!(async move {
12907                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
12908                            while let Some(update) = push_updates.0.next().await {
12909                                let action = lsp_store
12910                                    .update(cx, |this, _| {
12911                                        let Some(local) = this.as_local() else {
12912                                            return ControlFlow::Break(());
12913                                        };
12914                                        let Some(watcher) = local
12915                                            .language_server_watched_paths
12916                                            .get(&language_server_id)
12917                                        else {
12918                                            return ControlFlow::Break(());
12919                                        };
12920                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
12921                                            "Watched abs path is not registered with a watcher",
12922                                        );
12923                                        let matching_entries = update
12924                                            .into_iter()
12925                                            .filter(|event| globs.is_match(&event.path))
12926                                            .collect::<Vec<_>>();
12927                                        this.lsp_notify_abs_paths_changed(
12928                                            language_server_id,
12929                                            matching_entries,
12930                                        );
12931                                        ControlFlow::Continue(())
12932                                    })
12933                                    .ok()?;
12934
12935                                if action.is_break() {
12936                                    break;
12937                                }
12938                            }
12939                            Some(())
12940                        })
12941                        .await;
12942                    }
12943                });
12944                (abs_path, (globset, task))
12945            })
12946            .collect();
12947        LanguageServerWatchedPaths {
12948            worktree_paths: self.worktree_paths,
12949            abs_paths,
12950        }
12951    }
12952}
12953
12954struct LspBufferSnapshot {
12955    version: i32,
12956    snapshot: TextBufferSnapshot,
12957}
12958
12959/// A prompt requested by LSP server.
12960#[derive(Clone, Debug)]
12961pub struct LanguageServerPromptRequest {
12962    pub level: PromptLevel,
12963    pub message: String,
12964    pub actions: Vec<MessageActionItem>,
12965    pub lsp_name: String,
12966    pub(crate) response_channel: Sender<MessageActionItem>,
12967}
12968
12969impl LanguageServerPromptRequest {
12970    pub async fn respond(self, index: usize) -> Option<()> {
12971        if let Some(response) = self.actions.into_iter().nth(index) {
12972            self.response_channel.send(response).await.ok()
12973        } else {
12974            None
12975        }
12976    }
12977}
12978impl PartialEq for LanguageServerPromptRequest {
12979    fn eq(&self, other: &Self) -> bool {
12980        self.message == other.message && self.actions == other.actions
12981    }
12982}
12983
12984#[derive(Clone, Debug, PartialEq)]
12985pub enum LanguageServerLogType {
12986    Log(MessageType),
12987    Trace { verbose_info: Option<String> },
12988    Rpc { received: bool },
12989}
12990
12991impl LanguageServerLogType {
12992    pub fn to_proto(&self) -> proto::language_server_log::LogType {
12993        match self {
12994            Self::Log(log_type) => {
12995                use proto::log_message::LogLevel;
12996                let level = match *log_type {
12997                    MessageType::ERROR => LogLevel::Error,
12998                    MessageType::WARNING => LogLevel::Warning,
12999                    MessageType::INFO => LogLevel::Info,
13000                    MessageType::LOG => LogLevel::Log,
13001                    other => {
13002                        log::warn!("Unknown lsp log message type: {other:?}");
13003                        LogLevel::Log
13004                    }
13005                };
13006                proto::language_server_log::LogType::Log(proto::LogMessage {
13007                    level: level as i32,
13008                })
13009            }
13010            Self::Trace { verbose_info } => {
13011                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13012                    verbose_info: verbose_info.to_owned(),
13013                })
13014            }
13015            Self::Rpc { received } => {
13016                let kind = if *received {
13017                    proto::rpc_message::Kind::Received
13018                } else {
13019                    proto::rpc_message::Kind::Sent
13020                };
13021                let kind = kind as i32;
13022                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13023            }
13024        }
13025    }
13026
13027    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13028        use proto::log_message::LogLevel;
13029        use proto::rpc_message;
13030        match log_type {
13031            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13032                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13033                    LogLevel::Error => MessageType::ERROR,
13034                    LogLevel::Warning => MessageType::WARNING,
13035                    LogLevel::Info => MessageType::INFO,
13036                    LogLevel::Log => MessageType::LOG,
13037                },
13038            ),
13039            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13040                verbose_info: trace_message.verbose_info,
13041            },
13042            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13043                received: match rpc_message::Kind::from_i32(message.kind)
13044                    .unwrap_or(rpc_message::Kind::Received)
13045                {
13046                    rpc_message::Kind::Received => true,
13047                    rpc_message::Kind::Sent => false,
13048                },
13049            },
13050        }
13051    }
13052}
13053
13054pub struct WorkspaceRefreshTask {
13055    refresh_tx: mpsc::Sender<()>,
13056    progress_tx: mpsc::Sender<()>,
13057    #[allow(dead_code)]
13058    task: Task<()>,
13059}
13060
13061pub enum LanguageServerState {
13062    Starting {
13063        startup: Task<Option<Arc<LanguageServer>>>,
13064        /// List of language servers that will be added to the workspace once it's initialization completes.
13065        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13066    },
13067
13068    Running {
13069        adapter: Arc<CachedLspAdapter>,
13070        server: Arc<LanguageServer>,
13071        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13072        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13073    },
13074}
13075
13076impl LanguageServerState {
13077    fn add_workspace_folder(&self, uri: Uri) {
13078        match self {
13079            LanguageServerState::Starting {
13080                pending_workspace_folders,
13081                ..
13082            } => {
13083                pending_workspace_folders.lock().insert(uri);
13084            }
13085            LanguageServerState::Running { server, .. } => {
13086                server.add_workspace_folder(uri);
13087            }
13088        }
13089    }
13090    fn _remove_workspace_folder(&self, uri: Uri) {
13091        match self {
13092            LanguageServerState::Starting {
13093                pending_workspace_folders,
13094                ..
13095            } => {
13096                pending_workspace_folders.lock().remove(&uri);
13097            }
13098            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13099        }
13100    }
13101}
13102
13103impl std::fmt::Debug for LanguageServerState {
13104    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13105        match self {
13106            LanguageServerState::Starting { .. } => {
13107                f.debug_struct("LanguageServerState::Starting").finish()
13108            }
13109            LanguageServerState::Running { .. } => {
13110                f.debug_struct("LanguageServerState::Running").finish()
13111            }
13112        }
13113    }
13114}
13115
13116#[derive(Clone, Debug, Serialize)]
13117pub struct LanguageServerProgress {
13118    pub is_disk_based_diagnostics_progress: bool,
13119    pub is_cancellable: bool,
13120    pub title: Option<String>,
13121    pub message: Option<String>,
13122    pub percentage: Option<usize>,
13123    #[serde(skip_serializing)]
13124    pub last_update_at: Instant,
13125}
13126
13127#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13128pub struct DiagnosticSummary {
13129    pub error_count: usize,
13130    pub warning_count: usize,
13131}
13132
13133impl DiagnosticSummary {
13134    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13135        let mut this = Self {
13136            error_count: 0,
13137            warning_count: 0,
13138        };
13139
13140        for entry in diagnostics {
13141            if entry.diagnostic.is_primary {
13142                match entry.diagnostic.severity {
13143                    DiagnosticSeverity::ERROR => this.error_count += 1,
13144                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13145                    _ => {}
13146                }
13147            }
13148        }
13149
13150        this
13151    }
13152
13153    pub fn is_empty(&self) -> bool {
13154        self.error_count == 0 && self.warning_count == 0
13155    }
13156
13157    pub fn to_proto(
13158        self,
13159        language_server_id: LanguageServerId,
13160        path: &RelPath,
13161    ) -> proto::DiagnosticSummary {
13162        proto::DiagnosticSummary {
13163            path: path.to_proto(),
13164            language_server_id: language_server_id.0 as u64,
13165            error_count: self.error_count as u32,
13166            warning_count: self.warning_count as u32,
13167        }
13168    }
13169}
13170
13171#[derive(Clone, Debug)]
13172pub enum CompletionDocumentation {
13173    /// There is no documentation for this completion.
13174    Undocumented,
13175    /// A single line of documentation.
13176    SingleLine(SharedString),
13177    /// Multiple lines of plain text documentation.
13178    MultiLinePlainText(SharedString),
13179    /// Markdown documentation.
13180    MultiLineMarkdown(SharedString),
13181    /// Both single line and multiple lines of plain text documentation.
13182    SingleLineAndMultiLinePlainText {
13183        single_line: SharedString,
13184        plain_text: Option<SharedString>,
13185    },
13186}
13187
13188impl CompletionDocumentation {
13189    #[cfg(any(test, feature = "test-support"))]
13190    pub fn text(&self) -> SharedString {
13191        match self {
13192            CompletionDocumentation::Undocumented => "".into(),
13193            CompletionDocumentation::SingleLine(s) => s.clone(),
13194            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13195            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13196            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13197                single_line.clone()
13198            }
13199        }
13200    }
13201}
13202
13203impl From<lsp::Documentation> for CompletionDocumentation {
13204    fn from(docs: lsp::Documentation) -> Self {
13205        match docs {
13206            lsp::Documentation::String(text) => {
13207                if text.lines().count() <= 1 {
13208                    CompletionDocumentation::SingleLine(text.into())
13209                } else {
13210                    CompletionDocumentation::MultiLinePlainText(text.into())
13211                }
13212            }
13213
13214            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13215                lsp::MarkupKind::PlainText => {
13216                    if value.lines().count() <= 1 {
13217                        CompletionDocumentation::SingleLine(value.into())
13218                    } else {
13219                        CompletionDocumentation::MultiLinePlainText(value.into())
13220                    }
13221                }
13222
13223                lsp::MarkupKind::Markdown => {
13224                    CompletionDocumentation::MultiLineMarkdown(value.into())
13225                }
13226            },
13227        }
13228    }
13229}
13230
13231pub enum ResolvedHint {
13232    Resolved(InlayHint),
13233    Resolving(Shared<Task<()>>),
13234}
13235
13236fn glob_literal_prefix(glob: &Path) -> PathBuf {
13237    glob.components()
13238        .take_while(|component| match component {
13239            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13240            _ => true,
13241        })
13242        .collect()
13243}
13244
13245pub struct SshLspAdapter {
13246    name: LanguageServerName,
13247    binary: LanguageServerBinary,
13248    initialization_options: Option<String>,
13249    code_action_kinds: Option<Vec<CodeActionKind>>,
13250}
13251
13252impl SshLspAdapter {
13253    pub fn new(
13254        name: LanguageServerName,
13255        binary: LanguageServerBinary,
13256        initialization_options: Option<String>,
13257        code_action_kinds: Option<String>,
13258    ) -> Self {
13259        Self {
13260            name,
13261            binary,
13262            initialization_options,
13263            code_action_kinds: code_action_kinds
13264                .as_ref()
13265                .and_then(|c| serde_json::from_str(c).ok()),
13266        }
13267    }
13268}
13269
13270impl LspInstaller for SshLspAdapter {
13271    type BinaryVersion = ();
13272    async fn check_if_user_installed(
13273        &self,
13274        _: &dyn LspAdapterDelegate,
13275        _: Option<Toolchain>,
13276        _: &AsyncApp,
13277    ) -> Option<LanguageServerBinary> {
13278        Some(self.binary.clone())
13279    }
13280
13281    async fn cached_server_binary(
13282        &self,
13283        _: PathBuf,
13284        _: &dyn LspAdapterDelegate,
13285    ) -> Option<LanguageServerBinary> {
13286        None
13287    }
13288
13289    async fn fetch_latest_server_version(
13290        &self,
13291        _: &dyn LspAdapterDelegate,
13292        _: bool,
13293        _: &mut AsyncApp,
13294    ) -> Result<()> {
13295        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13296    }
13297
13298    async fn fetch_server_binary(
13299        &self,
13300        _: (),
13301        _: PathBuf,
13302        _: &dyn LspAdapterDelegate,
13303    ) -> Result<LanguageServerBinary> {
13304        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13305    }
13306}
13307
13308#[async_trait(?Send)]
13309impl LspAdapter for SshLspAdapter {
13310    fn name(&self) -> LanguageServerName {
13311        self.name.clone()
13312    }
13313
13314    async fn initialization_options(
13315        self: Arc<Self>,
13316        _: &Arc<dyn LspAdapterDelegate>,
13317    ) -> Result<Option<serde_json::Value>> {
13318        let Some(options) = &self.initialization_options else {
13319            return Ok(None);
13320        };
13321        let result = serde_json::from_str(options)?;
13322        Ok(result)
13323    }
13324
13325    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13326        self.code_action_kinds.clone()
13327    }
13328}
13329
13330pub fn language_server_settings<'a>(
13331    delegate: &'a dyn LspAdapterDelegate,
13332    language: &LanguageServerName,
13333    cx: &'a App,
13334) -> Option<&'a LspSettings> {
13335    language_server_settings_for(
13336        SettingsLocation {
13337            worktree_id: delegate.worktree_id(),
13338            path: RelPath::empty(),
13339        },
13340        language,
13341        cx,
13342    )
13343}
13344
13345pub(crate) fn language_server_settings_for<'a>(
13346    location: SettingsLocation<'a>,
13347    language: &LanguageServerName,
13348    cx: &'a App,
13349) -> Option<&'a LspSettings> {
13350    ProjectSettings::get(Some(location), cx).lsp.get(language)
13351}
13352
13353pub struct LocalLspAdapterDelegate {
13354    lsp_store: WeakEntity<LspStore>,
13355    worktree: worktree::Snapshot,
13356    fs: Arc<dyn Fs>,
13357    http_client: Arc<dyn HttpClient>,
13358    language_registry: Arc<LanguageRegistry>,
13359    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13360}
13361
13362impl LocalLspAdapterDelegate {
13363    pub fn new(
13364        language_registry: Arc<LanguageRegistry>,
13365        environment: &Entity<ProjectEnvironment>,
13366        lsp_store: WeakEntity<LspStore>,
13367        worktree: &Entity<Worktree>,
13368        http_client: Arc<dyn HttpClient>,
13369        fs: Arc<dyn Fs>,
13370        cx: &mut App,
13371    ) -> Arc<Self> {
13372        let load_shell_env_task = environment.update(cx, |env, cx| {
13373            env.get_worktree_environment(worktree.clone(), cx)
13374        });
13375
13376        Arc::new(Self {
13377            lsp_store,
13378            worktree: worktree.read(cx).snapshot(),
13379            fs,
13380            http_client,
13381            language_registry,
13382            load_shell_env_task,
13383        })
13384    }
13385
13386    fn from_local_lsp(
13387        local: &LocalLspStore,
13388        worktree: &Entity<Worktree>,
13389        cx: &mut App,
13390    ) -> Arc<Self> {
13391        Self::new(
13392            local.languages.clone(),
13393            &local.environment,
13394            local.weak.clone(),
13395            worktree,
13396            local.http_client.clone(),
13397            local.fs.clone(),
13398            cx,
13399        )
13400    }
13401}
13402
13403#[async_trait]
13404impl LspAdapterDelegate for LocalLspAdapterDelegate {
13405    fn show_notification(&self, message: &str, cx: &mut App) {
13406        self.lsp_store
13407            .update(cx, |_, cx| {
13408                cx.emit(LspStoreEvent::Notification(message.to_owned()))
13409            })
13410            .ok();
13411    }
13412
13413    fn http_client(&self) -> Arc<dyn HttpClient> {
13414        self.http_client.clone()
13415    }
13416
13417    fn worktree_id(&self) -> WorktreeId {
13418        self.worktree.id()
13419    }
13420
13421    fn worktree_root_path(&self) -> &Path {
13422        self.worktree.abs_path().as_ref()
13423    }
13424
13425    async fn shell_env(&self) -> HashMap<String, String> {
13426        let task = self.load_shell_env_task.clone();
13427        task.await.unwrap_or_default()
13428    }
13429
13430    async fn npm_package_installed_version(
13431        &self,
13432        package_name: &str,
13433    ) -> Result<Option<(PathBuf, String)>> {
13434        let local_package_directory = self.worktree_root_path();
13435        let node_modules_directory = local_package_directory.join("node_modules");
13436
13437        if let Some(version) =
13438            read_package_installed_version(node_modules_directory.clone(), package_name).await?
13439        {
13440            return Ok(Some((node_modules_directory, version)));
13441        }
13442        let Some(npm) = self.which("npm".as_ref()).await else {
13443            log::warn!(
13444                "Failed to find npm executable for {:?}",
13445                local_package_directory
13446            );
13447            return Ok(None);
13448        };
13449
13450        let env = self.shell_env().await;
13451        let output = util::command::new_smol_command(&npm)
13452            .args(["root", "-g"])
13453            .envs(env)
13454            .current_dir(local_package_directory)
13455            .output()
13456            .await?;
13457        let global_node_modules =
13458            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
13459
13460        if let Some(version) =
13461            read_package_installed_version(global_node_modules.clone(), package_name).await?
13462        {
13463            return Ok(Some((global_node_modules, version)));
13464        }
13465        return Ok(None);
13466    }
13467
13468    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
13469        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
13470        if self.fs.is_file(&worktree_abs_path).await {
13471            worktree_abs_path.pop();
13472        }
13473
13474        let env = self.shell_env().await;
13475
13476        let shell_path = env.get("PATH").cloned();
13477
13478        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
13479    }
13480
13481    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
13482        let mut working_dir = self.worktree_root_path().to_path_buf();
13483        if self.fs.is_file(&working_dir).await {
13484            working_dir.pop();
13485        }
13486        let output = util::command::new_smol_command(&command.path)
13487            .args(command.arguments)
13488            .envs(command.env.clone().unwrap_or_default())
13489            .current_dir(working_dir)
13490            .output()
13491            .await?;
13492
13493        anyhow::ensure!(
13494            output.status.success(),
13495            "{}, stdout: {:?}, stderr: {:?}",
13496            output.status,
13497            String::from_utf8_lossy(&output.stdout),
13498            String::from_utf8_lossy(&output.stderr)
13499        );
13500        Ok(())
13501    }
13502
13503    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
13504        self.language_registry
13505            .update_lsp_binary_status(server_name, status);
13506    }
13507
13508    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
13509        self.language_registry
13510            .all_lsp_adapters()
13511            .into_iter()
13512            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
13513            .collect()
13514    }
13515
13516    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
13517        let dir = self.language_registry.language_server_download_dir(name)?;
13518
13519        if !dir.exists() {
13520            smol::fs::create_dir_all(&dir)
13521                .await
13522                .context("failed to create container directory")
13523                .log_err()?;
13524        }
13525
13526        Some(dir)
13527    }
13528
13529    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
13530        let entry = self
13531            .worktree
13532            .entry_for_path(path)
13533            .with_context(|| format!("no worktree entry for path {path:?}"))?;
13534        let abs_path = self.worktree.absolutize(&entry.path);
13535        self.fs.load(&abs_path).await
13536    }
13537}
13538
13539async fn populate_labels_for_symbols(
13540    symbols: Vec<CoreSymbol>,
13541    language_registry: &Arc<LanguageRegistry>,
13542    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13543    output: &mut Vec<Symbol>,
13544) {
13545    #[allow(clippy::mutable_key_type)]
13546    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
13547
13548    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
13549    for symbol in symbols {
13550        let Some(file_name) = symbol.path.file_name() else {
13551            continue;
13552        };
13553        let language = language_registry
13554            .load_language_for_file_path(Path::new(file_name))
13555            .await
13556            .ok()
13557            .or_else(|| {
13558                unknown_paths.insert(file_name.into());
13559                None
13560            });
13561        symbols_by_language
13562            .entry(language)
13563            .or_default()
13564            .push(symbol);
13565    }
13566
13567    for unknown_path in unknown_paths {
13568        log::info!("no language found for symbol in file {unknown_path:?}");
13569    }
13570
13571    let mut label_params = Vec::new();
13572    for (language, mut symbols) in symbols_by_language {
13573        label_params.clear();
13574        label_params.extend(
13575            symbols
13576                .iter_mut()
13577                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
13578        );
13579
13580        let mut labels = Vec::new();
13581        if let Some(language) = language {
13582            let lsp_adapter = lsp_adapter.clone().or_else(|| {
13583                language_registry
13584                    .lsp_adapters(&language.name())
13585                    .first()
13586                    .cloned()
13587            });
13588            if let Some(lsp_adapter) = lsp_adapter {
13589                labels = lsp_adapter
13590                    .labels_for_symbols(&label_params, &language)
13591                    .await
13592                    .log_err()
13593                    .unwrap_or_default();
13594            }
13595        }
13596
13597        for ((symbol, (name, _)), label) in symbols
13598            .into_iter()
13599            .zip(label_params.drain(..))
13600            .zip(labels.into_iter().chain(iter::repeat(None)))
13601        {
13602            output.push(Symbol {
13603                language_server_name: symbol.language_server_name,
13604                source_worktree_id: symbol.source_worktree_id,
13605                source_language_server_id: symbol.source_language_server_id,
13606                path: symbol.path,
13607                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
13608                name,
13609                kind: symbol.kind,
13610                range: symbol.range,
13611            });
13612        }
13613    }
13614}
13615
13616fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
13617    match server.capabilities().text_document_sync.as_ref()? {
13618        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
13619            // Server wants didSave but didn't specify includeText.
13620            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
13621            // Server doesn't want didSave at all.
13622            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
13623            // Server provided SaveOptions.
13624            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
13625                Some(save_options.include_text.unwrap_or(false))
13626            }
13627        },
13628        // We do not have any save info. Kind affects didChange only.
13629        lsp::TextDocumentSyncCapability::Kind(_) => None,
13630    }
13631}
13632
13633/// Completion items are displayed in a `UniformList`.
13634/// Usually, those items are single-line strings, but in LSP responses,
13635/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
13636/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
13637/// 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,
13638/// breaking the completions menu presentation.
13639///
13640/// 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.
13641fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
13642    let mut new_text = String::with_capacity(label.text.len());
13643    let mut offset_map = vec![0; label.text.len() + 1];
13644    let mut last_char_was_space = false;
13645    let mut new_idx = 0;
13646    let chars = label.text.char_indices().fuse();
13647    let mut newlines_removed = false;
13648
13649    for (idx, c) in chars {
13650        offset_map[idx] = new_idx;
13651
13652        match c {
13653            '\n' if last_char_was_space => {
13654                newlines_removed = true;
13655            }
13656            '\t' | ' ' if last_char_was_space => {}
13657            '\n' if !last_char_was_space => {
13658                new_text.push(' ');
13659                new_idx += 1;
13660                last_char_was_space = true;
13661                newlines_removed = true;
13662            }
13663            ' ' | '\t' => {
13664                new_text.push(' ');
13665                new_idx += 1;
13666                last_char_was_space = true;
13667            }
13668            _ => {
13669                new_text.push(c);
13670                new_idx += c.len_utf8();
13671                last_char_was_space = false;
13672            }
13673        }
13674    }
13675    offset_map[label.text.len()] = new_idx;
13676
13677    // Only modify the label if newlines were removed.
13678    if !newlines_removed {
13679        return;
13680    }
13681
13682    let last_index = new_idx;
13683    let mut run_ranges_errors = Vec::new();
13684    label.runs.retain_mut(|(range, _)| {
13685        match offset_map.get(range.start) {
13686            Some(&start) => range.start = start,
13687            None => {
13688                run_ranges_errors.push(range.clone());
13689                return false;
13690            }
13691        }
13692
13693        match offset_map.get(range.end) {
13694            Some(&end) => range.end = end,
13695            None => {
13696                run_ranges_errors.push(range.clone());
13697                range.end = last_index;
13698            }
13699        }
13700        true
13701    });
13702    if !run_ranges_errors.is_empty() {
13703        log::error!(
13704            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
13705            label.text
13706        );
13707    }
13708
13709    let mut wrong_filter_range = None;
13710    if label.filter_range == (0..label.text.len()) {
13711        label.filter_range = 0..new_text.len();
13712    } else {
13713        let mut original_filter_range = Some(label.filter_range.clone());
13714        match offset_map.get(label.filter_range.start) {
13715            Some(&start) => label.filter_range.start = start,
13716            None => {
13717                wrong_filter_range = original_filter_range.take();
13718                label.filter_range.start = last_index;
13719            }
13720        }
13721
13722        match offset_map.get(label.filter_range.end) {
13723            Some(&end) => label.filter_range.end = end,
13724            None => {
13725                wrong_filter_range = original_filter_range.take();
13726                label.filter_range.end = last_index;
13727            }
13728        }
13729    }
13730    if let Some(wrong_filter_range) = wrong_filter_range {
13731        log::error!(
13732            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
13733            label.text
13734        );
13735    }
13736
13737    label.text = new_text;
13738}
13739
13740#[cfg(test)]
13741mod tests {
13742    use language::HighlightId;
13743
13744    use super::*;
13745
13746    #[test]
13747    fn test_glob_literal_prefix() {
13748        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
13749        assert_eq!(
13750            glob_literal_prefix(Path::new("node_modules/**/*.js")),
13751            Path::new("node_modules")
13752        );
13753        assert_eq!(
13754            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13755            Path::new("foo")
13756        );
13757        assert_eq!(
13758            glob_literal_prefix(Path::new("foo/bar/baz.js")),
13759            Path::new("foo/bar/baz.js")
13760        );
13761
13762        #[cfg(target_os = "windows")]
13763        {
13764            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
13765            assert_eq!(
13766                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
13767                Path::new("node_modules")
13768            );
13769            assert_eq!(
13770                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13771                Path::new("foo")
13772            );
13773            assert_eq!(
13774                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
13775                Path::new("foo/bar/baz.js")
13776            );
13777        }
13778    }
13779
13780    #[test]
13781    fn test_multi_len_chars_normalization() {
13782        let mut label = CodeLabel::new(
13783            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
13784            0..6,
13785            vec![(0..6, HighlightId(1))],
13786        );
13787        ensure_uniform_list_compatible_label(&mut label);
13788        assert_eq!(
13789            label,
13790            CodeLabel::new(
13791                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
13792                0..6,
13793                vec![(0..6, HighlightId(1))],
13794            )
13795        );
13796    }
13797}