lsp_store.rs

    1//! LSP store provides unified access to the language server protocol.
    2//! The consumers of LSP store can interact with language servers without knowing exactly which language server they're interacting with.
    3//!
    4//! # Local/Remote LSP Stores
    5//! This module is split up into three distinct parts:
    6//! - [`LocalLspStore`], which is ran on the host machine (either project host or SSH host), that manages the lifecycle of language servers.
    7//! - [`RemoteLspStore`], which is ran on the remote machine (project guests) which is mostly about passing through the requests via RPC.
    8//!   The remote stores don't really care about which language server they're running against - they don't usually get to decide which language server is going to responsible for handling their request.
    9//! - [`LspStore`], which unifies the two under one consistent interface for interacting with language servers.
   10//!
   11//! Most of the interesting work happens at the local layer, as bulk of the complexity is with managing the lifecycle of language servers. The actual implementation of the LSP protocol is handled by [`lsp`] crate.
   12pub mod clangd_ext;
   13pub mod json_language_server_ext;
   14pub mod log_store;
   15pub mod lsp_ext_command;
   16pub mod rust_analyzer_ext;
   17pub mod vue_language_server_ext;
   18
   19mod inlay_hint_cache;
   20
   21use self::inlay_hint_cache::BufferInlayHints;
   22use crate::{
   23    CodeAction, ColorPresentation, Completion, CompletionDisplayOptions, CompletionResponse,
   24    CompletionSource, CoreCompletion, DocumentColor, Hover, InlayHint, InlayId, LocationLink,
   25    LspAction, LspPullDiagnostics, ManifestProvidersStore, Project, ProjectItem, ProjectPath,
   26    ProjectTransaction, PulledDiagnostics, ResolveState, Symbol,
   27    buffer_store::{BufferStore, BufferStoreEvent},
   28    environment::ProjectEnvironment,
   29    lsp_command::{self, *},
   30    lsp_store::{
   31        self,
   32        inlay_hint_cache::BufferChunk,
   33        log_store::{GlobalLogStore, LanguageServerKind},
   34    },
   35    manifest_tree::{
   36        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   37        ManifestTree,
   38    },
   39    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   40    project_settings::{LspSettings, ProjectSettings},
   41    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   42    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   43    yarn::YarnPathStore,
   44};
   45use anyhow::{Context as _, Result, anyhow};
   46use async_trait::async_trait;
   47use client::{TypedEnvelope, proto};
   48use clock::Global;
   49use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   50use futures::{
   51    AsyncWriteExt, Future, FutureExt, StreamExt,
   52    future::{Either, Shared, join_all, pending, select},
   53    select, select_biased,
   54    stream::FuturesUnordered,
   55};
   56use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   57use gpui::{
   58    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString, Task,
   59    WeakEntity,
   60};
   61use http_client::HttpClient;
   62use itertools::Itertools as _;
   63use language::{
   64    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, CodeLabel, Diagnostic,
   65    DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language, LanguageName,
   66    LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller, ManifestDelegate,
   67    ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Toolchain,
   68    Transaction, Unclipped,
   69    language_settings::{FormatOnSave, Formatter, LanguageSettings, language_settings},
   70    point_to_lsp,
   71    proto::{
   72        deserialize_anchor, deserialize_lsp_edit, deserialize_version, serialize_anchor,
   73        serialize_lsp_edit, serialize_version,
   74    },
   75    range_from_lsp, range_to_lsp,
   76};
   77use lsp::{
   78    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   79    DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   80    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   81    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LSP_REQUEST_TIMEOUT,
   82    LanguageServer, LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId,
   83    LanguageServerName, LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType,
   84    OneOf, RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri,
   85    WillRenameFiles, WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   86};
   87use node_runtime::read_package_installed_version;
   88use parking_lot::Mutex;
   89use postage::{mpsc, sink::Sink, stream::Stream, watch};
   90use rand::prelude::*;
   91use rpc::{
   92    AnyProtoClient, ErrorCode, ErrorExt as _,
   93    proto::{LspRequestId, LspRequestMessage as _},
   94};
   95use serde::Serialize;
   96use settings::{Settings, SettingsLocation, SettingsStore};
   97use sha2::{Digest, Sha256};
   98use smol::channel::Sender;
   99use snippet::Snippet;
  100use std::{
  101    any::TypeId,
  102    borrow::Cow,
  103    cell::RefCell,
  104    cmp::{Ordering, Reverse},
  105    convert::TryInto,
  106    ffi::OsStr,
  107    future::ready,
  108    iter, mem,
  109    ops::{ControlFlow, Range},
  110    path::{self, Path, PathBuf},
  111    pin::pin,
  112    rc::Rc,
  113    sync::{
  114        Arc,
  115        atomic::{self, AtomicUsize},
  116    },
  117    time::{Duration, Instant},
  118};
  119use sum_tree::Dimensions;
  120use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, Point, ToPoint as _};
  121
  122use util::{
  123    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  124    paths::{PathStyle, SanitizedPath},
  125    post_inc,
  126    rel_path::RelPath,
  127};
  128
  129pub use fs::*;
  130pub use language::Location;
  131pub use lsp_store::inlay_hint_cache::{CacheInlayHints, InvalidationStrategy};
  132#[cfg(any(test, feature = "test-support"))]
  133pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  134pub use worktree::{
  135    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  136    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  137};
  138
  139const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  140pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  141const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  142
  143#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  144pub enum ProgressToken {
  145    Number(i32),
  146    String(SharedString),
  147}
  148
  149impl std::fmt::Display for ProgressToken {
  150    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  151        match self {
  152            Self::Number(number) => write!(f, "{number}"),
  153            Self::String(string) => write!(f, "{string}"),
  154        }
  155    }
  156}
  157
  158impl ProgressToken {
  159    fn from_lsp(value: lsp::NumberOrString) -> Self {
  160        match value {
  161            lsp::NumberOrString::Number(number) => Self::Number(number),
  162            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  163        }
  164    }
  165
  166    fn to_lsp(&self) -> lsp::NumberOrString {
  167        match self {
  168            Self::Number(number) => lsp::NumberOrString::Number(*number),
  169            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  170        }
  171    }
  172
  173    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  174        Some(match value.value? {
  175            proto::progress_token::Value::Number(number) => Self::Number(number),
  176            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  177        })
  178    }
  179
  180    fn to_proto(&self) -> proto::ProgressToken {
  181        proto::ProgressToken {
  182            value: Some(match self {
  183                Self::Number(number) => proto::progress_token::Value::Number(*number),
  184                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  185            }),
  186        }
  187    }
  188}
  189
  190#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  191pub enum FormatTrigger {
  192    Save,
  193    Manual,
  194}
  195
  196pub enum LspFormatTarget {
  197    Buffers,
  198    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  199}
  200
  201pub type OpenLspBufferHandle = Entity<Entity<Buffer>>;
  202
  203impl FormatTrigger {
  204    fn from_proto(value: i32) -> FormatTrigger {
  205        match value {
  206            0 => FormatTrigger::Save,
  207            1 => FormatTrigger::Manual,
  208            _ => FormatTrigger::Save,
  209        }
  210    }
  211}
  212
  213#[derive(Clone)]
  214struct UnifiedLanguageServer {
  215    id: LanguageServerId,
  216    project_roots: HashSet<Arc<RelPath>>,
  217}
  218
  219#[derive(Clone, Hash, PartialEq, Eq)]
  220struct LanguageServerSeed {
  221    worktree_id: WorktreeId,
  222    name: LanguageServerName,
  223    toolchain: Option<Toolchain>,
  224    settings: Arc<LspSettings>,
  225}
  226
  227#[derive(Debug)]
  228pub struct DocumentDiagnosticsUpdate<'a, D> {
  229    pub diagnostics: D,
  230    pub result_id: Option<String>,
  231    pub server_id: LanguageServerId,
  232    pub disk_based_sources: Cow<'a, [String]>,
  233}
  234
  235pub struct DocumentDiagnostics {
  236    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  237    document_abs_path: PathBuf,
  238    version: Option<i32>,
  239}
  240
  241#[derive(Default, Debug)]
  242struct DynamicRegistrations {
  243    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  244    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  245}
  246
  247pub struct LocalLspStore {
  248    weak: WeakEntity<LspStore>,
  249    worktree_store: Entity<WorktreeStore>,
  250    toolchain_store: Entity<LocalToolchainStore>,
  251    http_client: Arc<dyn HttpClient>,
  252    environment: Entity<ProjectEnvironment>,
  253    fs: Arc<dyn Fs>,
  254    languages: Arc<LanguageRegistry>,
  255    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  256    yarn: Entity<YarnPathStore>,
  257    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  258    buffers_being_formatted: HashSet<BufferId>,
  259    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  260    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  261    watched_manifest_filenames: HashSet<ManifestName>,
  262    language_server_paths_watched_for_rename:
  263        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  264    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  265    supplementary_language_servers:
  266        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  267    prettier_store: Entity<PrettierStore>,
  268    next_diagnostic_group_id: usize,
  269    diagnostics: HashMap<
  270        WorktreeId,
  271        HashMap<
  272            Arc<RelPath>,
  273            Vec<(
  274                LanguageServerId,
  275                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  276            )>,
  277        >,
  278    >,
  279    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  280    _subscription: gpui::Subscription,
  281    lsp_tree: LanguageServerTree,
  282    registered_buffers: HashMap<BufferId, usize>,
  283    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  284    buffer_pull_diagnostics_result_ids: HashMap<LanguageServerId, HashMap<PathBuf, Option<String>>>,
  285}
  286
  287impl LocalLspStore {
  288    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  289    pub fn running_language_server_for_id(
  290        &self,
  291        id: LanguageServerId,
  292    ) -> Option<&Arc<LanguageServer>> {
  293        let language_server_state = self.language_servers.get(&id)?;
  294
  295        match language_server_state {
  296            LanguageServerState::Running { server, .. } => Some(server),
  297            LanguageServerState::Starting { .. } => None,
  298        }
  299    }
  300
  301    fn get_or_insert_language_server(
  302        &mut self,
  303        worktree_handle: &Entity<Worktree>,
  304        delegate: Arc<LocalLspAdapterDelegate>,
  305        disposition: &Arc<LaunchDisposition>,
  306        language_name: &LanguageName,
  307        cx: &mut App,
  308    ) -> LanguageServerId {
  309        let key = LanguageServerSeed {
  310            worktree_id: worktree_handle.read(cx).id(),
  311            name: disposition.server_name.clone(),
  312            settings: disposition.settings.clone(),
  313            toolchain: disposition.toolchain.clone(),
  314        };
  315        if let Some(state) = self.language_server_ids.get_mut(&key) {
  316            state.project_roots.insert(disposition.path.path.clone());
  317            state.id
  318        } else {
  319            let adapter = self
  320                .languages
  321                .lsp_adapters(language_name)
  322                .into_iter()
  323                .find(|adapter| adapter.name() == disposition.server_name)
  324                .expect("To find LSP adapter");
  325            let new_language_server_id = self.start_language_server(
  326                worktree_handle,
  327                delegate,
  328                adapter,
  329                disposition.settings.clone(),
  330                key.clone(),
  331                cx,
  332            );
  333            if let Some(state) = self.language_server_ids.get_mut(&key) {
  334                state.project_roots.insert(disposition.path.path.clone());
  335            } else {
  336                debug_assert!(
  337                    false,
  338                    "Expected `start_language_server` to ensure that `key` exists in a map"
  339                );
  340            }
  341            new_language_server_id
  342        }
  343    }
  344
  345    fn start_language_server(
  346        &mut self,
  347        worktree_handle: &Entity<Worktree>,
  348        delegate: Arc<LocalLspAdapterDelegate>,
  349        adapter: Arc<CachedLspAdapter>,
  350        settings: Arc<LspSettings>,
  351        key: LanguageServerSeed,
  352        cx: &mut App,
  353    ) -> LanguageServerId {
  354        let worktree = worktree_handle.read(cx);
  355
  356        let root_path = worktree.abs_path();
  357        let toolchain = key.toolchain.clone();
  358        let override_options = settings.initialization_options.clone();
  359
  360        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  361
  362        let server_id = self.languages.next_language_server_id();
  363        log::trace!(
  364            "attempting to start language server {:?}, path: {root_path:?}, id: {server_id}",
  365            adapter.name.0
  366        );
  367
  368        let binary = self.get_language_server_binary(
  369            adapter.clone(),
  370            settings,
  371            toolchain.clone(),
  372            delegate.clone(),
  373            true,
  374            cx,
  375        );
  376        let pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>> = Default::default();
  377
  378        let pending_server = cx.spawn({
  379            let adapter = adapter.clone();
  380            let server_name = adapter.name.clone();
  381            let stderr_capture = stderr_capture.clone();
  382            #[cfg(any(test, feature = "test-support"))]
  383            let lsp_store = self.weak.clone();
  384            let pending_workspace_folders = pending_workspace_folders.clone();
  385            async move |cx| {
  386                let binary = binary.await?;
  387                #[cfg(any(test, feature = "test-support"))]
  388                if let Some(server) = lsp_store
  389                    .update(&mut cx.clone(), |this, cx| {
  390                        this.languages.create_fake_language_server(
  391                            server_id,
  392                            &server_name,
  393                            binary.clone(),
  394                            &mut cx.to_async(),
  395                        )
  396                    })
  397                    .ok()
  398                    .flatten()
  399                {
  400                    return Ok(server);
  401                }
  402
  403                let code_action_kinds = adapter.code_action_kinds();
  404                lsp::LanguageServer::new(
  405                    stderr_capture,
  406                    server_id,
  407                    server_name,
  408                    binary,
  409                    &root_path,
  410                    code_action_kinds,
  411                    Some(pending_workspace_folders),
  412                    cx,
  413                )
  414            }
  415        });
  416
  417        let startup = {
  418            let server_name = adapter.name.0.clone();
  419            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  420            let key = key.clone();
  421            let adapter = adapter.clone();
  422            let lsp_store = self.weak.clone();
  423            let pending_workspace_folders = pending_workspace_folders.clone();
  424
  425            let pull_diagnostics = ProjectSettings::get_global(cx)
  426                .diagnostics
  427                .lsp_pull_diagnostics
  428                .enabled;
  429            cx.spawn(async move |cx| {
  430                let result = async {
  431                    let language_server = pending_server.await?;
  432
  433                    let workspace_config = Self::workspace_configuration_for_adapter(
  434                        adapter.adapter.clone(),
  435                        &delegate,
  436                        toolchain,
  437                        cx,
  438                    )
  439                    .await?;
  440
  441                    let mut initialization_options = Self::initialization_options_for_adapter(
  442                        adapter.adapter.clone(),
  443                        &delegate,
  444                    )
  445                    .await?;
  446
  447                    match (&mut initialization_options, override_options) {
  448                        (Some(initialization_options), Some(override_options)) => {
  449                            merge_json_value_into(override_options, initialization_options);
  450                        }
  451                        (None, override_options) => initialization_options = override_options,
  452                        _ => {}
  453                    }
  454
  455                    let initialization_params = cx.update(|cx| {
  456                        let mut params =
  457                            language_server.default_initialize_params(pull_diagnostics, cx);
  458                        params.initialization_options = initialization_options;
  459                        adapter.adapter.prepare_initialize_params(params, cx)
  460                    })??;
  461
  462                    Self::setup_lsp_messages(
  463                        lsp_store.clone(),
  464                        &language_server,
  465                        delegate.clone(),
  466                        adapter.clone(),
  467                    );
  468
  469                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  470                        settings: workspace_config,
  471                    };
  472                    let language_server = cx
  473                        .update(|cx| {
  474                            language_server.initialize(
  475                                initialization_params,
  476                                Arc::new(did_change_configuration_params.clone()),
  477                                cx,
  478                            )
  479                        })?
  480                        .await
  481                        .inspect_err(|_| {
  482                            if let Some(lsp_store) = lsp_store.upgrade() {
  483                                lsp_store
  484                                    .update(cx, |lsp_store, cx| {
  485                                        lsp_store.cleanup_lsp_data(server_id);
  486                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  487                                    })
  488                                    .ok();
  489                            }
  490                        })?;
  491
  492                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  493                        did_change_configuration_params,
  494                    )?;
  495
  496                    anyhow::Ok(language_server)
  497                }
  498                .await;
  499
  500                match result {
  501                    Ok(server) => {
  502                        lsp_store
  503                            .update(cx, |lsp_store, cx| {
  504                                lsp_store.insert_newly_running_language_server(
  505                                    adapter,
  506                                    server.clone(),
  507                                    server_id,
  508                                    key,
  509                                    pending_workspace_folders,
  510                                    cx,
  511                                );
  512                            })
  513                            .ok();
  514                        stderr_capture.lock().take();
  515                        Some(server)
  516                    }
  517
  518                    Err(err) => {
  519                        let log = stderr_capture.lock().take().unwrap_or_default();
  520                        delegate.update_status(
  521                            adapter.name(),
  522                            BinaryStatus::Failed {
  523                                error: if log.is_empty() {
  524                                    format!("{err:#}")
  525                                } else {
  526                                    format!("{err:#}\n-- stderr --\n{log}")
  527                                },
  528                            },
  529                        );
  530                        log::error!("Failed to start language server {server_name:?}: {err:?}");
  531                        if !log.is_empty() {
  532                            log::error!("server stderr: {log}");
  533                        }
  534                        None
  535                    }
  536                }
  537            })
  538        };
  539        let state = LanguageServerState::Starting {
  540            startup,
  541            pending_workspace_folders,
  542        };
  543
  544        self.languages
  545            .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  546
  547        self.language_servers.insert(server_id, state);
  548        self.language_server_ids
  549            .entry(key)
  550            .or_insert(UnifiedLanguageServer {
  551                id: server_id,
  552                project_roots: Default::default(),
  553            });
  554        server_id
  555    }
  556
  557    fn get_language_server_binary(
  558        &self,
  559        adapter: Arc<CachedLspAdapter>,
  560        settings: Arc<LspSettings>,
  561        toolchain: Option<Toolchain>,
  562        delegate: Arc<dyn LspAdapterDelegate>,
  563        allow_binary_download: bool,
  564        cx: &mut App,
  565    ) -> Task<Result<LanguageServerBinary>> {
  566        if let Some(settings) = settings.binary.as_ref()
  567            && settings.path.is_some()
  568        {
  569            let settings = settings.clone();
  570
  571            return cx.background_spawn(async move {
  572                let mut env = delegate.shell_env().await;
  573                env.extend(settings.env.unwrap_or_default());
  574
  575                Ok(LanguageServerBinary {
  576                    path: PathBuf::from(&settings.path.unwrap()),
  577                    env: Some(env),
  578                    arguments: settings
  579                        .arguments
  580                        .unwrap_or_default()
  581                        .iter()
  582                        .map(Into::into)
  583                        .collect(),
  584                })
  585            });
  586        }
  587        let lsp_binary_options = LanguageServerBinaryOptions {
  588            allow_path_lookup: !settings
  589                .binary
  590                .as_ref()
  591                .and_then(|b| b.ignore_system_version)
  592                .unwrap_or_default(),
  593            allow_binary_download,
  594            pre_release: settings
  595                .fetch
  596                .as_ref()
  597                .and_then(|f| f.pre_release)
  598                .unwrap_or(false),
  599        };
  600
  601        cx.spawn(async move |cx| {
  602            let binary_result = adapter
  603                .clone()
  604                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  605                .await;
  606
  607            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  608
  609            let mut binary = binary_result?;
  610            let mut shell_env = delegate.shell_env().await;
  611
  612            shell_env.extend(binary.env.unwrap_or_default());
  613
  614            if let Some(settings) = settings.binary.as_ref() {
  615                if let Some(arguments) = &settings.arguments {
  616                    binary.arguments = arguments.iter().map(Into::into).collect();
  617                }
  618                if let Some(env) = &settings.env {
  619                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  620                }
  621            }
  622
  623            binary.env = Some(shell_env);
  624            Ok(binary)
  625        })
  626    }
  627
  628    fn setup_lsp_messages(
  629        lsp_store: WeakEntity<LspStore>,
  630        language_server: &LanguageServer,
  631        delegate: Arc<dyn LspAdapterDelegate>,
  632        adapter: Arc<CachedLspAdapter>,
  633    ) {
  634        let name = language_server.name();
  635        let server_id = language_server.server_id();
  636        language_server
  637            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  638                let adapter = adapter.clone();
  639                let this = lsp_store.clone();
  640                move |mut params, cx| {
  641                    let adapter = adapter.clone();
  642                    if let Some(this) = this.upgrade() {
  643                        this.update(cx, |this, cx| {
  644                            {
  645                                let buffer = params
  646                                    .uri
  647                                    .to_file_path()
  648                                    .map(|file_path| this.get_buffer(&file_path, cx))
  649                                    .ok()
  650                                    .flatten();
  651                                adapter.process_diagnostics(&mut params, server_id, buffer);
  652                            }
  653
  654                            this.merge_lsp_diagnostics(
  655                                DiagnosticSourceKind::Pushed,
  656                                vec![DocumentDiagnosticsUpdate {
  657                                    server_id,
  658                                    diagnostics: params,
  659                                    result_id: None,
  660                                    disk_based_sources: Cow::Borrowed(
  661                                        &adapter.disk_based_diagnostic_sources,
  662                                    ),
  663                                }],
  664                                |_, diagnostic, cx| match diagnostic.source_kind {
  665                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  666                                        adapter.retain_old_diagnostic(diagnostic, cx)
  667                                    }
  668                                    DiagnosticSourceKind::Pulled => true,
  669                                },
  670                                cx,
  671                            )
  672                            .log_err();
  673                        })
  674                        .ok();
  675                    }
  676                }
  677            })
  678            .detach();
  679        language_server
  680            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  681                let adapter = adapter.adapter.clone();
  682                let delegate = delegate.clone();
  683                let this = lsp_store.clone();
  684                move |params, cx| {
  685                    let adapter = adapter.clone();
  686                    let delegate = delegate.clone();
  687                    let this = this.clone();
  688                    let mut cx = cx.clone();
  689                    async move {
  690                        let toolchain_for_id = this
  691                            .update(&mut cx, |this, _| {
  692                                this.as_local()?.language_server_ids.iter().find_map(
  693                                    |(seed, value)| {
  694                                        (value.id == server_id).then(|| seed.toolchain.clone())
  695                                    },
  696                                )
  697                            })?
  698                            .context("Expected the LSP store to be in a local mode")?;
  699                        let workspace_config = Self::workspace_configuration_for_adapter(
  700                            adapter.clone(),
  701                            &delegate,
  702                            toolchain_for_id,
  703                            &mut cx,
  704                        )
  705                        .await?;
  706
  707                        Ok(params
  708                            .items
  709                            .into_iter()
  710                            .map(|item| {
  711                                if let Some(section) = &item.section {
  712                                    workspace_config
  713                                        .get(section)
  714                                        .cloned()
  715                                        .unwrap_or(serde_json::Value::Null)
  716                                } else {
  717                                    workspace_config.clone()
  718                                }
  719                            })
  720                            .collect())
  721                    }
  722                }
  723            })
  724            .detach();
  725
  726        language_server
  727            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  728                let this = lsp_store.clone();
  729                move |_, cx| {
  730                    let this = this.clone();
  731                    let cx = cx.clone();
  732                    async move {
  733                        let Some(server) =
  734                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  735                        else {
  736                            return Ok(None);
  737                        };
  738                        let root = server.workspace_folders();
  739                        Ok(Some(
  740                            root.into_iter()
  741                                .map(|uri| WorkspaceFolder {
  742                                    uri,
  743                                    name: Default::default(),
  744                                })
  745                                .collect(),
  746                        ))
  747                    }
  748                }
  749            })
  750            .detach();
  751        // Even though we don't have handling for these requests, respond to them to
  752        // avoid stalling any language server like `gopls` which waits for a response
  753        // to these requests when initializing.
  754        language_server
  755            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  756                let this = lsp_store.clone();
  757                move |params, cx| {
  758                    let this = this.clone();
  759                    let mut cx = cx.clone();
  760                    async move {
  761                        this.update(&mut cx, |this, _| {
  762                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  763                            {
  764                                status
  765                                    .progress_tokens
  766                                    .insert(ProgressToken::from_lsp(params.token));
  767                            }
  768                        })?;
  769
  770                        Ok(())
  771                    }
  772                }
  773            })
  774            .detach();
  775
  776        language_server
  777            .on_request::<lsp::request::RegisterCapability, _, _>({
  778                let lsp_store = lsp_store.clone();
  779                move |params, cx| {
  780                    let lsp_store = lsp_store.clone();
  781                    let mut cx = cx.clone();
  782                    async move {
  783                        lsp_store
  784                            .update(&mut cx, |lsp_store, cx| {
  785                                if lsp_store.as_local().is_some() {
  786                                    match lsp_store
  787                                        .register_server_capabilities(server_id, params, cx)
  788                                    {
  789                                        Ok(()) => {}
  790                                        Err(e) => {
  791                                            log::error!(
  792                                                "Failed to register server capabilities: {e:#}"
  793                                            );
  794                                        }
  795                                    };
  796                                }
  797                            })
  798                            .ok();
  799                        Ok(())
  800                    }
  801                }
  802            })
  803            .detach();
  804
  805        language_server
  806            .on_request::<lsp::request::UnregisterCapability, _, _>({
  807                let lsp_store = lsp_store.clone();
  808                move |params, cx| {
  809                    let lsp_store = lsp_store.clone();
  810                    let mut cx = cx.clone();
  811                    async move {
  812                        lsp_store
  813                            .update(&mut cx, |lsp_store, cx| {
  814                                if lsp_store.as_local().is_some() {
  815                                    match lsp_store
  816                                        .unregister_server_capabilities(server_id, params, cx)
  817                                    {
  818                                        Ok(()) => {}
  819                                        Err(e) => {
  820                                            log::error!(
  821                                                "Failed to unregister server capabilities: {e:#}"
  822                                            );
  823                                        }
  824                                    }
  825                                }
  826                            })
  827                            .ok();
  828                        Ok(())
  829                    }
  830                }
  831            })
  832            .detach();
  833
  834        language_server
  835            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  836                let this = lsp_store.clone();
  837                move |params, cx| {
  838                    let mut cx = cx.clone();
  839                    let this = this.clone();
  840                    async move {
  841                        LocalLspStore::on_lsp_workspace_edit(
  842                            this.clone(),
  843                            params,
  844                            server_id,
  845                            &mut cx,
  846                        )
  847                        .await
  848                    }
  849                }
  850            })
  851            .detach();
  852
  853        language_server
  854            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  855                let lsp_store = lsp_store.clone();
  856                let request_id = Arc::new(AtomicUsize::new(0));
  857                move |(), cx| {
  858                    let lsp_store = lsp_store.clone();
  859                    let request_id = request_id.clone();
  860                    let mut cx = cx.clone();
  861                    async move {
  862                        lsp_store
  863                            .update(&mut cx, |lsp_store, cx| {
  864                                let request_id =
  865                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
  866                                cx.emit(LspStoreEvent::RefreshInlayHints {
  867                                    server_id,
  868                                    request_id,
  869                                });
  870                                lsp_store
  871                                    .downstream_client
  872                                    .as_ref()
  873                                    .map(|(client, project_id)| {
  874                                        client.send(proto::RefreshInlayHints {
  875                                            project_id: *project_id,
  876                                            server_id: server_id.to_proto(),
  877                                            request_id: request_id.map(|id| id as u64),
  878                                        })
  879                                    })
  880                            })?
  881                            .transpose()?;
  882                        Ok(())
  883                    }
  884                }
  885            })
  886            .detach();
  887
  888        language_server
  889            .on_request::<lsp::request::CodeLensRefresh, _, _>({
  890                let this = lsp_store.clone();
  891                move |(), cx| {
  892                    let this = this.clone();
  893                    let mut cx = cx.clone();
  894                    async move {
  895                        this.update(&mut cx, |this, cx| {
  896                            cx.emit(LspStoreEvent::RefreshCodeLens);
  897                            this.downstream_client.as_ref().map(|(client, project_id)| {
  898                                client.send(proto::RefreshCodeLens {
  899                                    project_id: *project_id,
  900                                })
  901                            })
  902                        })?
  903                        .transpose()?;
  904                        Ok(())
  905                    }
  906                }
  907            })
  908            .detach();
  909
  910        language_server
  911            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
  912                let this = lsp_store.clone();
  913                move |(), cx| {
  914                    let this = this.clone();
  915                    let mut cx = cx.clone();
  916                    async move {
  917                        this.update(&mut cx, |lsp_store, _| {
  918                            lsp_store.pull_workspace_diagnostics(server_id);
  919                            lsp_store
  920                                .downstream_client
  921                                .as_ref()
  922                                .map(|(client, project_id)| {
  923                                    client.send(proto::PullWorkspaceDiagnostics {
  924                                        project_id: *project_id,
  925                                        server_id: server_id.to_proto(),
  926                                    })
  927                                })
  928                        })?
  929                        .transpose()?;
  930                        Ok(())
  931                    }
  932                }
  933            })
  934            .detach();
  935
  936        language_server
  937            .on_request::<lsp::request::ShowMessageRequest, _, _>({
  938                let this = lsp_store.clone();
  939                let name = name.to_string();
  940                move |params, cx| {
  941                    let this = this.clone();
  942                    let name = name.to_string();
  943                    let mut cx = cx.clone();
  944                    async move {
  945                        let actions = params.actions.unwrap_or_default();
  946                        let (tx, rx) = smol::channel::bounded(1);
  947                        let request = LanguageServerPromptRequest {
  948                            level: match params.typ {
  949                                lsp::MessageType::ERROR => PromptLevel::Critical,
  950                                lsp::MessageType::WARNING => PromptLevel::Warning,
  951                                _ => PromptLevel::Info,
  952                            },
  953                            message: params.message,
  954                            actions,
  955                            response_channel: tx,
  956                            lsp_name: name.clone(),
  957                        };
  958
  959                        let did_update = this
  960                            .update(&mut cx, |_, cx| {
  961                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
  962                            })
  963                            .is_ok();
  964                        if did_update {
  965                            let response = rx.recv().await.ok();
  966                            Ok(response)
  967                        } else {
  968                            Ok(None)
  969                        }
  970                    }
  971                }
  972            })
  973            .detach();
  974        language_server
  975            .on_notification::<lsp::notification::ShowMessage, _>({
  976                let this = lsp_store.clone();
  977                let name = name.to_string();
  978                move |params, cx| {
  979                    let this = this.clone();
  980                    let name = name.to_string();
  981                    let mut cx = cx.clone();
  982
  983                    let (tx, _) = smol::channel::bounded(1);
  984                    let request = LanguageServerPromptRequest {
  985                        level: match params.typ {
  986                            lsp::MessageType::ERROR => PromptLevel::Critical,
  987                            lsp::MessageType::WARNING => PromptLevel::Warning,
  988                            _ => PromptLevel::Info,
  989                        },
  990                        message: params.message,
  991                        actions: vec![],
  992                        response_channel: tx,
  993                        lsp_name: name,
  994                    };
  995
  996                    let _ = this.update(&mut cx, |_, cx| {
  997                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
  998                    });
  999                }
 1000            })
 1001            .detach();
 1002
 1003        let disk_based_diagnostics_progress_token =
 1004            adapter.disk_based_diagnostics_progress_token.clone();
 1005
 1006        language_server
 1007            .on_notification::<lsp::notification::Progress, _>({
 1008                let this = lsp_store.clone();
 1009                move |params, cx| {
 1010                    if let Some(this) = this.upgrade() {
 1011                        this.update(cx, |this, cx| {
 1012                            this.on_lsp_progress(
 1013                                params,
 1014                                server_id,
 1015                                disk_based_diagnostics_progress_token.clone(),
 1016                                cx,
 1017                            );
 1018                        })
 1019                        .ok();
 1020                    }
 1021                }
 1022            })
 1023            .detach();
 1024
 1025        language_server
 1026            .on_notification::<lsp::notification::LogMessage, _>({
 1027                let this = lsp_store.clone();
 1028                move |params, cx| {
 1029                    if let Some(this) = this.upgrade() {
 1030                        this.update(cx, |_, cx| {
 1031                            cx.emit(LspStoreEvent::LanguageServerLog(
 1032                                server_id,
 1033                                LanguageServerLogType::Log(params.typ),
 1034                                params.message,
 1035                            ));
 1036                        })
 1037                        .ok();
 1038                    }
 1039                }
 1040            })
 1041            .detach();
 1042
 1043        language_server
 1044            .on_notification::<lsp::notification::LogTrace, _>({
 1045                let this = lsp_store.clone();
 1046                move |params, cx| {
 1047                    let mut cx = cx.clone();
 1048                    if let Some(this) = this.upgrade() {
 1049                        this.update(&mut cx, |_, cx| {
 1050                            cx.emit(LspStoreEvent::LanguageServerLog(
 1051                                server_id,
 1052                                LanguageServerLogType::Trace {
 1053                                    verbose_info: params.verbose,
 1054                                },
 1055                                params.message,
 1056                            ));
 1057                        })
 1058                        .ok();
 1059                    }
 1060                }
 1061            })
 1062            .detach();
 1063
 1064        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1065        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1066        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1067        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1068    }
 1069
 1070    fn shutdown_language_servers_on_quit(
 1071        &mut self,
 1072        _: &mut Context<LspStore>,
 1073    ) -> impl Future<Output = ()> + use<> {
 1074        let shutdown_futures = self
 1075            .language_servers
 1076            .drain()
 1077            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1078            .collect::<Vec<_>>();
 1079
 1080        async move {
 1081            join_all(shutdown_futures).await;
 1082        }
 1083    }
 1084
 1085    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1086        match server_state {
 1087            LanguageServerState::Running { server, .. } => {
 1088                if let Some(shutdown) = server.shutdown() {
 1089                    shutdown.await;
 1090                }
 1091            }
 1092            LanguageServerState::Starting { startup, .. } => {
 1093                if let Some(server) = startup.await
 1094                    && let Some(shutdown) = server.shutdown()
 1095                {
 1096                    shutdown.await;
 1097                }
 1098            }
 1099        }
 1100        Ok(())
 1101    }
 1102
 1103    fn language_servers_for_worktree(
 1104        &self,
 1105        worktree_id: WorktreeId,
 1106    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1107        self.language_server_ids
 1108            .iter()
 1109            .filter_map(move |(seed, state)| {
 1110                if seed.worktree_id != worktree_id {
 1111                    return None;
 1112                }
 1113
 1114                if let Some(LanguageServerState::Running { server, .. }) =
 1115                    self.language_servers.get(&state.id)
 1116                {
 1117                    Some(server)
 1118                } else {
 1119                    None
 1120                }
 1121            })
 1122    }
 1123
 1124    fn language_server_ids_for_project_path(
 1125        &self,
 1126        project_path: ProjectPath,
 1127        language: &Language,
 1128        cx: &mut App,
 1129    ) -> Vec<LanguageServerId> {
 1130        let Some(worktree) = self
 1131            .worktree_store
 1132            .read(cx)
 1133            .worktree_for_id(project_path.worktree_id, cx)
 1134        else {
 1135            return Vec::new();
 1136        };
 1137        let delegate: Arc<dyn ManifestDelegate> =
 1138            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1139
 1140        self.lsp_tree
 1141            .get(
 1142                project_path,
 1143                language.name(),
 1144                language.manifest(),
 1145                &delegate,
 1146                cx,
 1147            )
 1148            .collect::<Vec<_>>()
 1149    }
 1150
 1151    fn language_server_ids_for_buffer(
 1152        &self,
 1153        buffer: &Buffer,
 1154        cx: &mut App,
 1155    ) -> Vec<LanguageServerId> {
 1156        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1157            let worktree_id = file.worktree_id(cx);
 1158
 1159            let path: Arc<RelPath> = file
 1160                .path()
 1161                .parent()
 1162                .map(Arc::from)
 1163                .unwrap_or_else(|| file.path().clone());
 1164            let worktree_path = ProjectPath { worktree_id, path };
 1165            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1166        } else {
 1167            Vec::new()
 1168        }
 1169    }
 1170
 1171    fn language_servers_for_buffer<'a>(
 1172        &'a self,
 1173        buffer: &'a Buffer,
 1174        cx: &'a mut App,
 1175    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1176        self.language_server_ids_for_buffer(buffer, cx)
 1177            .into_iter()
 1178            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1179                LanguageServerState::Running {
 1180                    adapter, server, ..
 1181                } => Some((adapter, server)),
 1182                _ => None,
 1183            })
 1184    }
 1185
 1186    async fn execute_code_action_kind_locally(
 1187        lsp_store: WeakEntity<LspStore>,
 1188        mut buffers: Vec<Entity<Buffer>>,
 1189        kind: CodeActionKind,
 1190        push_to_history: bool,
 1191        cx: &mut AsyncApp,
 1192    ) -> anyhow::Result<ProjectTransaction> {
 1193        // Do not allow multiple concurrent code actions requests for the
 1194        // same buffer.
 1195        lsp_store.update(cx, |this, cx| {
 1196            let this = this.as_local_mut().unwrap();
 1197            buffers.retain(|buffer| {
 1198                this.buffers_being_formatted
 1199                    .insert(buffer.read(cx).remote_id())
 1200            });
 1201        })?;
 1202        let _cleanup = defer({
 1203            let this = lsp_store.clone();
 1204            let mut cx = cx.clone();
 1205            let buffers = &buffers;
 1206            move || {
 1207                this.update(&mut cx, |this, cx| {
 1208                    let this = this.as_local_mut().unwrap();
 1209                    for buffer in buffers {
 1210                        this.buffers_being_formatted
 1211                            .remove(&buffer.read(cx).remote_id());
 1212                    }
 1213                })
 1214                .ok();
 1215            }
 1216        });
 1217        let mut project_transaction = ProjectTransaction::default();
 1218
 1219        for buffer in &buffers {
 1220            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1221                buffer.update(cx, |buffer, cx| {
 1222                    lsp_store
 1223                        .as_local()
 1224                        .unwrap()
 1225                        .language_servers_for_buffer(buffer, cx)
 1226                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1227                        .collect::<Vec<_>>()
 1228                })
 1229            })?;
 1230            for (_, language_server) in adapters_and_servers.iter() {
 1231                let actions = Self::get_server_code_actions_from_action_kinds(
 1232                    &lsp_store,
 1233                    language_server.server_id(),
 1234                    vec![kind.clone()],
 1235                    buffer,
 1236                    cx,
 1237                )
 1238                .await?;
 1239                Self::execute_code_actions_on_server(
 1240                    &lsp_store,
 1241                    language_server,
 1242                    actions,
 1243                    push_to_history,
 1244                    &mut project_transaction,
 1245                    cx,
 1246                )
 1247                .await?;
 1248            }
 1249        }
 1250        Ok(project_transaction)
 1251    }
 1252
 1253    async fn format_locally(
 1254        lsp_store: WeakEntity<LspStore>,
 1255        mut buffers: Vec<FormattableBuffer>,
 1256        push_to_history: bool,
 1257        trigger: FormatTrigger,
 1258        logger: zlog::Logger,
 1259        cx: &mut AsyncApp,
 1260    ) -> anyhow::Result<ProjectTransaction> {
 1261        // Do not allow multiple concurrent formatting requests for the
 1262        // same buffer.
 1263        lsp_store.update(cx, |this, cx| {
 1264            let this = this.as_local_mut().unwrap();
 1265            buffers.retain(|buffer| {
 1266                this.buffers_being_formatted
 1267                    .insert(buffer.handle.read(cx).remote_id())
 1268            });
 1269        })?;
 1270
 1271        let _cleanup = defer({
 1272            let this = lsp_store.clone();
 1273            let mut cx = cx.clone();
 1274            let buffers = &buffers;
 1275            move || {
 1276                this.update(&mut cx, |this, cx| {
 1277                    let this = this.as_local_mut().unwrap();
 1278                    for buffer in buffers {
 1279                        this.buffers_being_formatted
 1280                            .remove(&buffer.handle.read(cx).remote_id());
 1281                    }
 1282                })
 1283                .ok();
 1284            }
 1285        });
 1286
 1287        let mut project_transaction = ProjectTransaction::default();
 1288
 1289        for buffer in &buffers {
 1290            zlog::debug!(
 1291                logger =>
 1292                "formatting buffer '{:?}'",
 1293                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1294            );
 1295            // Create an empty transaction to hold all of the formatting edits.
 1296            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1297                // ensure no transactions created while formatting are
 1298                // grouped with the previous transaction in the history
 1299                // based on the transaction group interval
 1300                buffer.finalize_last_transaction();
 1301                buffer
 1302                    .start_transaction()
 1303                    .context("transaction already open")?;
 1304                buffer.end_transaction(cx);
 1305                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1306                buffer.finalize_last_transaction();
 1307                anyhow::Ok(transaction_id)
 1308            })??;
 1309
 1310            let result = Self::format_buffer_locally(
 1311                lsp_store.clone(),
 1312                buffer,
 1313                formatting_transaction_id,
 1314                trigger,
 1315                logger,
 1316                cx,
 1317            )
 1318            .await;
 1319
 1320            buffer.handle.update(cx, |buffer, cx| {
 1321                let Some(formatting_transaction) =
 1322                    buffer.get_transaction(formatting_transaction_id).cloned()
 1323                else {
 1324                    zlog::warn!(logger => "no formatting transaction");
 1325                    return;
 1326                };
 1327                if formatting_transaction.edit_ids.is_empty() {
 1328                    zlog::debug!(logger => "no changes made while formatting");
 1329                    buffer.forget_transaction(formatting_transaction_id);
 1330                    return;
 1331                }
 1332                if !push_to_history {
 1333                    zlog::trace!(logger => "forgetting format transaction");
 1334                    buffer.forget_transaction(formatting_transaction.id);
 1335                }
 1336                project_transaction
 1337                    .0
 1338                    .insert(cx.entity(), formatting_transaction);
 1339            })?;
 1340
 1341            result?;
 1342        }
 1343
 1344        Ok(project_transaction)
 1345    }
 1346
 1347    async fn format_buffer_locally(
 1348        lsp_store: WeakEntity<LspStore>,
 1349        buffer: &FormattableBuffer,
 1350        formatting_transaction_id: clock::Lamport,
 1351        trigger: FormatTrigger,
 1352        logger: zlog::Logger,
 1353        cx: &mut AsyncApp,
 1354    ) -> Result<()> {
 1355        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1356            buffer.handle.update(cx, |buffer, cx| {
 1357                let adapters_and_servers = lsp_store
 1358                    .as_local()
 1359                    .unwrap()
 1360                    .language_servers_for_buffer(buffer, cx)
 1361                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1362                    .collect::<Vec<_>>();
 1363                let settings =
 1364                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1365                        .into_owned();
 1366                (adapters_and_servers, settings)
 1367            })
 1368        })?;
 1369
 1370        /// Apply edits to the buffer that will become part of the formatting transaction.
 1371        /// Fails if the buffer has been edited since the start of that transaction.
 1372        fn extend_formatting_transaction(
 1373            buffer: &FormattableBuffer,
 1374            formatting_transaction_id: text::TransactionId,
 1375            cx: &mut AsyncApp,
 1376            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1377        ) -> anyhow::Result<()> {
 1378            buffer.handle.update(cx, |buffer, cx| {
 1379                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1380                if last_transaction_id != Some(formatting_transaction_id) {
 1381                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1382                }
 1383                buffer.start_transaction();
 1384                operation(buffer, cx);
 1385                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1386                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1387                }
 1388                Ok(())
 1389            })?
 1390        }
 1391
 1392        // handle whitespace formatting
 1393        if settings.remove_trailing_whitespace_on_save {
 1394            zlog::trace!(logger => "removing trailing whitespace");
 1395            let diff = buffer
 1396                .handle
 1397                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))?
 1398                .await;
 1399            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1400                buffer.apply_diff(diff, cx);
 1401            })?;
 1402        }
 1403
 1404        if settings.ensure_final_newline_on_save {
 1405            zlog::trace!(logger => "ensuring final newline");
 1406            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1407                buffer.ensure_final_newline(cx);
 1408            })?;
 1409        }
 1410
 1411        // Formatter for `code_actions_on_format` that runs before
 1412        // the rest of the formatters
 1413        let mut code_actions_on_format_formatters = None;
 1414        let should_run_code_actions_on_format = !matches!(
 1415            (trigger, &settings.format_on_save),
 1416            (FormatTrigger::Save, &FormatOnSave::Off)
 1417        );
 1418        if should_run_code_actions_on_format {
 1419            let have_code_actions_to_run_on_format = settings
 1420                .code_actions_on_format
 1421                .values()
 1422                .any(|enabled| *enabled);
 1423            if have_code_actions_to_run_on_format {
 1424                zlog::trace!(logger => "going to run code actions on format");
 1425                code_actions_on_format_formatters = Some(
 1426                    settings
 1427                        .code_actions_on_format
 1428                        .iter()
 1429                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1430                        .cloned()
 1431                        .map(Formatter::CodeAction)
 1432                        .collect::<Vec<_>>(),
 1433                );
 1434            }
 1435        }
 1436
 1437        let formatters = match (trigger, &settings.format_on_save) {
 1438            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1439            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1440                settings.formatter.as_ref()
 1441            }
 1442        };
 1443
 1444        let formatters = code_actions_on_format_formatters
 1445            .iter()
 1446            .flatten()
 1447            .chain(formatters);
 1448
 1449        for formatter in formatters {
 1450            let formatter = if formatter == &Formatter::Auto {
 1451                if settings.prettier.allowed {
 1452                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1453                    &Formatter::Prettier
 1454                } else {
 1455                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1456                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1457                }
 1458            } else {
 1459                formatter
 1460            };
 1461            match formatter {
 1462                Formatter::Auto => unreachable!("Auto resolved above"),
 1463                Formatter::Prettier => {
 1464                    let logger = zlog::scoped!(logger => "prettier");
 1465                    zlog::trace!(logger => "formatting");
 1466                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1467
 1468                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1469                        lsp_store.prettier_store().unwrap().downgrade()
 1470                    })?;
 1471                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1472                        .await
 1473                        .transpose()?;
 1474                    let Some(diff) = diff else {
 1475                        zlog::trace!(logger => "No changes");
 1476                        continue;
 1477                    };
 1478
 1479                    extend_formatting_transaction(
 1480                        buffer,
 1481                        formatting_transaction_id,
 1482                        cx,
 1483                        |buffer, cx| {
 1484                            buffer.apply_diff(diff, cx);
 1485                        },
 1486                    )?;
 1487                }
 1488                Formatter::External { command, arguments } => {
 1489                    let logger = zlog::scoped!(logger => "command");
 1490                    zlog::trace!(logger => "formatting");
 1491                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1492
 1493                    let diff = Self::format_via_external_command(
 1494                        buffer,
 1495                        command.as_ref(),
 1496                        arguments.as_deref(),
 1497                        cx,
 1498                    )
 1499                    .await
 1500                    .with_context(|| {
 1501                        format!("Failed to format buffer via external command: {}", command)
 1502                    })?;
 1503                    let Some(diff) = diff else {
 1504                        zlog::trace!(logger => "No changes");
 1505                        continue;
 1506                    };
 1507
 1508                    extend_formatting_transaction(
 1509                        buffer,
 1510                        formatting_transaction_id,
 1511                        cx,
 1512                        |buffer, cx| {
 1513                            buffer.apply_diff(diff, cx);
 1514                        },
 1515                    )?;
 1516                }
 1517                Formatter::LanguageServer(specifier) => {
 1518                    let logger = zlog::scoped!(logger => "language-server");
 1519                    zlog::trace!(logger => "formatting");
 1520                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1521
 1522                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1523                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1524                        continue;
 1525                    };
 1526
 1527                    let language_server = match specifier {
 1528                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1529                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1530                                if adapter.name.0.as_ref() == name {
 1531                                    Some(server.clone())
 1532                                } else {
 1533                                    None
 1534                                }
 1535                            })
 1536                        }
 1537                        settings::LanguageServerFormatterSpecifier::Current => {
 1538                            adapters_and_servers.first().map(|e| e.1.clone())
 1539                        }
 1540                    };
 1541
 1542                    let Some(language_server) = language_server else {
 1543                        log::debug!(
 1544                            "No language server found to format buffer '{:?}'. Skipping",
 1545                            buffer_path_abs.as_path().to_string_lossy()
 1546                        );
 1547                        continue;
 1548                    };
 1549
 1550                    zlog::trace!(
 1551                        logger =>
 1552                        "Formatting buffer '{:?}' using language server '{:?}'",
 1553                        buffer_path_abs.as_path().to_string_lossy(),
 1554                        language_server.name()
 1555                    );
 1556
 1557                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1558                        zlog::trace!(logger => "formatting ranges");
 1559                        Self::format_ranges_via_lsp(
 1560                            &lsp_store,
 1561                            &buffer.handle,
 1562                            ranges,
 1563                            buffer_path_abs,
 1564                            &language_server,
 1565                            &settings,
 1566                            cx,
 1567                        )
 1568                        .await
 1569                        .context("Failed to format ranges via language server")?
 1570                    } else {
 1571                        zlog::trace!(logger => "formatting full");
 1572                        Self::format_via_lsp(
 1573                            &lsp_store,
 1574                            &buffer.handle,
 1575                            buffer_path_abs,
 1576                            &language_server,
 1577                            &settings,
 1578                            cx,
 1579                        )
 1580                        .await
 1581                        .context("failed to format via language server")?
 1582                    };
 1583
 1584                    if edits.is_empty() {
 1585                        zlog::trace!(logger => "No changes");
 1586                        continue;
 1587                    }
 1588                    extend_formatting_transaction(
 1589                        buffer,
 1590                        formatting_transaction_id,
 1591                        cx,
 1592                        |buffer, cx| {
 1593                            buffer.edit(edits, None, cx);
 1594                        },
 1595                    )?;
 1596                }
 1597                Formatter::CodeAction(code_action_name) => {
 1598                    let logger = zlog::scoped!(logger => "code-actions");
 1599                    zlog::trace!(logger => "formatting");
 1600                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1601
 1602                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1603                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1604                        continue;
 1605                    };
 1606
 1607                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1608                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1609
 1610                    let mut actions_and_servers = Vec::new();
 1611
 1612                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1613                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1614                            &lsp_store,
 1615                            language_server.server_id(),
 1616                            vec![code_action_kind.clone()],
 1617                            &buffer.handle,
 1618                            cx,
 1619                        )
 1620                        .await
 1621                        .with_context(|| {
 1622                            format!(
 1623                                "Failed to resolve code action {:?} with language server {}",
 1624                                code_action_kind,
 1625                                language_server.name()
 1626                            )
 1627                        });
 1628                        let Ok(actions) = actions_result else {
 1629                            // note: it may be better to set result to the error and break formatters here
 1630                            // but for now we try to execute the actions that we can resolve and skip the rest
 1631                            zlog::error!(
 1632                                logger =>
 1633                                "Failed to resolve code action {:?} with language server {}",
 1634                                code_action_kind,
 1635                                language_server.name()
 1636                            );
 1637                            continue;
 1638                        };
 1639                        for action in actions {
 1640                            actions_and_servers.push((action, index));
 1641                        }
 1642                    }
 1643
 1644                    if actions_and_servers.is_empty() {
 1645                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1646                        continue;
 1647                    }
 1648
 1649                    'actions: for (mut action, server_index) in actions_and_servers {
 1650                        let server = &adapters_and_servers[server_index].1;
 1651
 1652                        let describe_code_action = |action: &CodeAction| {
 1653                            format!(
 1654                                "code action '{}' with title \"{}\" on server {}",
 1655                                action
 1656                                    .lsp_action
 1657                                    .action_kind()
 1658                                    .unwrap_or("unknown".into())
 1659                                    .as_str(),
 1660                                action.lsp_action.title(),
 1661                                server.name(),
 1662                            )
 1663                        };
 1664
 1665                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1666
 1667                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1668                            zlog::error!(
 1669                                logger =>
 1670                                "Failed to resolve {}. Error: {}",
 1671                                describe_code_action(&action),
 1672                                err
 1673                            );
 1674                            continue;
 1675                        }
 1676
 1677                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1678                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1679                            // but filters out and logs warnings for code actions that require unreasonably
 1680                            // difficult handling on our part, such as:
 1681                            // - applying edits that call commands
 1682                            //   which can result in arbitrary workspace edits being sent from the server that
 1683                            //   have no way of being tied back to the command that initiated them (i.e. we
 1684                            //   can't know which edits are part of the format request, or if the server is done sending
 1685                            //   actions in response to the command)
 1686                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1687                            //   as we then would need to handle such changes correctly in the local history as well
 1688                            //   as the remote history through the ProjectTransaction
 1689                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1690                            // Supporting these actions is not impossible, but not supported as of yet.
 1691                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1692                                zlog::trace!(
 1693                                    logger =>
 1694                                    "No changes for code action. Skipping {}",
 1695                                    describe_code_action(&action),
 1696                                );
 1697                                continue;
 1698                            }
 1699
 1700                            let mut operations = Vec::new();
 1701                            if let Some(document_changes) = edit.document_changes {
 1702                                match document_changes {
 1703                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1704                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1705                                    ),
 1706                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1707                                }
 1708                            } else if let Some(changes) = edit.changes {
 1709                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1710                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1711                                        text_document:
 1712                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1713                                                uri,
 1714                                                version: None,
 1715                                            },
 1716                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1717                                    })
 1718                                }));
 1719                            }
 1720
 1721                            let mut edits = Vec::with_capacity(operations.len());
 1722
 1723                            if operations.is_empty() {
 1724                                zlog::trace!(
 1725                                    logger =>
 1726                                    "No changes for code action. Skipping {}",
 1727                                    describe_code_action(&action),
 1728                                );
 1729                                continue;
 1730                            }
 1731                            for operation in operations {
 1732                                let op = match operation {
 1733                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1734                                    lsp::DocumentChangeOperation::Op(_) => {
 1735                                        zlog::warn!(
 1736                                            logger =>
 1737                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1738                                            describe_code_action(&action),
 1739                                        );
 1740                                        continue 'actions;
 1741                                    }
 1742                                };
 1743                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1744                                    zlog::warn!(
 1745                                        logger =>
 1746                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1747                                        &op.text_document.uri,
 1748                                        describe_code_action(&action),
 1749                                    );
 1750                                    continue 'actions;
 1751                                };
 1752                                if &file_path != buffer_path_abs {
 1753                                    zlog::warn!(
 1754                                        logger =>
 1755                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1756                                        file_path,
 1757                                        buffer_path_abs,
 1758                                        describe_code_action(&action),
 1759                                    );
 1760                                    continue 'actions;
 1761                                }
 1762
 1763                                let mut lsp_edits = Vec::new();
 1764                                for edit in op.edits {
 1765                                    match edit {
 1766                                        Edit::Plain(edit) => {
 1767                                            if !lsp_edits.contains(&edit) {
 1768                                                lsp_edits.push(edit);
 1769                                            }
 1770                                        }
 1771                                        Edit::Annotated(edit) => {
 1772                                            if !lsp_edits.contains(&edit.text_edit) {
 1773                                                lsp_edits.push(edit.text_edit);
 1774                                            }
 1775                                        }
 1776                                        Edit::Snippet(_) => {
 1777                                            zlog::warn!(
 1778                                                logger =>
 1779                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1780                                                describe_code_action(&action),
 1781                                            );
 1782                                            continue 'actions;
 1783                                        }
 1784                                    }
 1785                                }
 1786                                let edits_result = lsp_store
 1787                                    .update(cx, |lsp_store, cx| {
 1788                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1789                                            &buffer.handle,
 1790                                            lsp_edits,
 1791                                            server.server_id(),
 1792                                            op.text_document.version,
 1793                                            cx,
 1794                                        )
 1795                                    })?
 1796                                    .await;
 1797                                let Ok(resolved_edits) = edits_result else {
 1798                                    zlog::warn!(
 1799                                        logger =>
 1800                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1801                                        buffer_path_abs.as_path(),
 1802                                        describe_code_action(&action),
 1803                                    );
 1804                                    continue 'actions;
 1805                                };
 1806                                edits.extend(resolved_edits);
 1807                            }
 1808
 1809                            if edits.is_empty() {
 1810                                zlog::warn!(logger => "No edits resolved from LSP");
 1811                                continue;
 1812                            }
 1813
 1814                            extend_formatting_transaction(
 1815                                buffer,
 1816                                formatting_transaction_id,
 1817                                cx,
 1818                                |buffer, cx| {
 1819                                    zlog::info!(
 1820                                        "Applying edits {edits:?}. Content: {:?}",
 1821                                        buffer.text()
 1822                                    );
 1823                                    buffer.edit(edits, None, cx);
 1824                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 1825                                },
 1826                            )?;
 1827                        }
 1828
 1829                        if let Some(command) = action.lsp_action.command() {
 1830                            zlog::warn!(
 1831                                logger =>
 1832                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1833                                &command.command,
 1834                            );
 1835
 1836                            // bail early if command is invalid
 1837                            let server_capabilities = server.capabilities();
 1838                            let available_commands = server_capabilities
 1839                                .execute_command_provider
 1840                                .as_ref()
 1841                                .map(|options| options.commands.as_slice())
 1842                                .unwrap_or_default();
 1843                            if !available_commands.contains(&command.command) {
 1844                                zlog::warn!(
 1845                                    logger =>
 1846                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1847                                    command.command,
 1848                                    server.name(),
 1849                                );
 1850                                continue;
 1851                            }
 1852
 1853                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 1854                            extend_formatting_transaction(
 1855                                buffer,
 1856                                formatting_transaction_id,
 1857                                cx,
 1858                                |_, _| {},
 1859                            )?;
 1860                            zlog::info!(logger => "Executing command {}", &command.command);
 1861
 1862                            lsp_store.update(cx, |this, _| {
 1863                                this.as_local_mut()
 1864                                    .unwrap()
 1865                                    .last_workspace_edits_by_language_server
 1866                                    .remove(&server.server_id());
 1867                            })?;
 1868
 1869                            let execute_command_result = server
 1870                                .request::<lsp::request::ExecuteCommand>(
 1871                                    lsp::ExecuteCommandParams {
 1872                                        command: command.command.clone(),
 1873                                        arguments: command.arguments.clone().unwrap_or_default(),
 1874                                        ..Default::default()
 1875                                    },
 1876                                )
 1877                                .await
 1878                                .into_response();
 1879
 1880                            if execute_command_result.is_err() {
 1881                                zlog::error!(
 1882                                    logger =>
 1883                                    "Failed to execute command '{}' as part of {}",
 1884                                    &command.command,
 1885                                    describe_code_action(&action),
 1886                                );
 1887                                continue 'actions;
 1888                            }
 1889
 1890                            let mut project_transaction_command =
 1891                                lsp_store.update(cx, |this, _| {
 1892                                    this.as_local_mut()
 1893                                        .unwrap()
 1894                                        .last_workspace_edits_by_language_server
 1895                                        .remove(&server.server_id())
 1896                                        .unwrap_or_default()
 1897                                })?;
 1898
 1899                            if let Some(transaction) =
 1900                                project_transaction_command.0.remove(&buffer.handle)
 1901                            {
 1902                                zlog::trace!(
 1903                                    logger =>
 1904                                    "Successfully captured {} edits that resulted from command {}",
 1905                                    transaction.edit_ids.len(),
 1906                                    &command.command,
 1907                                );
 1908                                let transaction_id_project_transaction = transaction.id;
 1909                                buffer.handle.update(cx, |buffer, _| {
 1910                                    // it may have been removed from history if push_to_history was
 1911                                    // false in deserialize_workspace_edit. If so push it so we
 1912                                    // can merge it with the format transaction
 1913                                    // and pop the combined transaction off the history stack
 1914                                    // later if push_to_history is false
 1915                                    if buffer.get_transaction(transaction.id).is_none() {
 1916                                        buffer.push_transaction(transaction, Instant::now());
 1917                                    }
 1918                                    buffer.merge_transactions(
 1919                                        transaction_id_project_transaction,
 1920                                        formatting_transaction_id,
 1921                                    );
 1922                                })?;
 1923                            }
 1924
 1925                            if !project_transaction_command.0.is_empty() {
 1926                                let mut extra_buffers = String::new();
 1927                                for buffer in project_transaction_command.0.keys() {
 1928                                    buffer
 1929                                        .read_with(cx, |b, cx| {
 1930                                            if let Some(path) = b.project_path(cx) {
 1931                                                if !extra_buffers.is_empty() {
 1932                                                    extra_buffers.push_str(", ");
 1933                                                }
 1934                                                extra_buffers.push_str(path.path.as_unix_str());
 1935                                            }
 1936                                        })
 1937                                        .ok();
 1938                                }
 1939                                zlog::warn!(
 1940                                    logger =>
 1941                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 1942                                    &command.command,
 1943                                    extra_buffers,
 1944                                );
 1945                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 1946                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 1947                                // add it so it's included, and merge it into the format transaction when its created later
 1948                            }
 1949                        }
 1950                    }
 1951                }
 1952            }
 1953        }
 1954
 1955        Ok(())
 1956    }
 1957
 1958    pub async fn format_ranges_via_lsp(
 1959        this: &WeakEntity<LspStore>,
 1960        buffer_handle: &Entity<Buffer>,
 1961        ranges: &[Range<Anchor>],
 1962        abs_path: &Path,
 1963        language_server: &Arc<LanguageServer>,
 1964        settings: &LanguageSettings,
 1965        cx: &mut AsyncApp,
 1966    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 1967        let capabilities = &language_server.capabilities();
 1968        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 1969        if range_formatting_provider == Some(&OneOf::Left(false)) {
 1970            anyhow::bail!(
 1971                "{} language server does not support range formatting",
 1972                language_server.name()
 1973            );
 1974        }
 1975
 1976        let uri = file_path_to_lsp_url(abs_path)?;
 1977        let text_document = lsp::TextDocumentIdentifier::new(uri);
 1978
 1979        let lsp_edits = {
 1980            let mut lsp_ranges = Vec::new();
 1981            this.update(cx, |_this, cx| {
 1982                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 1983                // not have been sent to the language server. This seems like a fairly systemic
 1984                // issue, though, the resolution probably is not specific to formatting.
 1985                //
 1986                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 1987                // LSP.
 1988                let snapshot = buffer_handle.read(cx).snapshot();
 1989                for range in ranges {
 1990                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 1991                }
 1992                anyhow::Ok(())
 1993            })??;
 1994
 1995            let mut edits = None;
 1996            for range in lsp_ranges {
 1997                if let Some(mut edit) = language_server
 1998                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 1999                        text_document: text_document.clone(),
 2000                        range,
 2001                        options: lsp_command::lsp_formatting_options(settings),
 2002                        work_done_progress_params: Default::default(),
 2003                    })
 2004                    .await
 2005                    .into_response()?
 2006                {
 2007                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2008                }
 2009            }
 2010            edits
 2011        };
 2012
 2013        if let Some(lsp_edits) = lsp_edits {
 2014            this.update(cx, |this, cx| {
 2015                this.as_local_mut().unwrap().edits_from_lsp(
 2016                    buffer_handle,
 2017                    lsp_edits,
 2018                    language_server.server_id(),
 2019                    None,
 2020                    cx,
 2021                )
 2022            })?
 2023            .await
 2024        } else {
 2025            Ok(Vec::with_capacity(0))
 2026        }
 2027    }
 2028
 2029    async fn format_via_lsp(
 2030        this: &WeakEntity<LspStore>,
 2031        buffer: &Entity<Buffer>,
 2032        abs_path: &Path,
 2033        language_server: &Arc<LanguageServer>,
 2034        settings: &LanguageSettings,
 2035        cx: &mut AsyncApp,
 2036    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2037        let logger = zlog::scoped!("lsp_format");
 2038        zlog::debug!(logger => "Formatting via LSP");
 2039
 2040        let uri = file_path_to_lsp_url(abs_path)?;
 2041        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2042        let capabilities = &language_server.capabilities();
 2043
 2044        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2045        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2046
 2047        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2048            let _timer = zlog::time!(logger => "format-full");
 2049            language_server
 2050                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 2051                    text_document,
 2052                    options: lsp_command::lsp_formatting_options(settings),
 2053                    work_done_progress_params: Default::default(),
 2054                })
 2055                .await
 2056                .into_response()?
 2057        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2058            let _timer = zlog::time!(logger => "format-range");
 2059            let buffer_start = lsp::Position::new(0, 0);
 2060            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 2061            language_server
 2062                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2063                    text_document: text_document.clone(),
 2064                    range: lsp::Range::new(buffer_start, buffer_end),
 2065                    options: lsp_command::lsp_formatting_options(settings),
 2066                    work_done_progress_params: Default::default(),
 2067                })
 2068                .await
 2069                .into_response()?
 2070        } else {
 2071            None
 2072        };
 2073
 2074        if let Some(lsp_edits) = lsp_edits {
 2075            this.update(cx, |this, cx| {
 2076                this.as_local_mut().unwrap().edits_from_lsp(
 2077                    buffer,
 2078                    lsp_edits,
 2079                    language_server.server_id(),
 2080                    None,
 2081                    cx,
 2082                )
 2083            })?
 2084            .await
 2085        } else {
 2086            Ok(Vec::with_capacity(0))
 2087        }
 2088    }
 2089
 2090    async fn format_via_external_command(
 2091        buffer: &FormattableBuffer,
 2092        command: &str,
 2093        arguments: Option<&[String]>,
 2094        cx: &mut AsyncApp,
 2095    ) -> Result<Option<Diff>> {
 2096        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2097            let file = File::from_dyn(buffer.file())?;
 2098            let worktree = file.worktree.read(cx);
 2099            let mut worktree_path = worktree.abs_path().to_path_buf();
 2100            if worktree.root_entry()?.is_file() {
 2101                worktree_path.pop();
 2102            }
 2103            Some(worktree_path)
 2104        })?;
 2105
 2106        let mut child = util::command::new_smol_command(command);
 2107
 2108        if let Some(buffer_env) = buffer.env.as_ref() {
 2109            child.envs(buffer_env);
 2110        }
 2111
 2112        if let Some(working_dir_path) = working_dir_path {
 2113            child.current_dir(working_dir_path);
 2114        }
 2115
 2116        if let Some(arguments) = arguments {
 2117            child.args(arguments.iter().map(|arg| {
 2118                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2119                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2120                } else {
 2121                    arg.replace("{buffer_path}", "Untitled")
 2122                }
 2123            }));
 2124        }
 2125
 2126        let mut child = child
 2127            .stdin(smol::process::Stdio::piped())
 2128            .stdout(smol::process::Stdio::piped())
 2129            .stderr(smol::process::Stdio::piped())
 2130            .spawn()?;
 2131
 2132        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2133        let text = buffer
 2134            .handle
 2135            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2136        for chunk in text.chunks() {
 2137            stdin.write_all(chunk.as_bytes()).await?;
 2138        }
 2139        stdin.flush().await?;
 2140
 2141        let output = child.output().await?;
 2142        anyhow::ensure!(
 2143            output.status.success(),
 2144            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2145            output.status.code(),
 2146            String::from_utf8_lossy(&output.stdout),
 2147            String::from_utf8_lossy(&output.stderr),
 2148        );
 2149
 2150        let stdout = String::from_utf8(output.stdout)?;
 2151        Ok(Some(
 2152            buffer
 2153                .handle
 2154                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2155                .await,
 2156        ))
 2157    }
 2158
 2159    async fn try_resolve_code_action(
 2160        lang_server: &LanguageServer,
 2161        action: &mut CodeAction,
 2162    ) -> anyhow::Result<()> {
 2163        match &mut action.lsp_action {
 2164            LspAction::Action(lsp_action) => {
 2165                if !action.resolved
 2166                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2167                    && lsp_action.data.is_some()
 2168                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2169                {
 2170                    *lsp_action = Box::new(
 2171                        lang_server
 2172                            .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2173                            .await
 2174                            .into_response()?,
 2175                    );
 2176                }
 2177            }
 2178            LspAction::CodeLens(lens) => {
 2179                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2180                    *lens = lang_server
 2181                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2182                        .await
 2183                        .into_response()?;
 2184                }
 2185            }
 2186            LspAction::Command(_) => {}
 2187        }
 2188
 2189        action.resolved = true;
 2190        anyhow::Ok(())
 2191    }
 2192
 2193    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2194        let buffer = buffer_handle.read(cx);
 2195
 2196        let file = buffer.file().cloned();
 2197
 2198        let Some(file) = File::from_dyn(file.as_ref()) else {
 2199            return;
 2200        };
 2201        if !file.is_local() {
 2202            return;
 2203        }
 2204        let path = ProjectPath::from_file(file, cx);
 2205        let worktree_id = file.worktree_id(cx);
 2206        let language = buffer.language().cloned();
 2207
 2208        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2209            for (server_id, diagnostics) in
 2210                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2211            {
 2212                self.update_buffer_diagnostics(
 2213                    buffer_handle,
 2214                    server_id,
 2215                    None,
 2216                    None,
 2217                    diagnostics,
 2218                    Vec::new(),
 2219                    cx,
 2220                )
 2221                .log_err();
 2222            }
 2223        }
 2224        let Some(language) = language else {
 2225            return;
 2226        };
 2227        let Some(snapshot) = self
 2228            .worktree_store
 2229            .read(cx)
 2230            .worktree_for_id(worktree_id, cx)
 2231            .map(|worktree| worktree.read(cx).snapshot())
 2232        else {
 2233            return;
 2234        };
 2235        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2236
 2237        for server_id in
 2238            self.lsp_tree
 2239                .get(path, language.name(), language.manifest(), &delegate, cx)
 2240        {
 2241            let server = self
 2242                .language_servers
 2243                .get(&server_id)
 2244                .and_then(|server_state| {
 2245                    if let LanguageServerState::Running { server, .. } = server_state {
 2246                        Some(server.clone())
 2247                    } else {
 2248                        None
 2249                    }
 2250                });
 2251            let server = match server {
 2252                Some(server) => server,
 2253                None => continue,
 2254            };
 2255
 2256            buffer_handle.update(cx, |buffer, cx| {
 2257                buffer.set_completion_triggers(
 2258                    server.server_id(),
 2259                    server
 2260                        .capabilities()
 2261                        .completion_provider
 2262                        .as_ref()
 2263                        .and_then(|provider| {
 2264                            provider
 2265                                .trigger_characters
 2266                                .as_ref()
 2267                                .map(|characters| characters.iter().cloned().collect())
 2268                        })
 2269                        .unwrap_or_default(),
 2270                    cx,
 2271                );
 2272            });
 2273        }
 2274    }
 2275
 2276    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2277        buffer.update(cx, |buffer, cx| {
 2278            let Some(language) = buffer.language() else {
 2279                return;
 2280            };
 2281            let path = ProjectPath {
 2282                worktree_id: old_file.worktree_id(cx),
 2283                path: old_file.path.clone(),
 2284            };
 2285            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2286                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2287                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2288            }
 2289        });
 2290    }
 2291
 2292    fn update_buffer_diagnostics(
 2293        &mut self,
 2294        buffer: &Entity<Buffer>,
 2295        server_id: LanguageServerId,
 2296        result_id: Option<String>,
 2297        version: Option<i32>,
 2298        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2299        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2300        cx: &mut Context<LspStore>,
 2301    ) -> Result<()> {
 2302        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2303            Ordering::Equal
 2304                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2305                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2306                .then_with(|| a.severity.cmp(&b.severity))
 2307                .then_with(|| a.message.cmp(&b.message))
 2308        }
 2309
 2310        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2311        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2312        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2313
 2314        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2315            Ordering::Equal
 2316                .then_with(|| a.range.start.cmp(&b.range.start))
 2317                .then_with(|| b.range.end.cmp(&a.range.end))
 2318                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2319        });
 2320
 2321        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2322
 2323        let edits_since_save = std::cell::LazyCell::new(|| {
 2324            let saved_version = buffer.read(cx).saved_version();
 2325            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2326        });
 2327
 2328        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2329
 2330        for (new_diagnostic, entry) in diagnostics {
 2331            let start;
 2332            let end;
 2333            if new_diagnostic && entry.diagnostic.is_disk_based {
 2334                // Some diagnostics are based on files on disk instead of buffers'
 2335                // current contents. Adjust these diagnostics' ranges to reflect
 2336                // any unsaved edits.
 2337                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2338                // and were properly adjusted on reuse.
 2339                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2340                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2341            } else {
 2342                start = entry.range.start;
 2343                end = entry.range.end;
 2344            }
 2345
 2346            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2347                ..snapshot.clip_point_utf16(end, Bias::Right);
 2348
 2349            // Expand empty ranges by one codepoint
 2350            if range.start == range.end {
 2351                // This will be go to the next boundary when being clipped
 2352                range.end.column += 1;
 2353                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2354                if range.start == range.end && range.end.column > 0 {
 2355                    range.start.column -= 1;
 2356                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2357                }
 2358            }
 2359
 2360            sanitized_diagnostics.push(DiagnosticEntry {
 2361                range,
 2362                diagnostic: entry.diagnostic,
 2363            });
 2364        }
 2365        drop(edits_since_save);
 2366
 2367        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2368        buffer.update(cx, |buffer, cx| {
 2369            if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2370                self.buffer_pull_diagnostics_result_ids
 2371                    .entry(server_id)
 2372                    .or_default()
 2373                    .insert(abs_path, result_id);
 2374            }
 2375
 2376            buffer.update_diagnostics(server_id, set, cx)
 2377        });
 2378
 2379        Ok(())
 2380    }
 2381
 2382    fn register_language_server_for_invisible_worktree(
 2383        &mut self,
 2384        worktree: &Entity<Worktree>,
 2385        language_server_id: LanguageServerId,
 2386        cx: &mut App,
 2387    ) {
 2388        let worktree = worktree.read(cx);
 2389        let worktree_id = worktree.id();
 2390        debug_assert!(!worktree.is_visible());
 2391        let Some(mut origin_seed) = self
 2392            .language_server_ids
 2393            .iter()
 2394            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2395        else {
 2396            return;
 2397        };
 2398        origin_seed.worktree_id = worktree_id;
 2399        self.language_server_ids
 2400            .entry(origin_seed)
 2401            .or_insert_with(|| UnifiedLanguageServer {
 2402                id: language_server_id,
 2403                project_roots: Default::default(),
 2404            });
 2405    }
 2406
 2407    fn register_buffer_with_language_servers(
 2408        &mut self,
 2409        buffer_handle: &Entity<Buffer>,
 2410        only_register_servers: HashSet<LanguageServerSelector>,
 2411        cx: &mut Context<LspStore>,
 2412    ) {
 2413        let buffer = buffer_handle.read(cx);
 2414        let buffer_id = buffer.remote_id();
 2415
 2416        let Some(file) = File::from_dyn(buffer.file()) else {
 2417            return;
 2418        };
 2419        if !file.is_local() {
 2420            return;
 2421        }
 2422
 2423        let abs_path = file.abs_path(cx);
 2424        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2425            return;
 2426        };
 2427        let initial_snapshot = buffer.text_snapshot();
 2428        let worktree_id = file.worktree_id(cx);
 2429
 2430        let Some(language) = buffer.language().cloned() else {
 2431            return;
 2432        };
 2433        let path: Arc<RelPath> = file
 2434            .path()
 2435            .parent()
 2436            .map(Arc::from)
 2437            .unwrap_or_else(|| file.path().clone());
 2438        let Some(worktree) = self
 2439            .worktree_store
 2440            .read(cx)
 2441            .worktree_for_id(worktree_id, cx)
 2442        else {
 2443            return;
 2444        };
 2445        let language_name = language.name();
 2446        let (reused, delegate, servers) = self
 2447            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2448            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2449            .unwrap_or_else(|| {
 2450                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2451                let delegate: Arc<dyn ManifestDelegate> =
 2452                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2453
 2454                let servers = self
 2455                    .lsp_tree
 2456                    .walk(
 2457                        ProjectPath { worktree_id, path },
 2458                        language.name(),
 2459                        language.manifest(),
 2460                        &delegate,
 2461                        cx,
 2462                    )
 2463                    .collect::<Vec<_>>();
 2464                (false, lsp_delegate, servers)
 2465            });
 2466        let servers_and_adapters = servers
 2467            .into_iter()
 2468            .filter_map(|server_node| {
 2469                if reused && server_node.server_id().is_none() {
 2470                    return None;
 2471                }
 2472                if !only_register_servers.is_empty() {
 2473                    if let Some(server_id) = server_node.server_id()
 2474                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2475                    {
 2476                        return None;
 2477                    }
 2478                    if let Some(name) = server_node.name()
 2479                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2480                    {
 2481                        return None;
 2482                    }
 2483                }
 2484
 2485                let server_id = server_node.server_id_or_init(|disposition| {
 2486                    let path = &disposition.path;
 2487
 2488                    {
 2489                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2490
 2491                        let server_id = self.get_or_insert_language_server(
 2492                            &worktree,
 2493                            delegate.clone(),
 2494                            disposition,
 2495                            &language_name,
 2496                            cx,
 2497                        );
 2498
 2499                        if let Some(state) = self.language_servers.get(&server_id)
 2500                            && let Ok(uri) = uri
 2501                        {
 2502                            state.add_workspace_folder(uri);
 2503                        };
 2504                        server_id
 2505                    }
 2506                })?;
 2507                let server_state = self.language_servers.get(&server_id)?;
 2508                if let LanguageServerState::Running {
 2509                    server, adapter, ..
 2510                } = server_state
 2511                {
 2512                    Some((server.clone(), adapter.clone()))
 2513                } else {
 2514                    None
 2515                }
 2516            })
 2517            .collect::<Vec<_>>();
 2518        for (server, adapter) in servers_and_adapters {
 2519            buffer_handle.update(cx, |buffer, cx| {
 2520                buffer.set_completion_triggers(
 2521                    server.server_id(),
 2522                    server
 2523                        .capabilities()
 2524                        .completion_provider
 2525                        .as_ref()
 2526                        .and_then(|provider| {
 2527                            provider
 2528                                .trigger_characters
 2529                                .as_ref()
 2530                                .map(|characters| characters.iter().cloned().collect())
 2531                        })
 2532                        .unwrap_or_default(),
 2533                    cx,
 2534                );
 2535            });
 2536
 2537            let snapshot = LspBufferSnapshot {
 2538                version: 0,
 2539                snapshot: initial_snapshot.clone(),
 2540            };
 2541
 2542            let mut registered = false;
 2543            self.buffer_snapshots
 2544                .entry(buffer_id)
 2545                .or_default()
 2546                .entry(server.server_id())
 2547                .or_insert_with(|| {
 2548                    registered = true;
 2549                    server.register_buffer(
 2550                        uri.clone(),
 2551                        adapter.language_id(&language.name()),
 2552                        0,
 2553                        initial_snapshot.text(),
 2554                    );
 2555
 2556                    vec![snapshot]
 2557                });
 2558
 2559            self.buffers_opened_in_servers
 2560                .entry(buffer_id)
 2561                .or_default()
 2562                .insert(server.server_id());
 2563            if registered {
 2564                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2565                    language_server_id: server.server_id(),
 2566                    name: None,
 2567                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2568                        proto::RegisteredForBuffer {
 2569                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2570                            buffer_id: buffer_id.to_proto(),
 2571                        },
 2572                    ),
 2573                });
 2574            }
 2575        }
 2576    }
 2577
 2578    fn reuse_existing_language_server<'lang_name>(
 2579        &self,
 2580        server_tree: &LanguageServerTree,
 2581        worktree: &Entity<Worktree>,
 2582        language_name: &'lang_name LanguageName,
 2583        cx: &mut App,
 2584    ) -> Option<(
 2585        Arc<LocalLspAdapterDelegate>,
 2586        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2587    )> {
 2588        if worktree.read(cx).is_visible() {
 2589            return None;
 2590        }
 2591
 2592        let worktree_store = self.worktree_store.read(cx);
 2593        let servers = server_tree
 2594            .instances
 2595            .iter()
 2596            .filter(|(worktree_id, _)| {
 2597                worktree_store
 2598                    .worktree_for_id(**worktree_id, cx)
 2599                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2600            })
 2601            .flat_map(|(worktree_id, servers)| {
 2602                servers
 2603                    .roots
 2604                    .iter()
 2605                    .flat_map(|(_, language_servers)| language_servers)
 2606                    .map(move |(_, (server_node, server_languages))| {
 2607                        (worktree_id, server_node, server_languages)
 2608                    })
 2609                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2610                    .map(|(worktree_id, server_node, _)| {
 2611                        (
 2612                            *worktree_id,
 2613                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2614                        )
 2615                    })
 2616            })
 2617            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2618                acc.entry(worktree_id)
 2619                    .or_insert_with(Vec::new)
 2620                    .push(server_node);
 2621                acc
 2622            })
 2623            .into_values()
 2624            .max_by_key(|servers| servers.len())?;
 2625
 2626        let worktree_id = worktree.read(cx).id();
 2627        let apply = move |tree: &mut LanguageServerTree| {
 2628            for server_node in &servers {
 2629                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2630            }
 2631            servers
 2632        };
 2633
 2634        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2635        Some((delegate, apply))
 2636    }
 2637
 2638    pub(crate) fn unregister_old_buffer_from_language_servers(
 2639        &mut self,
 2640        buffer: &Entity<Buffer>,
 2641        old_file: &File,
 2642        cx: &mut App,
 2643    ) {
 2644        let old_path = match old_file.as_local() {
 2645            Some(local) => local.abs_path(cx),
 2646            None => return,
 2647        };
 2648
 2649        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2650            debug_panic!("{old_path:?} is not parseable as an URI");
 2651            return;
 2652        };
 2653        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2654    }
 2655
 2656    pub(crate) fn unregister_buffer_from_language_servers(
 2657        &mut self,
 2658        buffer: &Entity<Buffer>,
 2659        file_url: &lsp::Uri,
 2660        cx: &mut App,
 2661    ) {
 2662        buffer.update(cx, |buffer, cx| {
 2663            let _ = self.buffer_snapshots.remove(&buffer.remote_id());
 2664
 2665            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2666                language_server.unregister_buffer(file_url.clone());
 2667            }
 2668        });
 2669    }
 2670
 2671    fn buffer_snapshot_for_lsp_version(
 2672        &mut self,
 2673        buffer: &Entity<Buffer>,
 2674        server_id: LanguageServerId,
 2675        version: Option<i32>,
 2676        cx: &App,
 2677    ) -> Result<TextBufferSnapshot> {
 2678        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2679
 2680        if let Some(version) = version {
 2681            let buffer_id = buffer.read(cx).remote_id();
 2682            let snapshots = if let Some(snapshots) = self
 2683                .buffer_snapshots
 2684                .get_mut(&buffer_id)
 2685                .and_then(|m| m.get_mut(&server_id))
 2686            {
 2687                snapshots
 2688            } else if version == 0 {
 2689                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2690                // We detect this case and treat it as if the version was `None`.
 2691                return Ok(buffer.read(cx).text_snapshot());
 2692            } else {
 2693                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2694            };
 2695
 2696            let found_snapshot = snapshots
 2697                    .binary_search_by_key(&version, |e| e.version)
 2698                    .map(|ix| snapshots[ix].snapshot.clone())
 2699                    .map_err(|_| {
 2700                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2701                    })?;
 2702
 2703            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2704            Ok(found_snapshot)
 2705        } else {
 2706            Ok((buffer.read(cx)).text_snapshot())
 2707        }
 2708    }
 2709
 2710    async fn get_server_code_actions_from_action_kinds(
 2711        lsp_store: &WeakEntity<LspStore>,
 2712        language_server_id: LanguageServerId,
 2713        code_action_kinds: Vec<lsp::CodeActionKind>,
 2714        buffer: &Entity<Buffer>,
 2715        cx: &mut AsyncApp,
 2716    ) -> Result<Vec<CodeAction>> {
 2717        let actions = lsp_store
 2718            .update(cx, move |this, cx| {
 2719                let request = GetCodeActions {
 2720                    range: text::Anchor::MIN..text::Anchor::MAX,
 2721                    kinds: Some(code_action_kinds),
 2722                };
 2723                let server = LanguageServerToQuery::Other(language_server_id);
 2724                this.request_lsp(buffer.clone(), server, request, cx)
 2725            })?
 2726            .await?;
 2727        Ok(actions)
 2728    }
 2729
 2730    pub async fn execute_code_actions_on_server(
 2731        lsp_store: &WeakEntity<LspStore>,
 2732        language_server: &Arc<LanguageServer>,
 2733
 2734        actions: Vec<CodeAction>,
 2735        push_to_history: bool,
 2736        project_transaction: &mut ProjectTransaction,
 2737        cx: &mut AsyncApp,
 2738    ) -> anyhow::Result<()> {
 2739        for mut action in actions {
 2740            Self::try_resolve_code_action(language_server, &mut action)
 2741                .await
 2742                .context("resolving a formatting code action")?;
 2743
 2744            if let Some(edit) = action.lsp_action.edit() {
 2745                if edit.changes.is_none() && edit.document_changes.is_none() {
 2746                    continue;
 2747                }
 2748
 2749                let new = Self::deserialize_workspace_edit(
 2750                    lsp_store.upgrade().context("project dropped")?,
 2751                    edit.clone(),
 2752                    push_to_history,
 2753                    language_server.clone(),
 2754                    cx,
 2755                )
 2756                .await?;
 2757                project_transaction.0.extend(new.0);
 2758            }
 2759
 2760            if let Some(command) = action.lsp_action.command() {
 2761                let server_capabilities = language_server.capabilities();
 2762                let available_commands = server_capabilities
 2763                    .execute_command_provider
 2764                    .as_ref()
 2765                    .map(|options| options.commands.as_slice())
 2766                    .unwrap_or_default();
 2767                if available_commands.contains(&command.command) {
 2768                    lsp_store.update(cx, |lsp_store, _| {
 2769                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2770                            mode.last_workspace_edits_by_language_server
 2771                                .remove(&language_server.server_id());
 2772                        }
 2773                    })?;
 2774
 2775                    language_server
 2776                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2777                            command: command.command.clone(),
 2778                            arguments: command.arguments.clone().unwrap_or_default(),
 2779                            ..Default::default()
 2780                        })
 2781                        .await
 2782                        .into_response()
 2783                        .context("execute command")?;
 2784
 2785                    lsp_store.update(cx, |this, _| {
 2786                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2787                            project_transaction.0.extend(
 2788                                mode.last_workspace_edits_by_language_server
 2789                                    .remove(&language_server.server_id())
 2790                                    .unwrap_or_default()
 2791                                    .0,
 2792                            )
 2793                        }
 2794                    })?;
 2795                } else {
 2796                    log::warn!(
 2797                        "Cannot execute a command {} not listed in the language server capabilities",
 2798                        command.command
 2799                    )
 2800                }
 2801            }
 2802        }
 2803        Ok(())
 2804    }
 2805
 2806    pub async fn deserialize_text_edits(
 2807        this: Entity<LspStore>,
 2808        buffer_to_edit: Entity<Buffer>,
 2809        edits: Vec<lsp::TextEdit>,
 2810        push_to_history: bool,
 2811        _: Arc<CachedLspAdapter>,
 2812        language_server: Arc<LanguageServer>,
 2813        cx: &mut AsyncApp,
 2814    ) -> Result<Option<Transaction>> {
 2815        let edits = this
 2816            .update(cx, |this, cx| {
 2817                this.as_local_mut().unwrap().edits_from_lsp(
 2818                    &buffer_to_edit,
 2819                    edits,
 2820                    language_server.server_id(),
 2821                    None,
 2822                    cx,
 2823                )
 2824            })?
 2825            .await?;
 2826
 2827        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2828            buffer.finalize_last_transaction();
 2829            buffer.start_transaction();
 2830            for (range, text) in edits {
 2831                buffer.edit([(range, text)], None, cx);
 2832            }
 2833
 2834            if buffer.end_transaction(cx).is_some() {
 2835                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2836                if !push_to_history {
 2837                    buffer.forget_transaction(transaction.id);
 2838                }
 2839                Some(transaction)
 2840            } else {
 2841                None
 2842            }
 2843        })?;
 2844
 2845        Ok(transaction)
 2846    }
 2847
 2848    #[allow(clippy::type_complexity)]
 2849    pub(crate) fn edits_from_lsp(
 2850        &mut self,
 2851        buffer: &Entity<Buffer>,
 2852        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2853        server_id: LanguageServerId,
 2854        version: Option<i32>,
 2855        cx: &mut Context<LspStore>,
 2856    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 2857        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 2858        cx.background_spawn(async move {
 2859            let snapshot = snapshot?;
 2860            let mut lsp_edits = lsp_edits
 2861                .into_iter()
 2862                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 2863                .collect::<Vec<_>>();
 2864
 2865            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 2866
 2867            let mut lsp_edits = lsp_edits.into_iter().peekable();
 2868            let mut edits = Vec::new();
 2869            while let Some((range, mut new_text)) = lsp_edits.next() {
 2870                // Clip invalid ranges provided by the language server.
 2871                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 2872                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 2873
 2874                // Combine any LSP edits that are adjacent.
 2875                //
 2876                // Also, combine LSP edits that are separated from each other by only
 2877                // a newline. This is important because for some code actions,
 2878                // Rust-analyzer rewrites the entire buffer via a series of edits that
 2879                // are separated by unchanged newline characters.
 2880                //
 2881                // In order for the diffing logic below to work properly, any edits that
 2882                // cancel each other out must be combined into one.
 2883                while let Some((next_range, next_text)) = lsp_edits.peek() {
 2884                    if next_range.start.0 > range.end {
 2885                        if next_range.start.0.row > range.end.row + 1
 2886                            || next_range.start.0.column > 0
 2887                            || snapshot.clip_point_utf16(
 2888                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 2889                                Bias::Left,
 2890                            ) > range.end
 2891                        {
 2892                            break;
 2893                        }
 2894                        new_text.push('\n');
 2895                    }
 2896                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 2897                    new_text.push_str(next_text);
 2898                    lsp_edits.next();
 2899                }
 2900
 2901                // For multiline edits, perform a diff of the old and new text so that
 2902                // we can identify the changes more precisely, preserving the locations
 2903                // of any anchors positioned in the unchanged regions.
 2904                if range.end.row > range.start.row {
 2905                    let offset = range.start.to_offset(&snapshot);
 2906                    let old_text = snapshot.text_for_range(range).collect::<String>();
 2907                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 2908                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 2909                        (
 2910                            snapshot.anchor_after(offset + range.start)
 2911                                ..snapshot.anchor_before(offset + range.end),
 2912                            replacement,
 2913                        )
 2914                    }));
 2915                } else if range.end == range.start {
 2916                    let anchor = snapshot.anchor_after(range.start);
 2917                    edits.push((anchor..anchor, new_text.into()));
 2918                } else {
 2919                    let edit_start = snapshot.anchor_after(range.start);
 2920                    let edit_end = snapshot.anchor_before(range.end);
 2921                    edits.push((edit_start..edit_end, new_text.into()));
 2922                }
 2923            }
 2924
 2925            Ok(edits)
 2926        })
 2927    }
 2928
 2929    pub(crate) async fn deserialize_workspace_edit(
 2930        this: Entity<LspStore>,
 2931        edit: lsp::WorkspaceEdit,
 2932        push_to_history: bool,
 2933        language_server: Arc<LanguageServer>,
 2934        cx: &mut AsyncApp,
 2935    ) -> Result<ProjectTransaction> {
 2936        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 2937
 2938        let mut operations = Vec::new();
 2939        if let Some(document_changes) = edit.document_changes {
 2940            match document_changes {
 2941                lsp::DocumentChanges::Edits(edits) => {
 2942                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 2943                }
 2944                lsp::DocumentChanges::Operations(ops) => operations = ops,
 2945            }
 2946        } else if let Some(changes) = edit.changes {
 2947            operations.extend(changes.into_iter().map(|(uri, edits)| {
 2948                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 2949                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 2950                        uri,
 2951                        version: None,
 2952                    },
 2953                    edits: edits.into_iter().map(Edit::Plain).collect(),
 2954                })
 2955            }));
 2956        }
 2957
 2958        let mut project_transaction = ProjectTransaction::default();
 2959        for operation in operations {
 2960            match operation {
 2961                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 2962                    let abs_path = op
 2963                        .uri
 2964                        .to_file_path()
 2965                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2966
 2967                    if let Some(parent_path) = abs_path.parent() {
 2968                        fs.create_dir(parent_path).await?;
 2969                    }
 2970                    if abs_path.ends_with("/") {
 2971                        fs.create_dir(&abs_path).await?;
 2972                    } else {
 2973                        fs.create_file(
 2974                            &abs_path,
 2975                            op.options
 2976                                .map(|options| fs::CreateOptions {
 2977                                    overwrite: options.overwrite.unwrap_or(false),
 2978                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 2979                                })
 2980                                .unwrap_or_default(),
 2981                        )
 2982                        .await?;
 2983                    }
 2984                }
 2985
 2986                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 2987                    let source_abs_path = op
 2988                        .old_uri
 2989                        .to_file_path()
 2990                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2991                    let target_abs_path = op
 2992                        .new_uri
 2993                        .to_file_path()
 2994                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2995                    fs.rename(
 2996                        &source_abs_path,
 2997                        &target_abs_path,
 2998                        op.options
 2999                            .map(|options| fs::RenameOptions {
 3000                                overwrite: options.overwrite.unwrap_or(false),
 3001                                ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3002                            })
 3003                            .unwrap_or_default(),
 3004                    )
 3005                    .await?;
 3006                }
 3007
 3008                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3009                    let abs_path = op
 3010                        .uri
 3011                        .to_file_path()
 3012                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3013                    let options = op
 3014                        .options
 3015                        .map(|options| fs::RemoveOptions {
 3016                            recursive: options.recursive.unwrap_or(false),
 3017                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3018                        })
 3019                        .unwrap_or_default();
 3020                    if abs_path.ends_with("/") {
 3021                        fs.remove_dir(&abs_path, options).await?;
 3022                    } else {
 3023                        fs.remove_file(&abs_path, options).await?;
 3024                    }
 3025                }
 3026
 3027                lsp::DocumentChangeOperation::Edit(op) => {
 3028                    let buffer_to_edit = this
 3029                        .update(cx, |this, cx| {
 3030                            this.open_local_buffer_via_lsp(
 3031                                op.text_document.uri.clone(),
 3032                                language_server.server_id(),
 3033                                cx,
 3034                            )
 3035                        })?
 3036                        .await?;
 3037
 3038                    let edits = this
 3039                        .update(cx, |this, cx| {
 3040                            let path = buffer_to_edit.read(cx).project_path(cx);
 3041                            let active_entry = this.active_entry;
 3042                            let is_active_entry = path.is_some_and(|project_path| {
 3043                                this.worktree_store
 3044                                    .read(cx)
 3045                                    .entry_for_path(&project_path, cx)
 3046                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3047                            });
 3048                            let local = this.as_local_mut().unwrap();
 3049
 3050                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3051                            for edit in op.edits {
 3052                                match edit {
 3053                                    Edit::Plain(edit) => {
 3054                                        if !edits.contains(&edit) {
 3055                                            edits.push(edit)
 3056                                        }
 3057                                    }
 3058                                    Edit::Annotated(edit) => {
 3059                                        if !edits.contains(&edit.text_edit) {
 3060                                            edits.push(edit.text_edit)
 3061                                        }
 3062                                    }
 3063                                    Edit::Snippet(edit) => {
 3064                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3065                                        else {
 3066                                            continue;
 3067                                        };
 3068
 3069                                        if is_active_entry {
 3070                                            snippet_edits.push((edit.range, snippet));
 3071                                        } else {
 3072                                            // Since this buffer is not focused, apply a normal edit.
 3073                                            let new_edit = TextEdit {
 3074                                                range: edit.range,
 3075                                                new_text: snippet.text,
 3076                                            };
 3077                                            if !edits.contains(&new_edit) {
 3078                                                edits.push(new_edit);
 3079                                            }
 3080                                        }
 3081                                    }
 3082                                }
 3083                            }
 3084                            if !snippet_edits.is_empty() {
 3085                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3086                                let version = if let Some(buffer_version) = op.text_document.version
 3087                                {
 3088                                    local
 3089                                        .buffer_snapshot_for_lsp_version(
 3090                                            &buffer_to_edit,
 3091                                            language_server.server_id(),
 3092                                            Some(buffer_version),
 3093                                            cx,
 3094                                        )
 3095                                        .ok()
 3096                                        .map(|snapshot| snapshot.version)
 3097                                } else {
 3098                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3099                                };
 3100
 3101                                let most_recent_edit =
 3102                                    version.and_then(|version| version.most_recent());
 3103                                // Check if the edit that triggered that edit has been made by this participant.
 3104
 3105                                if let Some(most_recent_edit) = most_recent_edit {
 3106                                    cx.emit(LspStoreEvent::SnippetEdit {
 3107                                        buffer_id,
 3108                                        edits: snippet_edits,
 3109                                        most_recent_edit,
 3110                                    });
 3111                                }
 3112                            }
 3113
 3114                            local.edits_from_lsp(
 3115                                &buffer_to_edit,
 3116                                edits,
 3117                                language_server.server_id(),
 3118                                op.text_document.version,
 3119                                cx,
 3120                            )
 3121                        })?
 3122                        .await?;
 3123
 3124                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3125                        buffer.finalize_last_transaction();
 3126                        buffer.start_transaction();
 3127                        for (range, text) in edits {
 3128                            buffer.edit([(range, text)], None, cx);
 3129                        }
 3130
 3131                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3132                            if push_to_history {
 3133                                buffer.finalize_last_transaction();
 3134                                buffer.get_transaction(transaction_id).cloned()
 3135                            } else {
 3136                                buffer.forget_transaction(transaction_id)
 3137                            }
 3138                        })
 3139                    })?;
 3140                    if let Some(transaction) = transaction {
 3141                        project_transaction.0.insert(buffer_to_edit, transaction);
 3142                    }
 3143                }
 3144            }
 3145        }
 3146
 3147        Ok(project_transaction)
 3148    }
 3149
 3150    async fn on_lsp_workspace_edit(
 3151        this: WeakEntity<LspStore>,
 3152        params: lsp::ApplyWorkspaceEditParams,
 3153        server_id: LanguageServerId,
 3154        cx: &mut AsyncApp,
 3155    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3156        let this = this.upgrade().context("project project closed")?;
 3157        let language_server = this
 3158            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3159            .context("language server not found")?;
 3160        let transaction = Self::deserialize_workspace_edit(
 3161            this.clone(),
 3162            params.edit,
 3163            true,
 3164            language_server.clone(),
 3165            cx,
 3166        )
 3167        .await
 3168        .log_err();
 3169        this.update(cx, |this, _| {
 3170            if let Some(transaction) = transaction {
 3171                this.as_local_mut()
 3172                    .unwrap()
 3173                    .last_workspace_edits_by_language_server
 3174                    .insert(server_id, transaction);
 3175            }
 3176        })?;
 3177        Ok(lsp::ApplyWorkspaceEditResponse {
 3178            applied: true,
 3179            failed_change: None,
 3180            failure_reason: None,
 3181        })
 3182    }
 3183
 3184    fn remove_worktree(
 3185        &mut self,
 3186        id_to_remove: WorktreeId,
 3187        cx: &mut Context<LspStore>,
 3188    ) -> Vec<LanguageServerId> {
 3189        self.diagnostics.remove(&id_to_remove);
 3190        self.prettier_store.update(cx, |prettier_store, cx| {
 3191            prettier_store.remove_worktree(id_to_remove, cx);
 3192        });
 3193
 3194        let mut servers_to_remove = BTreeSet::default();
 3195        let mut servers_to_preserve = HashSet::default();
 3196        for (seed, state) in &self.language_server_ids {
 3197            if seed.worktree_id == id_to_remove {
 3198                servers_to_remove.insert(state.id);
 3199            } else {
 3200                servers_to_preserve.insert(state.id);
 3201            }
 3202        }
 3203        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3204        self.language_server_ids
 3205            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3206        for server_id_to_remove in &servers_to_remove {
 3207            self.language_server_watched_paths
 3208                .remove(server_id_to_remove);
 3209            self.language_server_paths_watched_for_rename
 3210                .remove(server_id_to_remove);
 3211            self.last_workspace_edits_by_language_server
 3212                .remove(server_id_to_remove);
 3213            self.language_servers.remove(server_id_to_remove);
 3214            self.buffer_pull_diagnostics_result_ids
 3215                .remove(server_id_to_remove);
 3216            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3217                buffer_servers.remove(server_id_to_remove);
 3218            }
 3219            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3220        }
 3221        servers_to_remove.into_iter().collect()
 3222    }
 3223
 3224    fn rebuild_watched_paths_inner<'a>(
 3225        &'a self,
 3226        language_server_id: LanguageServerId,
 3227        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3228        cx: &mut Context<LspStore>,
 3229    ) -> LanguageServerWatchedPathsBuilder {
 3230        let worktrees = self
 3231            .worktree_store
 3232            .read(cx)
 3233            .worktrees()
 3234            .filter_map(|worktree| {
 3235                self.language_servers_for_worktree(worktree.read(cx).id())
 3236                    .find(|server| server.server_id() == language_server_id)
 3237                    .map(|_| worktree)
 3238            })
 3239            .collect::<Vec<_>>();
 3240
 3241        let mut worktree_globs = HashMap::default();
 3242        let mut abs_globs = HashMap::default();
 3243        log::trace!(
 3244            "Processing new watcher paths for language server with id {}",
 3245            language_server_id
 3246        );
 3247
 3248        for watcher in watchers {
 3249            if let Some((worktree, literal_prefix, pattern)) =
 3250                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3251            {
 3252                worktree.update(cx, |worktree, _| {
 3253                    if let Some((tree, glob)) =
 3254                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3255                    {
 3256                        tree.add_path_prefix_to_scan(literal_prefix);
 3257                        worktree_globs
 3258                            .entry(tree.id())
 3259                            .or_insert_with(GlobSetBuilder::new)
 3260                            .add(glob);
 3261                    }
 3262                });
 3263            } else {
 3264                let (path, pattern) = match &watcher.glob_pattern {
 3265                    lsp::GlobPattern::String(s) => {
 3266                        let watcher_path = SanitizedPath::new(s);
 3267                        let path = glob_literal_prefix(watcher_path.as_path());
 3268                        let pattern = watcher_path
 3269                            .as_path()
 3270                            .strip_prefix(&path)
 3271                            .map(|p| p.to_string_lossy().into_owned())
 3272                            .unwrap_or_else(|e| {
 3273                                debug_panic!(
 3274                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3275                                    s,
 3276                                    path.display(),
 3277                                    e
 3278                                );
 3279                                watcher_path.as_path().to_string_lossy().into_owned()
 3280                            });
 3281                        (path, pattern)
 3282                    }
 3283                    lsp::GlobPattern::Relative(rp) => {
 3284                        let Ok(mut base_uri) = match &rp.base_uri {
 3285                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3286                            lsp::OneOf::Right(base_uri) => base_uri,
 3287                        }
 3288                        .to_file_path() else {
 3289                            continue;
 3290                        };
 3291
 3292                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3293                        let pattern = Path::new(&rp.pattern)
 3294                            .strip_prefix(&path)
 3295                            .map(|p| p.to_string_lossy().into_owned())
 3296                            .unwrap_or_else(|e| {
 3297                                debug_panic!(
 3298                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3299                                    rp.pattern,
 3300                                    path.display(),
 3301                                    e
 3302                                );
 3303                                rp.pattern.clone()
 3304                            });
 3305                        base_uri.push(path);
 3306                        (base_uri, pattern)
 3307                    }
 3308                };
 3309
 3310                if let Some(glob) = Glob::new(&pattern).log_err() {
 3311                    if !path
 3312                        .components()
 3313                        .any(|c| matches!(c, path::Component::Normal(_)))
 3314                    {
 3315                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3316                        // rather than adding a new watcher for `/`.
 3317                        for worktree in &worktrees {
 3318                            worktree_globs
 3319                                .entry(worktree.read(cx).id())
 3320                                .or_insert_with(GlobSetBuilder::new)
 3321                                .add(glob.clone());
 3322                        }
 3323                    } else {
 3324                        abs_globs
 3325                            .entry(path.into())
 3326                            .or_insert_with(GlobSetBuilder::new)
 3327                            .add(glob);
 3328                    }
 3329                }
 3330            }
 3331        }
 3332
 3333        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3334        for (worktree_id, builder) in worktree_globs {
 3335            if let Ok(globset) = builder.build() {
 3336                watch_builder.watch_worktree(worktree_id, globset);
 3337            }
 3338        }
 3339        for (abs_path, builder) in abs_globs {
 3340            if let Ok(globset) = builder.build() {
 3341                watch_builder.watch_abs_path(abs_path, globset);
 3342            }
 3343        }
 3344        watch_builder
 3345    }
 3346
 3347    fn worktree_and_path_for_file_watcher(
 3348        worktrees: &[Entity<Worktree>],
 3349        watcher: &FileSystemWatcher,
 3350        cx: &App,
 3351    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3352        worktrees.iter().find_map(|worktree| {
 3353            let tree = worktree.read(cx);
 3354            let worktree_root_path = tree.abs_path();
 3355            let path_style = tree.path_style();
 3356            match &watcher.glob_pattern {
 3357                lsp::GlobPattern::String(s) => {
 3358                    let watcher_path = SanitizedPath::new(s);
 3359                    let relative = watcher_path
 3360                        .as_path()
 3361                        .strip_prefix(&worktree_root_path)
 3362                        .ok()?;
 3363                    let literal_prefix = glob_literal_prefix(relative);
 3364                    Some((
 3365                        worktree.clone(),
 3366                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3367                        relative.to_string_lossy().into_owned(),
 3368                    ))
 3369                }
 3370                lsp::GlobPattern::Relative(rp) => {
 3371                    let base_uri = match &rp.base_uri {
 3372                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3373                        lsp::OneOf::Right(base_uri) => base_uri,
 3374                    }
 3375                    .to_file_path()
 3376                    .ok()?;
 3377                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3378                    let mut literal_prefix = relative.to_owned();
 3379                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3380                    Some((
 3381                        worktree.clone(),
 3382                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3383                        rp.pattern.clone(),
 3384                    ))
 3385                }
 3386            }
 3387        })
 3388    }
 3389
 3390    fn rebuild_watched_paths(
 3391        &mut self,
 3392        language_server_id: LanguageServerId,
 3393        cx: &mut Context<LspStore>,
 3394    ) {
 3395        let Some(registrations) = self
 3396            .language_server_dynamic_registrations
 3397            .get(&language_server_id)
 3398        else {
 3399            return;
 3400        };
 3401
 3402        let watch_builder = self.rebuild_watched_paths_inner(
 3403            language_server_id,
 3404            registrations.did_change_watched_files.values().flatten(),
 3405            cx,
 3406        );
 3407        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3408        self.language_server_watched_paths
 3409            .insert(language_server_id, watcher);
 3410
 3411        cx.notify();
 3412    }
 3413
 3414    fn on_lsp_did_change_watched_files(
 3415        &mut self,
 3416        language_server_id: LanguageServerId,
 3417        registration_id: &str,
 3418        params: DidChangeWatchedFilesRegistrationOptions,
 3419        cx: &mut Context<LspStore>,
 3420    ) {
 3421        let registrations = self
 3422            .language_server_dynamic_registrations
 3423            .entry(language_server_id)
 3424            .or_default();
 3425
 3426        registrations
 3427            .did_change_watched_files
 3428            .insert(registration_id.to_string(), params.watchers);
 3429
 3430        self.rebuild_watched_paths(language_server_id, cx);
 3431    }
 3432
 3433    fn on_lsp_unregister_did_change_watched_files(
 3434        &mut self,
 3435        language_server_id: LanguageServerId,
 3436        registration_id: &str,
 3437        cx: &mut Context<LspStore>,
 3438    ) {
 3439        let registrations = self
 3440            .language_server_dynamic_registrations
 3441            .entry(language_server_id)
 3442            .or_default();
 3443
 3444        if registrations
 3445            .did_change_watched_files
 3446            .remove(registration_id)
 3447            .is_some()
 3448        {
 3449            log::info!(
 3450                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3451                language_server_id,
 3452                registration_id
 3453            );
 3454        } else {
 3455            log::warn!(
 3456                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3457                language_server_id,
 3458                registration_id
 3459            );
 3460        }
 3461
 3462        self.rebuild_watched_paths(language_server_id, cx);
 3463    }
 3464
 3465    async fn initialization_options_for_adapter(
 3466        adapter: Arc<dyn LspAdapter>,
 3467        delegate: &Arc<dyn LspAdapterDelegate>,
 3468    ) -> Result<Option<serde_json::Value>> {
 3469        let Some(mut initialization_config) =
 3470            adapter.clone().initialization_options(delegate).await?
 3471        else {
 3472            return Ok(None);
 3473        };
 3474
 3475        for other_adapter in delegate.registered_lsp_adapters() {
 3476            if other_adapter.name() == adapter.name() {
 3477                continue;
 3478            }
 3479            if let Ok(Some(target_config)) = other_adapter
 3480                .clone()
 3481                .additional_initialization_options(adapter.name(), delegate)
 3482                .await
 3483            {
 3484                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3485            }
 3486        }
 3487
 3488        Ok(Some(initialization_config))
 3489    }
 3490
 3491    async fn workspace_configuration_for_adapter(
 3492        adapter: Arc<dyn LspAdapter>,
 3493        delegate: &Arc<dyn LspAdapterDelegate>,
 3494        toolchain: Option<Toolchain>,
 3495        cx: &mut AsyncApp,
 3496    ) -> Result<serde_json::Value> {
 3497        let mut workspace_config = adapter
 3498            .clone()
 3499            .workspace_configuration(delegate, toolchain, cx)
 3500            .await?;
 3501
 3502        for other_adapter in delegate.registered_lsp_adapters() {
 3503            if other_adapter.name() == adapter.name() {
 3504                continue;
 3505            }
 3506            if let Ok(Some(target_config)) = other_adapter
 3507                .clone()
 3508                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3509                .await
 3510            {
 3511                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3512            }
 3513        }
 3514
 3515        Ok(workspace_config)
 3516    }
 3517
 3518    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3519        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3520            Some(server.clone())
 3521        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3522            Some(Arc::clone(server))
 3523        } else {
 3524            None
 3525        }
 3526    }
 3527}
 3528
 3529fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3530    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3531        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3532            language_server_id: server.server_id(),
 3533            name: Some(server.name()),
 3534            message: proto::update_language_server::Variant::MetadataUpdated(
 3535                proto::ServerMetadataUpdated {
 3536                    capabilities: Some(capabilities),
 3537                },
 3538            ),
 3539        });
 3540    }
 3541}
 3542
 3543#[derive(Debug)]
 3544pub struct FormattableBuffer {
 3545    handle: Entity<Buffer>,
 3546    abs_path: Option<PathBuf>,
 3547    env: Option<HashMap<String, String>>,
 3548    ranges: Option<Vec<Range<Anchor>>>,
 3549}
 3550
 3551pub struct RemoteLspStore {
 3552    upstream_client: Option<AnyProtoClient>,
 3553    upstream_project_id: u64,
 3554}
 3555
 3556pub(crate) enum LspStoreMode {
 3557    Local(LocalLspStore),   // ssh host and collab host
 3558    Remote(RemoteLspStore), // collab guest
 3559}
 3560
 3561impl LspStoreMode {
 3562    fn is_local(&self) -> bool {
 3563        matches!(self, LspStoreMode::Local(_))
 3564    }
 3565}
 3566
 3567pub struct LspStore {
 3568    mode: LspStoreMode,
 3569    last_formatting_failure: Option<String>,
 3570    downstream_client: Option<(AnyProtoClient, u64)>,
 3571    nonce: u128,
 3572    buffer_store: Entity<BufferStore>,
 3573    worktree_store: Entity<WorktreeStore>,
 3574    pub languages: Arc<LanguageRegistry>,
 3575    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3576    active_entry: Option<ProjectEntryId>,
 3577    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3578    _maintain_buffer_languages: Task<()>,
 3579    diagnostic_summaries:
 3580        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3581    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3582    lsp_data: HashMap<BufferId, BufferLspData>,
 3583    next_hint_id: Arc<AtomicUsize>,
 3584}
 3585
 3586#[derive(Debug)]
 3587pub struct BufferLspData {
 3588    buffer_version: Global,
 3589    document_colors: Option<DocumentColorData>,
 3590    code_lens: Option<CodeLensData>,
 3591    inlay_hints: BufferInlayHints,
 3592    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3593    chunk_lsp_requests: HashMap<LspKey, HashMap<BufferChunk, LspRequestId>>,
 3594}
 3595
 3596#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3597struct LspKey {
 3598    request_type: TypeId,
 3599    server_queried: Option<LanguageServerId>,
 3600}
 3601
 3602impl BufferLspData {
 3603    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3604        Self {
 3605            buffer_version: buffer.read(cx).version(),
 3606            document_colors: None,
 3607            code_lens: None,
 3608            inlay_hints: BufferInlayHints::new(buffer, cx),
 3609            lsp_requests: HashMap::default(),
 3610            chunk_lsp_requests: HashMap::default(),
 3611        }
 3612    }
 3613
 3614    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3615        if let Some(document_colors) = &mut self.document_colors {
 3616            document_colors.colors.remove(&for_server);
 3617            document_colors.cache_version += 1;
 3618        }
 3619
 3620        if let Some(code_lens) = &mut self.code_lens {
 3621            code_lens.lens.remove(&for_server);
 3622        }
 3623
 3624        self.inlay_hints.remove_server_data(for_server);
 3625    }
 3626
 3627    #[cfg(any(test, feature = "test-support"))]
 3628    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3629        &self.inlay_hints
 3630    }
 3631}
 3632
 3633#[derive(Debug, Default, Clone)]
 3634pub struct DocumentColors {
 3635    pub colors: HashSet<DocumentColor>,
 3636    pub cache_version: Option<usize>,
 3637}
 3638
 3639type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3640type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3641
 3642#[derive(Debug, Default)]
 3643struct DocumentColorData {
 3644    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3645    cache_version: usize,
 3646    colors_update: Option<(Global, DocumentColorTask)>,
 3647}
 3648
 3649#[derive(Debug, Default)]
 3650struct CodeLensData {
 3651    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3652    update: Option<(Global, CodeLensTask)>,
 3653}
 3654
 3655#[derive(Debug)]
 3656pub enum LspStoreEvent {
 3657    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3658    LanguageServerRemoved(LanguageServerId),
 3659    LanguageServerUpdate {
 3660        language_server_id: LanguageServerId,
 3661        name: Option<LanguageServerName>,
 3662        message: proto::update_language_server::Variant,
 3663    },
 3664    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3665    LanguageServerPrompt(LanguageServerPromptRequest),
 3666    LanguageDetected {
 3667        buffer: Entity<Buffer>,
 3668        new_language: Option<Arc<Language>>,
 3669    },
 3670    Notification(String),
 3671    RefreshInlayHints {
 3672        server_id: LanguageServerId,
 3673        request_id: Option<usize>,
 3674    },
 3675    RefreshCodeLens,
 3676    DiagnosticsUpdated {
 3677        server_id: LanguageServerId,
 3678        paths: Vec<ProjectPath>,
 3679    },
 3680    DiskBasedDiagnosticsStarted {
 3681        language_server_id: LanguageServerId,
 3682    },
 3683    DiskBasedDiagnosticsFinished {
 3684        language_server_id: LanguageServerId,
 3685    },
 3686    SnippetEdit {
 3687        buffer_id: BufferId,
 3688        edits: Vec<(lsp::Range, Snippet)>,
 3689        most_recent_edit: clock::Lamport,
 3690    },
 3691}
 3692
 3693#[derive(Clone, Debug, Serialize)]
 3694pub struct LanguageServerStatus {
 3695    pub name: LanguageServerName,
 3696    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 3697    pub has_pending_diagnostic_updates: bool,
 3698    progress_tokens: HashSet<ProgressToken>,
 3699    pub worktree: Option<WorktreeId>,
 3700}
 3701
 3702#[derive(Clone, Debug)]
 3703struct CoreSymbol {
 3704    pub language_server_name: LanguageServerName,
 3705    pub source_worktree_id: WorktreeId,
 3706    pub source_language_server_id: LanguageServerId,
 3707    pub path: SymbolLocation,
 3708    pub name: String,
 3709    pub kind: lsp::SymbolKind,
 3710    pub range: Range<Unclipped<PointUtf16>>,
 3711}
 3712
 3713#[derive(Clone, Debug, PartialEq, Eq)]
 3714pub enum SymbolLocation {
 3715    InProject(ProjectPath),
 3716    OutsideProject {
 3717        abs_path: Arc<Path>,
 3718        signature: [u8; 32],
 3719    },
 3720}
 3721
 3722impl SymbolLocation {
 3723    fn file_name(&self) -> Option<&str> {
 3724        match self {
 3725            Self::InProject(path) => path.path.file_name(),
 3726            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3727        }
 3728    }
 3729}
 3730
 3731impl LspStore {
 3732    pub fn init(client: &AnyProtoClient) {
 3733        client.add_entity_request_handler(Self::handle_lsp_query);
 3734        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3735        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3736        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3737        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3738        client.add_entity_message_handler(Self::handle_start_language_server);
 3739        client.add_entity_message_handler(Self::handle_update_language_server);
 3740        client.add_entity_message_handler(Self::handle_language_server_log);
 3741        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3742        client.add_entity_request_handler(Self::handle_format_buffers);
 3743        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3744        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3745        client.add_entity_request_handler(Self::handle_apply_code_action);
 3746        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3747        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3748        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3749        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3750        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3751        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3752        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3753        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3754        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3755        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3756        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3757        client.add_entity_request_handler(Self::handle_lsp_command::<GetCompletions>);
 3758        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3759        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3760        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3761        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3762        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3763
 3764        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3765        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3766        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3767        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3768        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3769        client.add_entity_request_handler(
 3770            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3771        );
 3772        client.add_entity_request_handler(
 3773            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3774        );
 3775        client.add_entity_request_handler(
 3776            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3777        );
 3778    }
 3779
 3780    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3781        match &self.mode {
 3782            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3783            _ => None,
 3784        }
 3785    }
 3786
 3787    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3788        match &self.mode {
 3789            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3790            _ => None,
 3791        }
 3792    }
 3793
 3794    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3795        match &mut self.mode {
 3796            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3797            _ => None,
 3798        }
 3799    }
 3800
 3801    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3802        match &self.mode {
 3803            LspStoreMode::Remote(RemoteLspStore {
 3804                upstream_client: Some(upstream_client),
 3805                upstream_project_id,
 3806                ..
 3807            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3808
 3809            LspStoreMode::Remote(RemoteLspStore {
 3810                upstream_client: None,
 3811                ..
 3812            }) => None,
 3813            LspStoreMode::Local(_) => None,
 3814        }
 3815    }
 3816
 3817    pub fn new_local(
 3818        buffer_store: Entity<BufferStore>,
 3819        worktree_store: Entity<WorktreeStore>,
 3820        prettier_store: Entity<PrettierStore>,
 3821        toolchain_store: Entity<LocalToolchainStore>,
 3822        environment: Entity<ProjectEnvironment>,
 3823        manifest_tree: Entity<ManifestTree>,
 3824        languages: Arc<LanguageRegistry>,
 3825        http_client: Arc<dyn HttpClient>,
 3826        fs: Arc<dyn Fs>,
 3827        cx: &mut Context<Self>,
 3828    ) -> Self {
 3829        let yarn = YarnPathStore::new(fs.clone(), cx);
 3830        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3831            .detach();
 3832        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3833            .detach();
 3834        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 3835            .detach();
 3836        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 3837            .detach();
 3838        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 3839            .detach();
 3840        subscribe_to_binary_statuses(&languages, cx).detach();
 3841
 3842        let _maintain_workspace_config = {
 3843            let (sender, receiver) = watch::channel();
 3844            (Self::maintain_workspace_config(receiver, cx), sender)
 3845        };
 3846
 3847        Self {
 3848            mode: LspStoreMode::Local(LocalLspStore {
 3849                weak: cx.weak_entity(),
 3850                worktree_store: worktree_store.clone(),
 3851
 3852                supplementary_language_servers: Default::default(),
 3853                languages: languages.clone(),
 3854                language_server_ids: Default::default(),
 3855                language_servers: Default::default(),
 3856                last_workspace_edits_by_language_server: Default::default(),
 3857                language_server_watched_paths: Default::default(),
 3858                language_server_paths_watched_for_rename: Default::default(),
 3859                language_server_dynamic_registrations: Default::default(),
 3860                buffers_being_formatted: Default::default(),
 3861                buffer_snapshots: Default::default(),
 3862                prettier_store,
 3863                environment,
 3864                http_client,
 3865                fs,
 3866                yarn,
 3867                next_diagnostic_group_id: Default::default(),
 3868                diagnostics: Default::default(),
 3869                _subscription: cx.on_app_quit(|this, cx| {
 3870                    this.as_local_mut()
 3871                        .unwrap()
 3872                        .shutdown_language_servers_on_quit(cx)
 3873                }),
 3874                lsp_tree: LanguageServerTree::new(
 3875                    manifest_tree,
 3876                    languages.clone(),
 3877                    toolchain_store.clone(),
 3878                ),
 3879                toolchain_store,
 3880                registered_buffers: HashMap::default(),
 3881                buffers_opened_in_servers: HashMap::default(),
 3882                buffer_pull_diagnostics_result_ids: HashMap::default(),
 3883                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 3884                    .manifest_file_names(),
 3885            }),
 3886            last_formatting_failure: None,
 3887            downstream_client: None,
 3888            buffer_store,
 3889            worktree_store,
 3890            languages: languages.clone(),
 3891            language_server_statuses: Default::default(),
 3892            nonce: StdRng::from_os_rng().random(),
 3893            diagnostic_summaries: HashMap::default(),
 3894            lsp_server_capabilities: HashMap::default(),
 3895            lsp_data: HashMap::default(),
 3896            next_hint_id: Arc::default(),
 3897            active_entry: None,
 3898            _maintain_workspace_config,
 3899            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 3900        }
 3901    }
 3902
 3903    fn send_lsp_proto_request<R: LspCommand>(
 3904        &self,
 3905        buffer: Entity<Buffer>,
 3906        client: AnyProtoClient,
 3907        upstream_project_id: u64,
 3908        request: R,
 3909        cx: &mut Context<LspStore>,
 3910    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 3911        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 3912            return Task::ready(Ok(R::Response::default()));
 3913        }
 3914        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 3915        cx.spawn(async move |this, cx| {
 3916            let response = client.request(message).await?;
 3917            let this = this.upgrade().context("project dropped")?;
 3918            request
 3919                .response_from_proto(response, this, buffer, cx.clone())
 3920                .await
 3921        })
 3922    }
 3923
 3924    pub(super) fn new_remote(
 3925        buffer_store: Entity<BufferStore>,
 3926        worktree_store: Entity<WorktreeStore>,
 3927        languages: Arc<LanguageRegistry>,
 3928        upstream_client: AnyProtoClient,
 3929        project_id: u64,
 3930        cx: &mut Context<Self>,
 3931    ) -> Self {
 3932        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3933            .detach();
 3934        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3935            .detach();
 3936        subscribe_to_binary_statuses(&languages, cx).detach();
 3937        let _maintain_workspace_config = {
 3938            let (sender, receiver) = watch::channel();
 3939            (Self::maintain_workspace_config(receiver, cx), sender)
 3940        };
 3941        Self {
 3942            mode: LspStoreMode::Remote(RemoteLspStore {
 3943                upstream_client: Some(upstream_client),
 3944                upstream_project_id: project_id,
 3945            }),
 3946            downstream_client: None,
 3947            last_formatting_failure: None,
 3948            buffer_store,
 3949            worktree_store,
 3950            languages: languages.clone(),
 3951            language_server_statuses: Default::default(),
 3952            nonce: StdRng::from_os_rng().random(),
 3953            diagnostic_summaries: HashMap::default(),
 3954            lsp_server_capabilities: HashMap::default(),
 3955            next_hint_id: Arc::default(),
 3956            lsp_data: HashMap::default(),
 3957            active_entry: None,
 3958
 3959            _maintain_workspace_config,
 3960            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 3961        }
 3962    }
 3963
 3964    fn on_buffer_store_event(
 3965        &mut self,
 3966        _: Entity<BufferStore>,
 3967        event: &BufferStoreEvent,
 3968        cx: &mut Context<Self>,
 3969    ) {
 3970        match event {
 3971            BufferStoreEvent::BufferAdded(buffer) => {
 3972                self.on_buffer_added(buffer, cx).log_err();
 3973            }
 3974            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 3975                let buffer_id = buffer.read(cx).remote_id();
 3976                if let Some(local) = self.as_local_mut()
 3977                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 3978                {
 3979                    local.reset_buffer(buffer, old_file, cx);
 3980
 3981                    if local.registered_buffers.contains_key(&buffer_id) {
 3982                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 3983                    }
 3984                }
 3985
 3986                self.detect_language_for_buffer(buffer, cx);
 3987                if let Some(local) = self.as_local_mut() {
 3988                    local.initialize_buffer(buffer, cx);
 3989                    if local.registered_buffers.contains_key(&buffer_id) {
 3990                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 3991                    }
 3992                }
 3993            }
 3994            _ => {}
 3995        }
 3996    }
 3997
 3998    fn on_worktree_store_event(
 3999        &mut self,
 4000        _: Entity<WorktreeStore>,
 4001        event: &WorktreeStoreEvent,
 4002        cx: &mut Context<Self>,
 4003    ) {
 4004        match event {
 4005            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4006                if !worktree.read(cx).is_local() {
 4007                    return;
 4008                }
 4009                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4010                    worktree::Event::UpdatedEntries(changes) => {
 4011                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4012                    }
 4013                    worktree::Event::UpdatedGitRepositories(_)
 4014                    | worktree::Event::DeletedEntry(_) => {}
 4015                })
 4016                .detach()
 4017            }
 4018            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4019            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4020                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4021            }
 4022            WorktreeStoreEvent::WorktreeReleased(..)
 4023            | WorktreeStoreEvent::WorktreeOrderChanged
 4024            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4025            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4026            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4027        }
 4028    }
 4029
 4030    fn on_prettier_store_event(
 4031        &mut self,
 4032        _: Entity<PrettierStore>,
 4033        event: &PrettierStoreEvent,
 4034        cx: &mut Context<Self>,
 4035    ) {
 4036        match event {
 4037            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4038                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4039            }
 4040            PrettierStoreEvent::LanguageServerAdded {
 4041                new_server_id,
 4042                name,
 4043                prettier_server,
 4044            } => {
 4045                self.register_supplementary_language_server(
 4046                    *new_server_id,
 4047                    name.clone(),
 4048                    prettier_server.clone(),
 4049                    cx,
 4050                );
 4051            }
 4052        }
 4053    }
 4054
 4055    fn on_toolchain_store_event(
 4056        &mut self,
 4057        _: Entity<LocalToolchainStore>,
 4058        event: &ToolchainStoreEvent,
 4059        _: &mut Context<Self>,
 4060    ) {
 4061        if let ToolchainStoreEvent::ToolchainActivated = event {
 4062            self.request_workspace_config_refresh()
 4063        }
 4064    }
 4065
 4066    fn request_workspace_config_refresh(&mut self) {
 4067        *self._maintain_workspace_config.1.borrow_mut() = ();
 4068    }
 4069
 4070    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4071        self.as_local().map(|local| local.prettier_store.clone())
 4072    }
 4073
 4074    fn on_buffer_event(
 4075        &mut self,
 4076        buffer: Entity<Buffer>,
 4077        event: &language::BufferEvent,
 4078        cx: &mut Context<Self>,
 4079    ) {
 4080        match event {
 4081            language::BufferEvent::Edited => {
 4082                self.on_buffer_edited(buffer, cx);
 4083            }
 4084
 4085            language::BufferEvent::Saved => {
 4086                self.on_buffer_saved(buffer, cx);
 4087            }
 4088
 4089            _ => {}
 4090        }
 4091    }
 4092
 4093    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4094        buffer
 4095            .read(cx)
 4096            .set_language_registry(self.languages.clone());
 4097
 4098        cx.subscribe(buffer, |this, buffer, event, cx| {
 4099            this.on_buffer_event(buffer, event, cx);
 4100        })
 4101        .detach();
 4102
 4103        self.detect_language_for_buffer(buffer, cx);
 4104        if let Some(local) = self.as_local_mut() {
 4105            local.initialize_buffer(buffer, cx);
 4106        }
 4107
 4108        Ok(())
 4109    }
 4110
 4111    pub(crate) fn register_buffer_with_language_servers(
 4112        &mut self,
 4113        buffer: &Entity<Buffer>,
 4114        only_register_servers: HashSet<LanguageServerSelector>,
 4115        ignore_refcounts: bool,
 4116        cx: &mut Context<Self>,
 4117    ) -> OpenLspBufferHandle {
 4118        let buffer_id = buffer.read(cx).remote_id();
 4119        let handle = cx.new(|_| buffer.clone());
 4120        if let Some(local) = self.as_local_mut() {
 4121            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4122            if !ignore_refcounts {
 4123                *refcount += 1;
 4124            }
 4125
 4126            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4127            // When a new unnamed buffer is created and saved, we will start loading it's language. Once the language is loaded, we go over all "language-less" buffers and try to fit that new language
 4128            // with them. However, we do that only for the buffers that we think are open in at least one editor; thus, we need to keep tab of unnamed buffers as well, even though they're not actually registered with any language
 4129            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4130            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4131                return handle;
 4132            };
 4133            if !file.is_local() {
 4134                return handle;
 4135            }
 4136
 4137            if ignore_refcounts || *refcount == 1 {
 4138                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4139            }
 4140            if !ignore_refcounts {
 4141                cx.observe_release(&handle, move |lsp_store, buffer, cx| {
 4142                    let refcount = {
 4143                        let local = lsp_store.as_local_mut().unwrap();
 4144                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4145                            debug_panic!("bad refcounting");
 4146                            return;
 4147                        };
 4148
 4149                        *refcount -= 1;
 4150                        *refcount
 4151                    };
 4152                    if refcount == 0 {
 4153                        lsp_store.lsp_data.remove(&buffer_id);
 4154                        let local = lsp_store.as_local_mut().unwrap();
 4155                        local.registered_buffers.remove(&buffer_id);
 4156                        local.buffers_opened_in_servers.remove(&buffer_id);
 4157                        if let Some(file) = File::from_dyn(buffer.read(cx).file()).cloned() {
 4158                            local.unregister_old_buffer_from_language_servers(buffer, &file, cx);
 4159                        }
 4160                    }
 4161                })
 4162                .detach();
 4163            }
 4164        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4165            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4166            cx.background_spawn(async move {
 4167                upstream_client
 4168                    .request(proto::RegisterBufferWithLanguageServers {
 4169                        project_id: upstream_project_id,
 4170                        buffer_id,
 4171                        only_servers: only_register_servers
 4172                            .into_iter()
 4173                            .map(|selector| {
 4174                                let selector = match selector {
 4175                                    LanguageServerSelector::Id(language_server_id) => {
 4176                                        proto::language_server_selector::Selector::ServerId(
 4177                                            language_server_id.to_proto(),
 4178                                        )
 4179                                    }
 4180                                    LanguageServerSelector::Name(language_server_name) => {
 4181                                        proto::language_server_selector::Selector::Name(
 4182                                            language_server_name.to_string(),
 4183                                        )
 4184                                    }
 4185                                };
 4186                                proto::LanguageServerSelector {
 4187                                    selector: Some(selector),
 4188                                }
 4189                            })
 4190                            .collect(),
 4191                    })
 4192                    .await
 4193            })
 4194            .detach();
 4195        } else {
 4196            // Our remote connection got closed
 4197        }
 4198        handle
 4199    }
 4200
 4201    fn maintain_buffer_languages(
 4202        languages: Arc<LanguageRegistry>,
 4203        cx: &mut Context<Self>,
 4204    ) -> Task<()> {
 4205        let mut subscription = languages.subscribe();
 4206        let mut prev_reload_count = languages.reload_count();
 4207        cx.spawn(async move |this, cx| {
 4208            while let Some(()) = subscription.next().await {
 4209                if let Some(this) = this.upgrade() {
 4210                    // If the language registry has been reloaded, then remove and
 4211                    // re-assign the languages on all open buffers.
 4212                    let reload_count = languages.reload_count();
 4213                    if reload_count > prev_reload_count {
 4214                        prev_reload_count = reload_count;
 4215                        this.update(cx, |this, cx| {
 4216                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4217                                for buffer in buffer_store.buffers() {
 4218                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4219                                    {
 4220                                        buffer
 4221                                            .update(cx, |buffer, cx| buffer.set_language(None, cx));
 4222                                        if let Some(local) = this.as_local_mut() {
 4223                                            local.reset_buffer(&buffer, &f, cx);
 4224
 4225                                            if local
 4226                                                .registered_buffers
 4227                                                .contains_key(&buffer.read(cx).remote_id())
 4228                                                && let Some(file_url) =
 4229                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4230                                            {
 4231                                                local.unregister_buffer_from_language_servers(
 4232                                                    &buffer, &file_url, cx,
 4233                                                );
 4234                                            }
 4235                                        }
 4236                                    }
 4237                                }
 4238                            });
 4239                        })
 4240                        .ok();
 4241                    }
 4242
 4243                    this.update(cx, |this, cx| {
 4244                        let mut plain_text_buffers = Vec::new();
 4245                        let mut buffers_with_unknown_injections = Vec::new();
 4246                        for handle in this.buffer_store.read(cx).buffers() {
 4247                            let buffer = handle.read(cx);
 4248                            if buffer.language().is_none()
 4249                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4250                            {
 4251                                plain_text_buffers.push(handle);
 4252                            } else if buffer.contains_unknown_injections() {
 4253                                buffers_with_unknown_injections.push(handle);
 4254                            }
 4255                        }
 4256
 4257                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4258                        // and reused later in the invisible worktrees.
 4259                        plain_text_buffers.sort_by_key(|buffer| {
 4260                            Reverse(
 4261                                File::from_dyn(buffer.read(cx).file())
 4262                                    .map(|file| file.worktree.read(cx).is_visible()),
 4263                            )
 4264                        });
 4265
 4266                        for buffer in plain_text_buffers {
 4267                            this.detect_language_for_buffer(&buffer, cx);
 4268                            if let Some(local) = this.as_local_mut() {
 4269                                local.initialize_buffer(&buffer, cx);
 4270                                if local
 4271                                    .registered_buffers
 4272                                    .contains_key(&buffer.read(cx).remote_id())
 4273                                {
 4274                                    local.register_buffer_with_language_servers(
 4275                                        &buffer,
 4276                                        HashSet::default(),
 4277                                        cx,
 4278                                    );
 4279                                }
 4280                            }
 4281                        }
 4282
 4283                        for buffer in buffers_with_unknown_injections {
 4284                            buffer.update(cx, |buffer, cx| buffer.reparse(cx));
 4285                        }
 4286                    })
 4287                    .ok();
 4288                }
 4289            }
 4290        })
 4291    }
 4292
 4293    fn detect_language_for_buffer(
 4294        &mut self,
 4295        buffer_handle: &Entity<Buffer>,
 4296        cx: &mut Context<Self>,
 4297    ) -> Option<language::AvailableLanguage> {
 4298        // If the buffer has a language, set it and start the language server if we haven't already.
 4299        let buffer = buffer_handle.read(cx);
 4300        let file = buffer.file()?;
 4301
 4302        let content = buffer.as_rope();
 4303        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4304        if let Some(available_language) = &available_language {
 4305            if let Some(Ok(Ok(new_language))) = self
 4306                .languages
 4307                .load_language(available_language)
 4308                .now_or_never()
 4309            {
 4310                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4311            }
 4312        } else {
 4313            cx.emit(LspStoreEvent::LanguageDetected {
 4314                buffer: buffer_handle.clone(),
 4315                new_language: None,
 4316            });
 4317        }
 4318
 4319        available_language
 4320    }
 4321
 4322    pub(crate) fn set_language_for_buffer(
 4323        &mut self,
 4324        buffer_entity: &Entity<Buffer>,
 4325        new_language: Arc<Language>,
 4326        cx: &mut Context<Self>,
 4327    ) {
 4328        let buffer = buffer_entity.read(cx);
 4329        let buffer_file = buffer.file().cloned();
 4330        let buffer_id = buffer.remote_id();
 4331        if let Some(local_store) = self.as_local_mut()
 4332            && local_store.registered_buffers.contains_key(&buffer_id)
 4333            && let Some(abs_path) =
 4334                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4335            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4336        {
 4337            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4338        }
 4339        buffer_entity.update(cx, |buffer, cx| {
 4340            if buffer
 4341                .language()
 4342                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4343            {
 4344                buffer.set_language(Some(new_language.clone()), cx);
 4345            }
 4346        });
 4347
 4348        let settings =
 4349            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4350        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4351
 4352        let worktree_id = if let Some(file) = buffer_file {
 4353            let worktree = file.worktree.clone();
 4354
 4355            if let Some(local) = self.as_local_mut()
 4356                && local.registered_buffers.contains_key(&buffer_id)
 4357            {
 4358                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4359            }
 4360            Some(worktree.read(cx).id())
 4361        } else {
 4362            None
 4363        };
 4364
 4365        if settings.prettier.allowed
 4366            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4367        {
 4368            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4369            if let Some(prettier_store) = prettier_store {
 4370                prettier_store.update(cx, |prettier_store, cx| {
 4371                    prettier_store.install_default_prettier(
 4372                        worktree_id,
 4373                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4374                        cx,
 4375                    )
 4376                })
 4377            }
 4378        }
 4379
 4380        cx.emit(LspStoreEvent::LanguageDetected {
 4381            buffer: buffer_entity.clone(),
 4382            new_language: Some(new_language),
 4383        })
 4384    }
 4385
 4386    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4387        self.buffer_store.clone()
 4388    }
 4389
 4390    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4391        self.active_entry = active_entry;
 4392    }
 4393
 4394    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4395        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4396            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4397        {
 4398            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4399                summaries
 4400                    .iter()
 4401                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4402            });
 4403            if let Some(summary) = summaries.next() {
 4404                client
 4405                    .send(proto::UpdateDiagnosticSummary {
 4406                        project_id: downstream_project_id,
 4407                        worktree_id: worktree.id().to_proto(),
 4408                        summary: Some(summary),
 4409                        more_summaries: summaries.collect(),
 4410                    })
 4411                    .log_err();
 4412            }
 4413        }
 4414    }
 4415
 4416    fn is_capable_for_proto_request<R>(
 4417        &self,
 4418        buffer: &Entity<Buffer>,
 4419        request: &R,
 4420        cx: &App,
 4421    ) -> bool
 4422    where
 4423        R: LspCommand,
 4424    {
 4425        self.check_if_capable_for_proto_request(
 4426            buffer,
 4427            |capabilities| {
 4428                request.check_capabilities(AdapterServerCapabilities {
 4429                    server_capabilities: capabilities.clone(),
 4430                    code_action_kinds: None,
 4431                })
 4432            },
 4433            cx,
 4434        )
 4435    }
 4436
 4437    fn check_if_capable_for_proto_request<F>(
 4438        &self,
 4439        buffer: &Entity<Buffer>,
 4440        check: F,
 4441        cx: &App,
 4442    ) -> bool
 4443    where
 4444        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4445    {
 4446        let Some(language) = buffer.read(cx).language().cloned() else {
 4447            return false;
 4448        };
 4449        let relevant_language_servers = self
 4450            .languages
 4451            .lsp_adapters(&language.name())
 4452            .into_iter()
 4453            .map(|lsp_adapter| lsp_adapter.name())
 4454            .collect::<HashSet<_>>();
 4455        self.language_server_statuses
 4456            .iter()
 4457            .filter_map(|(server_id, server_status)| {
 4458                relevant_language_servers
 4459                    .contains(&server_status.name)
 4460                    .then_some(server_id)
 4461            })
 4462            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4463            .any(check)
 4464    }
 4465
 4466    pub fn request_lsp<R>(
 4467        &mut self,
 4468        buffer: Entity<Buffer>,
 4469        server: LanguageServerToQuery,
 4470        request: R,
 4471        cx: &mut Context<Self>,
 4472    ) -> Task<Result<R::Response>>
 4473    where
 4474        R: LspCommand,
 4475        <R::LspRequest as lsp::request::Request>::Result: Send,
 4476        <R::LspRequest as lsp::request::Request>::Params: Send,
 4477    {
 4478        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4479            return self.send_lsp_proto_request(
 4480                buffer,
 4481                upstream_client,
 4482                upstream_project_id,
 4483                request,
 4484                cx,
 4485            );
 4486        }
 4487
 4488        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4489            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4490                local
 4491                    .language_servers_for_buffer(buffer, cx)
 4492                    .find(|(_, server)| {
 4493                        request.check_capabilities(server.adapter_server_capabilities())
 4494                    })
 4495                    .map(|(_, server)| server.clone())
 4496            }),
 4497            LanguageServerToQuery::Other(id) => self
 4498                .language_server_for_local_buffer(buffer, id, cx)
 4499                .and_then(|(_, server)| {
 4500                    request
 4501                        .check_capabilities(server.adapter_server_capabilities())
 4502                        .then(|| Arc::clone(server))
 4503                }),
 4504        }) else {
 4505            return Task::ready(Ok(Default::default()));
 4506        };
 4507
 4508        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4509
 4510        let Some(file) = file else {
 4511            return Task::ready(Ok(Default::default()));
 4512        };
 4513
 4514        let lsp_params = match request.to_lsp_params_or_response(
 4515            &file.abs_path(cx),
 4516            buffer.read(cx),
 4517            &language_server,
 4518            cx,
 4519        ) {
 4520            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4521            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4522            Err(err) => {
 4523                let message = format!(
 4524                    "{} via {} failed: {}",
 4525                    request.display_name(),
 4526                    language_server.name(),
 4527                    err
 4528                );
 4529                // rust-analyzer likes to error with this when its still loading up
 4530                if !message.ends_with("content modified") {
 4531                    log::warn!("{message}");
 4532                }
 4533                return Task::ready(Err(anyhow!(message)));
 4534            }
 4535        };
 4536
 4537        let status = request.status();
 4538        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4539            return Task::ready(Ok(Default::default()));
 4540        }
 4541        cx.spawn(async move |this, cx| {
 4542            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4543
 4544            let id = lsp_request.id();
 4545            let _cleanup = if status.is_some() {
 4546                cx.update(|cx| {
 4547                    this.update(cx, |this, cx| {
 4548                        this.on_lsp_work_start(
 4549                            language_server.server_id(),
 4550                            ProgressToken::Number(id),
 4551                            LanguageServerProgress {
 4552                                is_disk_based_diagnostics_progress: false,
 4553                                is_cancellable: false,
 4554                                title: None,
 4555                                message: status.clone(),
 4556                                percentage: None,
 4557                                last_update_at: cx.background_executor().now(),
 4558                            },
 4559                            cx,
 4560                        );
 4561                    })
 4562                })
 4563                .log_err();
 4564
 4565                Some(defer(|| {
 4566                    cx.update(|cx| {
 4567                        this.update(cx, |this, cx| {
 4568                            this.on_lsp_work_end(
 4569                                language_server.server_id(),
 4570                                ProgressToken::Number(id),
 4571                                cx,
 4572                            );
 4573                        })
 4574                    })
 4575                    .log_err();
 4576                }))
 4577            } else {
 4578                None
 4579            };
 4580
 4581            let result = lsp_request.await.into_response();
 4582
 4583            let response = result.map_err(|err| {
 4584                let message = format!(
 4585                    "{} via {} failed: {}",
 4586                    request.display_name(),
 4587                    language_server.name(),
 4588                    err
 4589                );
 4590                // rust-analyzer likes to error with this when its still loading up
 4591                if !message.ends_with("content modified") {
 4592                    log::warn!("{message}");
 4593                }
 4594                anyhow::anyhow!(message)
 4595            })?;
 4596
 4597            request
 4598                .response_from_lsp(
 4599                    response,
 4600                    this.upgrade().context("no app context")?,
 4601                    buffer,
 4602                    language_server.server_id(),
 4603                    cx.clone(),
 4604                )
 4605                .await
 4606        })
 4607    }
 4608
 4609    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4610        let mut language_formatters_to_check = Vec::new();
 4611        for buffer in self.buffer_store.read(cx).buffers() {
 4612            let buffer = buffer.read(cx);
 4613            let buffer_file = File::from_dyn(buffer.file());
 4614            let buffer_language = buffer.language();
 4615            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4616            if buffer_language.is_some() {
 4617                language_formatters_to_check.push((
 4618                    buffer_file.map(|f| f.worktree_id(cx)),
 4619                    settings.into_owned(),
 4620                ));
 4621            }
 4622        }
 4623
 4624        self.request_workspace_config_refresh();
 4625
 4626        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4627            prettier_store.update(cx, |prettier_store, cx| {
 4628                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4629            })
 4630        }
 4631
 4632        cx.notify();
 4633    }
 4634
 4635    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4636        let buffer_store = self.buffer_store.clone();
 4637        let Some(local) = self.as_local_mut() else {
 4638            return;
 4639        };
 4640        let mut adapters = BTreeMap::default();
 4641        let get_adapter = {
 4642            let languages = local.languages.clone();
 4643            let environment = local.environment.clone();
 4644            let weak = local.weak.clone();
 4645            let worktree_store = local.worktree_store.clone();
 4646            let http_client = local.http_client.clone();
 4647            let fs = local.fs.clone();
 4648            move |worktree_id, cx: &mut App| {
 4649                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4650                Some(LocalLspAdapterDelegate::new(
 4651                    languages.clone(),
 4652                    &environment,
 4653                    weak.clone(),
 4654                    &worktree,
 4655                    http_client.clone(),
 4656                    fs.clone(),
 4657                    cx,
 4658                ))
 4659            }
 4660        };
 4661
 4662        let mut messages_to_report = Vec::new();
 4663        let (new_tree, to_stop) = {
 4664            let mut rebase = local.lsp_tree.rebase();
 4665            let buffers = buffer_store
 4666                .read(cx)
 4667                .buffers()
 4668                .filter_map(|buffer| {
 4669                    let raw_buffer = buffer.read(cx);
 4670                    if !local
 4671                        .registered_buffers
 4672                        .contains_key(&raw_buffer.remote_id())
 4673                    {
 4674                        return None;
 4675                    }
 4676                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4677                    let language = raw_buffer.language().cloned()?;
 4678                    Some((file, language, raw_buffer.remote_id()))
 4679                })
 4680                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4681            for (file, language, buffer_id) in buffers {
 4682                let worktree_id = file.worktree_id(cx);
 4683                let Some(worktree) = local
 4684                    .worktree_store
 4685                    .read(cx)
 4686                    .worktree_for_id(worktree_id, cx)
 4687                else {
 4688                    continue;
 4689                };
 4690
 4691                if let Some((_, apply)) = local.reuse_existing_language_server(
 4692                    rebase.server_tree(),
 4693                    &worktree,
 4694                    &language.name(),
 4695                    cx,
 4696                ) {
 4697                    (apply)(rebase.server_tree());
 4698                } else if let Some(lsp_delegate) = adapters
 4699                    .entry(worktree_id)
 4700                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4701                    .clone()
 4702                {
 4703                    let delegate =
 4704                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4705                    let path = file
 4706                        .path()
 4707                        .parent()
 4708                        .map(Arc::from)
 4709                        .unwrap_or_else(|| file.path().clone());
 4710                    let worktree_path = ProjectPath { worktree_id, path };
 4711                    let abs_path = file.abs_path(cx);
 4712                    let nodes = rebase
 4713                        .walk(
 4714                            worktree_path,
 4715                            language.name(),
 4716                            language.manifest(),
 4717                            delegate.clone(),
 4718                            cx,
 4719                        )
 4720                        .collect::<Vec<_>>();
 4721                    for node in nodes {
 4722                        let server_id = node.server_id_or_init(|disposition| {
 4723                            let path = &disposition.path;
 4724                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 4725                            let key = LanguageServerSeed {
 4726                                worktree_id,
 4727                                name: disposition.server_name.clone(),
 4728                                settings: disposition.settings.clone(),
 4729                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4730                                    path.worktree_id,
 4731                                    &path.path,
 4732                                    language.name(),
 4733                                ),
 4734                            };
 4735                            local.language_server_ids.remove(&key);
 4736
 4737                            let server_id = local.get_or_insert_language_server(
 4738                                &worktree,
 4739                                lsp_delegate.clone(),
 4740                                disposition,
 4741                                &language.name(),
 4742                                cx,
 4743                            );
 4744                            if let Some(state) = local.language_servers.get(&server_id)
 4745                                && let Ok(uri) = uri
 4746                            {
 4747                                state.add_workspace_folder(uri);
 4748                            };
 4749                            server_id
 4750                        });
 4751
 4752                        if let Some(language_server_id) = server_id {
 4753                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 4754                                language_server_id,
 4755                                name: node.name(),
 4756                                message:
 4757                                    proto::update_language_server::Variant::RegisteredForBuffer(
 4758                                        proto::RegisteredForBuffer {
 4759                                            buffer_abs_path: abs_path
 4760                                                .to_string_lossy()
 4761                                                .into_owned(),
 4762                                            buffer_id: buffer_id.to_proto(),
 4763                                        },
 4764                                    ),
 4765                            });
 4766                        }
 4767                    }
 4768                } else {
 4769                    continue;
 4770                }
 4771            }
 4772            rebase.finish()
 4773        };
 4774        for message in messages_to_report {
 4775            cx.emit(message);
 4776        }
 4777        local.lsp_tree = new_tree;
 4778        for (id, _) in to_stop {
 4779            self.stop_local_language_server(id, cx).detach();
 4780        }
 4781    }
 4782
 4783    pub fn apply_code_action(
 4784        &self,
 4785        buffer_handle: Entity<Buffer>,
 4786        mut action: CodeAction,
 4787        push_to_history: bool,
 4788        cx: &mut Context<Self>,
 4789    ) -> Task<Result<ProjectTransaction>> {
 4790        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4791            let request = proto::ApplyCodeAction {
 4792                project_id,
 4793                buffer_id: buffer_handle.read(cx).remote_id().into(),
 4794                action: Some(Self::serialize_code_action(&action)),
 4795            };
 4796            let buffer_store = self.buffer_store();
 4797            cx.spawn(async move |_, cx| {
 4798                let response = upstream_client
 4799                    .request(request)
 4800                    .await?
 4801                    .transaction
 4802                    .context("missing transaction")?;
 4803
 4804                buffer_store
 4805                    .update(cx, |buffer_store, cx| {
 4806                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 4807                    })?
 4808                    .await
 4809            })
 4810        } else if self.mode.is_local() {
 4811            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 4812                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 4813                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 4814            }) else {
 4815                return Task::ready(Ok(ProjectTransaction::default()));
 4816            };
 4817            cx.spawn(async move |this,  cx| {
 4818                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 4819                    .await
 4820                    .context("resolving a code action")?;
 4821                if let Some(edit) = action.lsp_action.edit()
 4822                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 4823                        return LocalLspStore::deserialize_workspace_edit(
 4824                            this.upgrade().context("no app present")?,
 4825                            edit.clone(),
 4826                            push_to_history,
 4827
 4828                            lang_server.clone(),
 4829                            cx,
 4830                        )
 4831                        .await;
 4832                    }
 4833
 4834                if let Some(command) = action.lsp_action.command() {
 4835                    let server_capabilities = lang_server.capabilities();
 4836                    let available_commands = server_capabilities
 4837                        .execute_command_provider
 4838                        .as_ref()
 4839                        .map(|options| options.commands.as_slice())
 4840                        .unwrap_or_default();
 4841                    if available_commands.contains(&command.command) {
 4842                        this.update(cx, |this, _| {
 4843                            this.as_local_mut()
 4844                                .unwrap()
 4845                                .last_workspace_edits_by_language_server
 4846                                .remove(&lang_server.server_id());
 4847                        })?;
 4848
 4849                        let _result = lang_server
 4850                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 4851                                command: command.command.clone(),
 4852                                arguments: command.arguments.clone().unwrap_or_default(),
 4853                                ..lsp::ExecuteCommandParams::default()
 4854                            })
 4855                            .await.into_response()
 4856                            .context("execute command")?;
 4857
 4858                        return this.update(cx, |this, _| {
 4859                            this.as_local_mut()
 4860                                .unwrap()
 4861                                .last_workspace_edits_by_language_server
 4862                                .remove(&lang_server.server_id())
 4863                                .unwrap_or_default()
 4864                        });
 4865                    } else {
 4866                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 4867                    }
 4868                }
 4869
 4870                Ok(ProjectTransaction::default())
 4871            })
 4872        } else {
 4873            Task::ready(Err(anyhow!("no upstream client and not local")))
 4874        }
 4875    }
 4876
 4877    pub fn apply_code_action_kind(
 4878        &mut self,
 4879        buffers: HashSet<Entity<Buffer>>,
 4880        kind: CodeActionKind,
 4881        push_to_history: bool,
 4882        cx: &mut Context<Self>,
 4883    ) -> Task<anyhow::Result<ProjectTransaction>> {
 4884        if self.as_local().is_some() {
 4885            cx.spawn(async move |lsp_store, cx| {
 4886                let buffers = buffers.into_iter().collect::<Vec<_>>();
 4887                let result = LocalLspStore::execute_code_action_kind_locally(
 4888                    lsp_store.clone(),
 4889                    buffers,
 4890                    kind,
 4891                    push_to_history,
 4892                    cx,
 4893                )
 4894                .await;
 4895                lsp_store.update(cx, |lsp_store, _| {
 4896                    lsp_store.update_last_formatting_failure(&result);
 4897                })?;
 4898                result
 4899            })
 4900        } else if let Some((client, project_id)) = self.upstream_client() {
 4901            let buffer_store = self.buffer_store();
 4902            cx.spawn(async move |lsp_store, cx| {
 4903                let result = client
 4904                    .request(proto::ApplyCodeActionKind {
 4905                        project_id,
 4906                        kind: kind.as_str().to_owned(),
 4907                        buffer_ids: buffers
 4908                            .iter()
 4909                            .map(|buffer| {
 4910                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 4911                            })
 4912                            .collect::<Result<_>>()?,
 4913                    })
 4914                    .await
 4915                    .and_then(|result| result.transaction.context("missing transaction"));
 4916                lsp_store.update(cx, |lsp_store, _| {
 4917                    lsp_store.update_last_formatting_failure(&result);
 4918                })?;
 4919
 4920                let transaction_response = result?;
 4921                buffer_store
 4922                    .update(cx, |buffer_store, cx| {
 4923                        buffer_store.deserialize_project_transaction(
 4924                            transaction_response,
 4925                            push_to_history,
 4926                            cx,
 4927                        )
 4928                    })?
 4929                    .await
 4930            })
 4931        } else {
 4932            Task::ready(Ok(ProjectTransaction::default()))
 4933        }
 4934    }
 4935
 4936    pub fn resolved_hint(
 4937        &mut self,
 4938        buffer_id: BufferId,
 4939        id: InlayId,
 4940        cx: &mut Context<Self>,
 4941    ) -> Option<ResolvedHint> {
 4942        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 4943
 4944        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 4945        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 4946        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 4947        let (server_id, resolve_data) = match &hint.resolve_state {
 4948            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 4949            ResolveState::Resolving => {
 4950                return Some(ResolvedHint::Resolving(
 4951                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 4952                ));
 4953            }
 4954            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 4955        };
 4956
 4957        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 4958        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 4959        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 4960            id,
 4961            cx.spawn(async move |lsp_store, cx| {
 4962                let resolved_hint = resolve_task.await;
 4963                lsp_store
 4964                    .update(cx, |lsp_store, _| {
 4965                        if let Some(old_inlay_hint) = lsp_store
 4966                            .lsp_data
 4967                            .get_mut(&buffer_id)
 4968                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 4969                        {
 4970                            match resolved_hint {
 4971                                Ok(resolved_hint) => {
 4972                                    *old_inlay_hint = resolved_hint;
 4973                                }
 4974                                Err(e) => {
 4975                                    old_inlay_hint.resolve_state =
 4976                                        ResolveState::CanResolve(server_id, resolve_data);
 4977                                    log::error!("Inlay hint resolve failed: {e:#}");
 4978                                }
 4979                            }
 4980                        }
 4981                    })
 4982                    .ok();
 4983            })
 4984            .shared(),
 4985        );
 4986        debug_assert!(
 4987            previous_task.is_none(),
 4988            "Did not change hint's resolve state after spawning its resolve"
 4989        );
 4990        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 4991        None
 4992    }
 4993
 4994    fn resolve_inlay_hint(
 4995        &self,
 4996        mut hint: InlayHint,
 4997        buffer: Entity<Buffer>,
 4998        server_id: LanguageServerId,
 4999        cx: &mut Context<Self>,
 5000    ) -> Task<anyhow::Result<InlayHint>> {
 5001        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5002            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 5003            {
 5004                hint.resolve_state = ResolveState::Resolved;
 5005                return Task::ready(Ok(hint));
 5006            }
 5007            let request = proto::ResolveInlayHint {
 5008                project_id,
 5009                buffer_id: buffer.read(cx).remote_id().into(),
 5010                language_server_id: server_id.0 as u64,
 5011                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 5012            };
 5013            cx.background_spawn(async move {
 5014                let response = upstream_client
 5015                    .request(request)
 5016                    .await
 5017                    .context("inlay hints proto request")?;
 5018                match response.hint {
 5019                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5020                        .context("inlay hints proto resolve response conversion"),
 5021                    None => Ok(hint),
 5022                }
 5023            })
 5024        } else {
 5025            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5026                self.language_server_for_local_buffer(buffer, server_id, cx)
 5027                    .map(|(_, server)| server.clone())
 5028            }) else {
 5029                return Task::ready(Ok(hint));
 5030            };
 5031            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5032                return Task::ready(Ok(hint));
 5033            }
 5034            let buffer_snapshot = buffer.read(cx).snapshot();
 5035            cx.spawn(async move |_, cx| {
 5036                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5037                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5038                );
 5039                let resolved_hint = resolve_task
 5040                    .await
 5041                    .into_response()
 5042                    .context("inlay hint resolve LSP request")?;
 5043                let resolved_hint = InlayHints::lsp_to_project_hint(
 5044                    resolved_hint,
 5045                    &buffer,
 5046                    server_id,
 5047                    ResolveState::Resolved,
 5048                    false,
 5049                    cx,
 5050                )
 5051                .await?;
 5052                Ok(resolved_hint)
 5053            })
 5054        }
 5055    }
 5056
 5057    pub fn resolve_color_presentation(
 5058        &mut self,
 5059        mut color: DocumentColor,
 5060        buffer: Entity<Buffer>,
 5061        server_id: LanguageServerId,
 5062        cx: &mut Context<Self>,
 5063    ) -> Task<Result<DocumentColor>> {
 5064        if color.resolved {
 5065            return Task::ready(Ok(color));
 5066        }
 5067
 5068        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5069            let start = color.lsp_range.start;
 5070            let end = color.lsp_range.end;
 5071            let request = proto::GetColorPresentation {
 5072                project_id,
 5073                server_id: server_id.to_proto(),
 5074                buffer_id: buffer.read(cx).remote_id().into(),
 5075                color: Some(proto::ColorInformation {
 5076                    red: color.color.red,
 5077                    green: color.color.green,
 5078                    blue: color.color.blue,
 5079                    alpha: color.color.alpha,
 5080                    lsp_range_start: Some(proto::PointUtf16 {
 5081                        row: start.line,
 5082                        column: start.character,
 5083                    }),
 5084                    lsp_range_end: Some(proto::PointUtf16 {
 5085                        row: end.line,
 5086                        column: end.character,
 5087                    }),
 5088                }),
 5089            };
 5090            cx.background_spawn(async move {
 5091                let response = upstream_client
 5092                    .request(request)
 5093                    .await
 5094                    .context("color presentation proto request")?;
 5095                color.resolved = true;
 5096                color.color_presentations = response
 5097                    .presentations
 5098                    .into_iter()
 5099                    .map(|presentation| ColorPresentation {
 5100                        label: SharedString::from(presentation.label),
 5101                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5102                        additional_text_edits: presentation
 5103                            .additional_text_edits
 5104                            .into_iter()
 5105                            .filter_map(deserialize_lsp_edit)
 5106                            .collect(),
 5107                    })
 5108                    .collect();
 5109                Ok(color)
 5110            })
 5111        } else {
 5112            let path = match buffer
 5113                .update(cx, |buffer, cx| {
 5114                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5115                })
 5116                .context("buffer with the missing path")
 5117            {
 5118                Ok(path) => path,
 5119                Err(e) => return Task::ready(Err(e)),
 5120            };
 5121            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5122                self.language_server_for_local_buffer(buffer, server_id, cx)
 5123                    .map(|(_, server)| server.clone())
 5124            }) else {
 5125                return Task::ready(Ok(color));
 5126            };
 5127            cx.background_spawn(async move {
 5128                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5129                    lsp::ColorPresentationParams {
 5130                        text_document: make_text_document_identifier(&path)?,
 5131                        color: color.color,
 5132                        range: color.lsp_range,
 5133                        work_done_progress_params: Default::default(),
 5134                        partial_result_params: Default::default(),
 5135                    },
 5136                );
 5137                color.color_presentations = resolve_task
 5138                    .await
 5139                    .into_response()
 5140                    .context("color presentation resolve LSP request")?
 5141                    .into_iter()
 5142                    .map(|presentation| ColorPresentation {
 5143                        label: SharedString::from(presentation.label),
 5144                        text_edit: presentation.text_edit,
 5145                        additional_text_edits: presentation
 5146                            .additional_text_edits
 5147                            .unwrap_or_default(),
 5148                    })
 5149                    .collect();
 5150                color.resolved = true;
 5151                Ok(color)
 5152            })
 5153        }
 5154    }
 5155
 5156    pub(crate) fn linked_edits(
 5157        &mut self,
 5158        buffer: &Entity<Buffer>,
 5159        position: Anchor,
 5160        cx: &mut Context<Self>,
 5161    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5162        let snapshot = buffer.read(cx).snapshot();
 5163        let scope = snapshot.language_scope_at(position);
 5164        let Some(server_id) = self
 5165            .as_local()
 5166            .and_then(|local| {
 5167                buffer.update(cx, |buffer, cx| {
 5168                    local
 5169                        .language_servers_for_buffer(buffer, cx)
 5170                        .filter(|(_, server)| {
 5171                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5172                        })
 5173                        .filter(|(adapter, _)| {
 5174                            scope
 5175                                .as_ref()
 5176                                .map(|scope| scope.language_allowed(&adapter.name))
 5177                                .unwrap_or(true)
 5178                        })
 5179                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5180                        .next()
 5181                })
 5182            })
 5183            .or_else(|| {
 5184                self.upstream_client()
 5185                    .is_some()
 5186                    .then_some(LanguageServerToQuery::FirstCapable)
 5187            })
 5188            .filter(|_| {
 5189                maybe!({
 5190                    let language = buffer.read(cx).language_at(position)?;
 5191                    Some(
 5192                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5193                            .linked_edits,
 5194                    )
 5195                }) == Some(true)
 5196            })
 5197        else {
 5198            return Task::ready(Ok(Vec::new()));
 5199        };
 5200
 5201        self.request_lsp(
 5202            buffer.clone(),
 5203            server_id,
 5204            LinkedEditingRange { position },
 5205            cx,
 5206        )
 5207    }
 5208
 5209    fn apply_on_type_formatting(
 5210        &mut self,
 5211        buffer: Entity<Buffer>,
 5212        position: Anchor,
 5213        trigger: String,
 5214        cx: &mut Context<Self>,
 5215    ) -> Task<Result<Option<Transaction>>> {
 5216        if let Some((client, project_id)) = self.upstream_client() {
 5217            if !self.check_if_capable_for_proto_request(
 5218                &buffer,
 5219                |capabilities| {
 5220                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5221                },
 5222                cx,
 5223            ) {
 5224                return Task::ready(Ok(None));
 5225            }
 5226            let request = proto::OnTypeFormatting {
 5227                project_id,
 5228                buffer_id: buffer.read(cx).remote_id().into(),
 5229                position: Some(serialize_anchor(&position)),
 5230                trigger,
 5231                version: serialize_version(&buffer.read(cx).version()),
 5232            };
 5233            cx.background_spawn(async move {
 5234                client
 5235                    .request(request)
 5236                    .await?
 5237                    .transaction
 5238                    .map(language::proto::deserialize_transaction)
 5239                    .transpose()
 5240            })
 5241        } else if let Some(local) = self.as_local_mut() {
 5242            let buffer_id = buffer.read(cx).remote_id();
 5243            local.buffers_being_formatted.insert(buffer_id);
 5244            cx.spawn(async move |this, cx| {
 5245                let _cleanup = defer({
 5246                    let this = this.clone();
 5247                    let mut cx = cx.clone();
 5248                    move || {
 5249                        this.update(&mut cx, |this, _| {
 5250                            if let Some(local) = this.as_local_mut() {
 5251                                local.buffers_being_formatted.remove(&buffer_id);
 5252                            }
 5253                        })
 5254                        .ok();
 5255                    }
 5256                });
 5257
 5258                buffer
 5259                    .update(cx, |buffer, _| {
 5260                        buffer.wait_for_edits(Some(position.timestamp))
 5261                    })?
 5262                    .await?;
 5263                this.update(cx, |this, cx| {
 5264                    let position = position.to_point_utf16(buffer.read(cx));
 5265                    this.on_type_format(buffer, position, trigger, false, cx)
 5266                })?
 5267                .await
 5268            })
 5269        } else {
 5270            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5271        }
 5272    }
 5273
 5274    pub fn on_type_format<T: ToPointUtf16>(
 5275        &mut self,
 5276        buffer: Entity<Buffer>,
 5277        position: T,
 5278        trigger: String,
 5279        push_to_history: bool,
 5280        cx: &mut Context<Self>,
 5281    ) -> Task<Result<Option<Transaction>>> {
 5282        let position = position.to_point_utf16(buffer.read(cx));
 5283        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5284    }
 5285
 5286    fn on_type_format_impl(
 5287        &mut self,
 5288        buffer: Entity<Buffer>,
 5289        position: PointUtf16,
 5290        trigger: String,
 5291        push_to_history: bool,
 5292        cx: &mut Context<Self>,
 5293    ) -> Task<Result<Option<Transaction>>> {
 5294        let options = buffer.update(cx, |buffer, cx| {
 5295            lsp_command::lsp_formatting_options(
 5296                language_settings(
 5297                    buffer.language_at(position).map(|l| l.name()),
 5298                    buffer.file(),
 5299                    cx,
 5300                )
 5301                .as_ref(),
 5302            )
 5303        });
 5304
 5305        cx.spawn(async move |this, cx| {
 5306            if let Some(waiter) =
 5307                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5308            {
 5309                waiter.await?;
 5310            }
 5311            cx.update(|cx| {
 5312                this.update(cx, |this, cx| {
 5313                    this.request_lsp(
 5314                        buffer.clone(),
 5315                        LanguageServerToQuery::FirstCapable,
 5316                        OnTypeFormatting {
 5317                            position,
 5318                            trigger,
 5319                            options,
 5320                            push_to_history,
 5321                        },
 5322                        cx,
 5323                    )
 5324                })
 5325            })??
 5326            .await
 5327        })
 5328    }
 5329
 5330    pub fn definitions(
 5331        &mut self,
 5332        buffer: &Entity<Buffer>,
 5333        position: PointUtf16,
 5334        cx: &mut Context<Self>,
 5335    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5336        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5337            let request = GetDefinitions { position };
 5338            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5339                return Task::ready(Ok(None));
 5340            }
 5341            let request_task = upstream_client.request_lsp(
 5342                project_id,
 5343                None,
 5344                LSP_REQUEST_TIMEOUT,
 5345                cx.background_executor().clone(),
 5346                request.to_proto(project_id, buffer.read(cx)),
 5347            );
 5348            let buffer = buffer.clone();
 5349            cx.spawn(async move |weak_lsp_store, cx| {
 5350                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5351                    return Ok(None);
 5352                };
 5353                let Some(responses) = request_task.await? else {
 5354                    return Ok(None);
 5355                };
 5356                let actions = join_all(responses.payload.into_iter().map(|response| {
 5357                    GetDefinitions { position }.response_from_proto(
 5358                        response.response,
 5359                        lsp_store.clone(),
 5360                        buffer.clone(),
 5361                        cx.clone(),
 5362                    )
 5363                }))
 5364                .await;
 5365
 5366                Ok(Some(
 5367                    actions
 5368                        .into_iter()
 5369                        .collect::<Result<Vec<Vec<_>>>>()?
 5370                        .into_iter()
 5371                        .flatten()
 5372                        .dedup()
 5373                        .collect(),
 5374                ))
 5375            })
 5376        } else {
 5377            let definitions_task = self.request_multiple_lsp_locally(
 5378                buffer,
 5379                Some(position),
 5380                GetDefinitions { position },
 5381                cx,
 5382            );
 5383            cx.background_spawn(async move {
 5384                Ok(Some(
 5385                    definitions_task
 5386                        .await
 5387                        .into_iter()
 5388                        .flat_map(|(_, definitions)| definitions)
 5389                        .dedup()
 5390                        .collect(),
 5391                ))
 5392            })
 5393        }
 5394    }
 5395
 5396    pub fn declarations(
 5397        &mut self,
 5398        buffer: &Entity<Buffer>,
 5399        position: PointUtf16,
 5400        cx: &mut Context<Self>,
 5401    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5402        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5403            let request = GetDeclarations { position };
 5404            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5405                return Task::ready(Ok(None));
 5406            }
 5407            let request_task = upstream_client.request_lsp(
 5408                project_id,
 5409                None,
 5410                LSP_REQUEST_TIMEOUT,
 5411                cx.background_executor().clone(),
 5412                request.to_proto(project_id, buffer.read(cx)),
 5413            );
 5414            let buffer = buffer.clone();
 5415            cx.spawn(async move |weak_lsp_store, cx| {
 5416                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5417                    return Ok(None);
 5418                };
 5419                let Some(responses) = request_task.await? else {
 5420                    return Ok(None);
 5421                };
 5422                let actions = join_all(responses.payload.into_iter().map(|response| {
 5423                    GetDeclarations { position }.response_from_proto(
 5424                        response.response,
 5425                        lsp_store.clone(),
 5426                        buffer.clone(),
 5427                        cx.clone(),
 5428                    )
 5429                }))
 5430                .await;
 5431
 5432                Ok(Some(
 5433                    actions
 5434                        .into_iter()
 5435                        .collect::<Result<Vec<Vec<_>>>>()?
 5436                        .into_iter()
 5437                        .flatten()
 5438                        .dedup()
 5439                        .collect(),
 5440                ))
 5441            })
 5442        } else {
 5443            let declarations_task = self.request_multiple_lsp_locally(
 5444                buffer,
 5445                Some(position),
 5446                GetDeclarations { position },
 5447                cx,
 5448            );
 5449            cx.background_spawn(async move {
 5450                Ok(Some(
 5451                    declarations_task
 5452                        .await
 5453                        .into_iter()
 5454                        .flat_map(|(_, declarations)| declarations)
 5455                        .dedup()
 5456                        .collect(),
 5457                ))
 5458            })
 5459        }
 5460    }
 5461
 5462    pub fn type_definitions(
 5463        &mut self,
 5464        buffer: &Entity<Buffer>,
 5465        position: PointUtf16,
 5466        cx: &mut Context<Self>,
 5467    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5468        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5469            let request = GetTypeDefinitions { position };
 5470            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5471                return Task::ready(Ok(None));
 5472            }
 5473            let request_task = upstream_client.request_lsp(
 5474                project_id,
 5475                None,
 5476                LSP_REQUEST_TIMEOUT,
 5477                cx.background_executor().clone(),
 5478                request.to_proto(project_id, buffer.read(cx)),
 5479            );
 5480            let buffer = buffer.clone();
 5481            cx.spawn(async move |weak_lsp_store, cx| {
 5482                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5483                    return Ok(None);
 5484                };
 5485                let Some(responses) = request_task.await? else {
 5486                    return Ok(None);
 5487                };
 5488                let actions = join_all(responses.payload.into_iter().map(|response| {
 5489                    GetTypeDefinitions { position }.response_from_proto(
 5490                        response.response,
 5491                        lsp_store.clone(),
 5492                        buffer.clone(),
 5493                        cx.clone(),
 5494                    )
 5495                }))
 5496                .await;
 5497
 5498                Ok(Some(
 5499                    actions
 5500                        .into_iter()
 5501                        .collect::<Result<Vec<Vec<_>>>>()?
 5502                        .into_iter()
 5503                        .flatten()
 5504                        .dedup()
 5505                        .collect(),
 5506                ))
 5507            })
 5508        } else {
 5509            let type_definitions_task = self.request_multiple_lsp_locally(
 5510                buffer,
 5511                Some(position),
 5512                GetTypeDefinitions { position },
 5513                cx,
 5514            );
 5515            cx.background_spawn(async move {
 5516                Ok(Some(
 5517                    type_definitions_task
 5518                        .await
 5519                        .into_iter()
 5520                        .flat_map(|(_, type_definitions)| type_definitions)
 5521                        .dedup()
 5522                        .collect(),
 5523                ))
 5524            })
 5525        }
 5526    }
 5527
 5528    pub fn implementations(
 5529        &mut self,
 5530        buffer: &Entity<Buffer>,
 5531        position: PointUtf16,
 5532        cx: &mut Context<Self>,
 5533    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5534        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5535            let request = GetImplementations { position };
 5536            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5537                return Task::ready(Ok(None));
 5538            }
 5539            let request_task = upstream_client.request_lsp(
 5540                project_id,
 5541                None,
 5542                LSP_REQUEST_TIMEOUT,
 5543                cx.background_executor().clone(),
 5544                request.to_proto(project_id, buffer.read(cx)),
 5545            );
 5546            let buffer = buffer.clone();
 5547            cx.spawn(async move |weak_lsp_store, cx| {
 5548                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5549                    return Ok(None);
 5550                };
 5551                let Some(responses) = request_task.await? else {
 5552                    return Ok(None);
 5553                };
 5554                let actions = join_all(responses.payload.into_iter().map(|response| {
 5555                    GetImplementations { position }.response_from_proto(
 5556                        response.response,
 5557                        lsp_store.clone(),
 5558                        buffer.clone(),
 5559                        cx.clone(),
 5560                    )
 5561                }))
 5562                .await;
 5563
 5564                Ok(Some(
 5565                    actions
 5566                        .into_iter()
 5567                        .collect::<Result<Vec<Vec<_>>>>()?
 5568                        .into_iter()
 5569                        .flatten()
 5570                        .dedup()
 5571                        .collect(),
 5572                ))
 5573            })
 5574        } else {
 5575            let implementations_task = self.request_multiple_lsp_locally(
 5576                buffer,
 5577                Some(position),
 5578                GetImplementations { position },
 5579                cx,
 5580            );
 5581            cx.background_spawn(async move {
 5582                Ok(Some(
 5583                    implementations_task
 5584                        .await
 5585                        .into_iter()
 5586                        .flat_map(|(_, implementations)| implementations)
 5587                        .dedup()
 5588                        .collect(),
 5589                ))
 5590            })
 5591        }
 5592    }
 5593
 5594    pub fn references(
 5595        &mut self,
 5596        buffer: &Entity<Buffer>,
 5597        position: PointUtf16,
 5598        cx: &mut Context<Self>,
 5599    ) -> Task<Result<Option<Vec<Location>>>> {
 5600        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5601            let request = GetReferences { position };
 5602            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5603                return Task::ready(Ok(None));
 5604            }
 5605
 5606            let request_task = upstream_client.request_lsp(
 5607                project_id,
 5608                None,
 5609                LSP_REQUEST_TIMEOUT,
 5610                cx.background_executor().clone(),
 5611                request.to_proto(project_id, buffer.read(cx)),
 5612            );
 5613            let buffer = buffer.clone();
 5614            cx.spawn(async move |weak_lsp_store, cx| {
 5615                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5616                    return Ok(None);
 5617                };
 5618                let Some(responses) = request_task.await? else {
 5619                    return Ok(None);
 5620                };
 5621
 5622                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5623                    GetReferences { position }.response_from_proto(
 5624                        lsp_response.response,
 5625                        lsp_store.clone(),
 5626                        buffer.clone(),
 5627                        cx.clone(),
 5628                    )
 5629                }))
 5630                .await
 5631                .into_iter()
 5632                .collect::<Result<Vec<Vec<_>>>>()?
 5633                .into_iter()
 5634                .flatten()
 5635                .dedup()
 5636                .collect();
 5637                Ok(Some(locations))
 5638            })
 5639        } else {
 5640            let references_task = self.request_multiple_lsp_locally(
 5641                buffer,
 5642                Some(position),
 5643                GetReferences { position },
 5644                cx,
 5645            );
 5646            cx.background_spawn(async move {
 5647                Ok(Some(
 5648                    references_task
 5649                        .await
 5650                        .into_iter()
 5651                        .flat_map(|(_, references)| references)
 5652                        .dedup()
 5653                        .collect(),
 5654                ))
 5655            })
 5656        }
 5657    }
 5658
 5659    pub fn code_actions(
 5660        &mut self,
 5661        buffer: &Entity<Buffer>,
 5662        range: Range<Anchor>,
 5663        kinds: Option<Vec<CodeActionKind>>,
 5664        cx: &mut Context<Self>,
 5665    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5666        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5667            let request = GetCodeActions {
 5668                range: range.clone(),
 5669                kinds: kinds.clone(),
 5670            };
 5671            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5672                return Task::ready(Ok(None));
 5673            }
 5674            let request_task = upstream_client.request_lsp(
 5675                project_id,
 5676                None,
 5677                LSP_REQUEST_TIMEOUT,
 5678                cx.background_executor().clone(),
 5679                request.to_proto(project_id, buffer.read(cx)),
 5680            );
 5681            let buffer = buffer.clone();
 5682            cx.spawn(async move |weak_lsp_store, cx| {
 5683                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5684                    return Ok(None);
 5685                };
 5686                let Some(responses) = request_task.await? else {
 5687                    return Ok(None);
 5688                };
 5689                let actions = join_all(responses.payload.into_iter().map(|response| {
 5690                    GetCodeActions {
 5691                        range: range.clone(),
 5692                        kinds: kinds.clone(),
 5693                    }
 5694                    .response_from_proto(
 5695                        response.response,
 5696                        lsp_store.clone(),
 5697                        buffer.clone(),
 5698                        cx.clone(),
 5699                    )
 5700                }))
 5701                .await;
 5702
 5703                Ok(Some(
 5704                    actions
 5705                        .into_iter()
 5706                        .collect::<Result<Vec<Vec<_>>>>()?
 5707                        .into_iter()
 5708                        .flatten()
 5709                        .collect(),
 5710                ))
 5711            })
 5712        } else {
 5713            let all_actions_task = self.request_multiple_lsp_locally(
 5714                buffer,
 5715                Some(range.start),
 5716                GetCodeActions { range, kinds },
 5717                cx,
 5718            );
 5719            cx.background_spawn(async move {
 5720                Ok(Some(
 5721                    all_actions_task
 5722                        .await
 5723                        .into_iter()
 5724                        .flat_map(|(_, actions)| actions)
 5725                        .collect(),
 5726                ))
 5727            })
 5728        }
 5729    }
 5730
 5731    pub fn code_lens_actions(
 5732        &mut self,
 5733        buffer: &Entity<Buffer>,
 5734        cx: &mut Context<Self>,
 5735    ) -> CodeLensTask {
 5736        let version_queried_for = buffer.read(cx).version();
 5737        let buffer_id = buffer.read(cx).remote_id();
 5738        let existing_servers = self.as_local().map(|local| {
 5739            local
 5740                .buffers_opened_in_servers
 5741                .get(&buffer_id)
 5742                .cloned()
 5743                .unwrap_or_default()
 5744        });
 5745
 5746        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 5747            if let Some(cached_lens) = &lsp_data.code_lens {
 5748                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 5749                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 5750                        existing_servers != cached_lens.lens.keys().copied().collect()
 5751                    });
 5752                    if !has_different_servers {
 5753                        return Task::ready(Ok(Some(
 5754                            cached_lens.lens.values().flatten().cloned().collect(),
 5755                        )))
 5756                        .shared();
 5757                    }
 5758                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 5759                    if !version_queried_for.changed_since(updating_for) {
 5760                        return running_update.clone();
 5761                    }
 5762                }
 5763            }
 5764        }
 5765
 5766        let lens_lsp_data = self
 5767            .latest_lsp_data(buffer, cx)
 5768            .code_lens
 5769            .get_or_insert_default();
 5770        let buffer = buffer.clone();
 5771        let query_version_queried_for = version_queried_for.clone();
 5772        let new_task = cx
 5773            .spawn(async move |lsp_store, cx| {
 5774                cx.background_executor()
 5775                    .timer(Duration::from_millis(30))
 5776                    .await;
 5777                let fetched_lens = lsp_store
 5778                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 5779                    .map_err(Arc::new)?
 5780                    .await
 5781                    .context("fetching code lens")
 5782                    .map_err(Arc::new);
 5783                let fetched_lens = match fetched_lens {
 5784                    Ok(fetched_lens) => fetched_lens,
 5785                    Err(e) => {
 5786                        lsp_store
 5787                            .update(cx, |lsp_store, _| {
 5788                                if let Some(lens_lsp_data) = lsp_store
 5789                                    .lsp_data
 5790                                    .get_mut(&buffer_id)
 5791                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 5792                                {
 5793                                    lens_lsp_data.update = None;
 5794                                }
 5795                            })
 5796                            .ok();
 5797                        return Err(e);
 5798                    }
 5799                };
 5800
 5801                lsp_store
 5802                    .update(cx, |lsp_store, _| {
 5803                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 5804                        let code_lens = lsp_data.code_lens.as_mut()?;
 5805                        if let Some(fetched_lens) = fetched_lens {
 5806                            if lsp_data.buffer_version == query_version_queried_for {
 5807                                code_lens.lens.extend(fetched_lens);
 5808                            } else if !lsp_data
 5809                                .buffer_version
 5810                                .changed_since(&query_version_queried_for)
 5811                            {
 5812                                lsp_data.buffer_version = query_version_queried_for;
 5813                                code_lens.lens = fetched_lens;
 5814                            }
 5815                        }
 5816                        code_lens.update = None;
 5817                        Some(code_lens.lens.values().flatten().cloned().collect())
 5818                    })
 5819                    .map_err(Arc::new)
 5820            })
 5821            .shared();
 5822        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 5823        new_task
 5824    }
 5825
 5826    fn fetch_code_lens(
 5827        &mut self,
 5828        buffer: &Entity<Buffer>,
 5829        cx: &mut Context<Self>,
 5830    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 5831        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5832            let request = GetCodeLens;
 5833            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5834                return Task::ready(Ok(None));
 5835            }
 5836            let request_task = upstream_client.request_lsp(
 5837                project_id,
 5838                None,
 5839                LSP_REQUEST_TIMEOUT,
 5840                cx.background_executor().clone(),
 5841                request.to_proto(project_id, buffer.read(cx)),
 5842            );
 5843            let buffer = buffer.clone();
 5844            cx.spawn(async move |weak_lsp_store, cx| {
 5845                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5846                    return Ok(None);
 5847                };
 5848                let Some(responses) = request_task.await? else {
 5849                    return Ok(None);
 5850                };
 5851
 5852                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 5853                    let lsp_store = lsp_store.clone();
 5854                    let buffer = buffer.clone();
 5855                    let cx = cx.clone();
 5856                    async move {
 5857                        (
 5858                            LanguageServerId::from_proto(response.server_id),
 5859                            GetCodeLens
 5860                                .response_from_proto(response.response, lsp_store, buffer, cx)
 5861                                .await,
 5862                        )
 5863                    }
 5864                }))
 5865                .await;
 5866
 5867                let mut has_errors = false;
 5868                let code_lens_actions = code_lens_actions
 5869                    .into_iter()
 5870                    .filter_map(|(server_id, code_lens)| match code_lens {
 5871                        Ok(code_lens) => Some((server_id, code_lens)),
 5872                        Err(e) => {
 5873                            has_errors = true;
 5874                            log::error!("{e:#}");
 5875                            None
 5876                        }
 5877                    })
 5878                    .collect::<HashMap<_, _>>();
 5879                anyhow::ensure!(
 5880                    !has_errors || !code_lens_actions.is_empty(),
 5881                    "Failed to fetch code lens"
 5882                );
 5883                Ok(Some(code_lens_actions))
 5884            })
 5885        } else {
 5886            let code_lens_actions_task =
 5887                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 5888            cx.background_spawn(async move {
 5889                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 5890            })
 5891        }
 5892    }
 5893
 5894    #[inline(never)]
 5895    pub fn completions(
 5896        &self,
 5897        buffer: &Entity<Buffer>,
 5898        position: PointUtf16,
 5899        context: CompletionContext,
 5900        cx: &mut Context<Self>,
 5901    ) -> Task<Result<Vec<CompletionResponse>>> {
 5902        let language_registry = self.languages.clone();
 5903
 5904        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5905            let request = GetCompletions { position, context };
 5906            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5907                return Task::ready(Ok(Vec::new()));
 5908            }
 5909            let task = self.send_lsp_proto_request(
 5910                buffer.clone(),
 5911                upstream_client,
 5912                project_id,
 5913                request,
 5914                cx,
 5915            );
 5916            let language = buffer.read(cx).language().cloned();
 5917
 5918            // In the future, we should provide project guests with the names of LSP adapters,
 5919            // so that they can use the correct LSP adapter when computing labels. For now,
 5920            // guests just use the first LSP adapter associated with the buffer's language.
 5921            let lsp_adapter = language.as_ref().and_then(|language| {
 5922                language_registry
 5923                    .lsp_adapters(&language.name())
 5924                    .first()
 5925                    .cloned()
 5926            });
 5927
 5928            cx.foreground_executor().spawn(async move {
 5929                let completion_response = task.await?;
 5930                let completions = populate_labels_for_completions(
 5931                    completion_response.completions,
 5932                    language,
 5933                    lsp_adapter,
 5934                )
 5935                .await;
 5936                Ok(vec![CompletionResponse {
 5937                    completions,
 5938                    display_options: CompletionDisplayOptions::default(),
 5939                    is_incomplete: completion_response.is_incomplete,
 5940                }])
 5941            })
 5942        } else if let Some(local) = self.as_local() {
 5943            let snapshot = buffer.read(cx).snapshot();
 5944            let offset = position.to_offset(&snapshot);
 5945            let scope = snapshot.language_scope_at(offset);
 5946            let language = snapshot.language().cloned();
 5947            let completion_settings = language_settings(
 5948                language.as_ref().map(|language| language.name()),
 5949                buffer.read(cx).file(),
 5950                cx,
 5951            )
 5952            .completions
 5953            .clone();
 5954            if !completion_settings.lsp {
 5955                return Task::ready(Ok(Vec::new()));
 5956            }
 5957
 5958            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 5959                local
 5960                    .language_servers_for_buffer(buffer, cx)
 5961                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 5962                    .filter(|(adapter, _)| {
 5963                        scope
 5964                            .as_ref()
 5965                            .map(|scope| scope.language_allowed(&adapter.name))
 5966                            .unwrap_or(true)
 5967                    })
 5968                    .map(|(_, server)| server.server_id())
 5969                    .collect()
 5970            });
 5971
 5972            let buffer = buffer.clone();
 5973            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 5974            let lsp_timeout = if lsp_timeout > 0 {
 5975                Some(Duration::from_millis(lsp_timeout))
 5976            } else {
 5977                None
 5978            };
 5979            cx.spawn(async move |this,  cx| {
 5980                let mut tasks = Vec::with_capacity(server_ids.len());
 5981                this.update(cx, |lsp_store, cx| {
 5982                    for server_id in server_ids {
 5983                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 5984                        let lsp_timeout = lsp_timeout
 5985                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 5986                        let mut timeout = cx.background_spawn(async move {
 5987                            match lsp_timeout {
 5988                                Some(lsp_timeout) => {
 5989                                    lsp_timeout.await;
 5990                                    true
 5991                                },
 5992                                None => false,
 5993                            }
 5994                        }).fuse();
 5995                        let mut lsp_request = lsp_store.request_lsp(
 5996                            buffer.clone(),
 5997                            LanguageServerToQuery::Other(server_id),
 5998                            GetCompletions {
 5999                                position,
 6000                                context: context.clone(),
 6001                            },
 6002                            cx,
 6003                        ).fuse();
 6004                        let new_task = cx.background_spawn(async move {
 6005                            select_biased! {
 6006                                response = lsp_request => anyhow::Ok(Some(response?)),
 6007                                timeout_happened = timeout => {
 6008                                    if timeout_happened {
 6009                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6010                                        Ok(None)
 6011                                    } else {
 6012                                        let completions = lsp_request.await?;
 6013                                        Ok(Some(completions))
 6014                                    }
 6015                                },
 6016                            }
 6017                        });
 6018                        tasks.push((lsp_adapter, new_task));
 6019                    }
 6020                })?;
 6021
 6022                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6023                    let completion_response = task.await.ok()??;
 6024                    let completions = populate_labels_for_completions(
 6025                            completion_response.completions,
 6026                            language.clone(),
 6027                            lsp_adapter,
 6028                        )
 6029                        .await;
 6030                    Some(CompletionResponse {
 6031                        completions,
 6032                        display_options: CompletionDisplayOptions::default(),
 6033                        is_incomplete: completion_response.is_incomplete,
 6034                    })
 6035                });
 6036
 6037                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6038
 6039                Ok(responses.into_iter().flatten().collect())
 6040            })
 6041        } else {
 6042            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6043        }
 6044    }
 6045
 6046    pub fn resolve_completions(
 6047        &self,
 6048        buffer: Entity<Buffer>,
 6049        completion_indices: Vec<usize>,
 6050        completions: Rc<RefCell<Box<[Completion]>>>,
 6051        cx: &mut Context<Self>,
 6052    ) -> Task<Result<bool>> {
 6053        let client = self.upstream_client();
 6054        let buffer_id = buffer.read(cx).remote_id();
 6055        let buffer_snapshot = buffer.read(cx).snapshot();
 6056
 6057        if !self.check_if_capable_for_proto_request(
 6058            &buffer,
 6059            GetCompletions::can_resolve_completions,
 6060            cx,
 6061        ) {
 6062            return Task::ready(Ok(false));
 6063        }
 6064        cx.spawn(async move |lsp_store, cx| {
 6065            let mut did_resolve = false;
 6066            if let Some((client, project_id)) = client {
 6067                for completion_index in completion_indices {
 6068                    let server_id = {
 6069                        let completion = &completions.borrow()[completion_index];
 6070                        completion.source.server_id()
 6071                    };
 6072                    if let Some(server_id) = server_id {
 6073                        if Self::resolve_completion_remote(
 6074                            project_id,
 6075                            server_id,
 6076                            buffer_id,
 6077                            completions.clone(),
 6078                            completion_index,
 6079                            client.clone(),
 6080                        )
 6081                        .await
 6082                        .log_err()
 6083                        .is_some()
 6084                        {
 6085                            did_resolve = true;
 6086                        }
 6087                    } else {
 6088                        resolve_word_completion(
 6089                            &buffer_snapshot,
 6090                            &mut completions.borrow_mut()[completion_index],
 6091                        );
 6092                    }
 6093                }
 6094            } else {
 6095                for completion_index in completion_indices {
 6096                    let server_id = {
 6097                        let completion = &completions.borrow()[completion_index];
 6098                        completion.source.server_id()
 6099                    };
 6100                    if let Some(server_id) = server_id {
 6101                        let server_and_adapter = lsp_store
 6102                            .read_with(cx, |lsp_store, _| {
 6103                                let server = lsp_store.language_server_for_id(server_id)?;
 6104                                let adapter =
 6105                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6106                                Some((server, adapter))
 6107                            })
 6108                            .ok()
 6109                            .flatten();
 6110                        let Some((server, adapter)) = server_and_adapter else {
 6111                            continue;
 6112                        };
 6113
 6114                        let resolved = Self::resolve_completion_local(
 6115                            server,
 6116                            completions.clone(),
 6117                            completion_index,
 6118                        )
 6119                        .await
 6120                        .log_err()
 6121                        .is_some();
 6122                        if resolved {
 6123                            Self::regenerate_completion_labels(
 6124                                adapter,
 6125                                &buffer_snapshot,
 6126                                completions.clone(),
 6127                                completion_index,
 6128                            )
 6129                            .await
 6130                            .log_err();
 6131                            did_resolve = true;
 6132                        }
 6133                    } else {
 6134                        resolve_word_completion(
 6135                            &buffer_snapshot,
 6136                            &mut completions.borrow_mut()[completion_index],
 6137                        );
 6138                    }
 6139                }
 6140            }
 6141
 6142            Ok(did_resolve)
 6143        })
 6144    }
 6145
 6146    async fn resolve_completion_local(
 6147        server: Arc<lsp::LanguageServer>,
 6148        completions: Rc<RefCell<Box<[Completion]>>>,
 6149        completion_index: usize,
 6150    ) -> Result<()> {
 6151        let server_id = server.server_id();
 6152        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6153            return Ok(());
 6154        }
 6155
 6156        let request = {
 6157            let completion = &completions.borrow()[completion_index];
 6158            match &completion.source {
 6159                CompletionSource::Lsp {
 6160                    lsp_completion,
 6161                    resolved,
 6162                    server_id: completion_server_id,
 6163                    ..
 6164                } => {
 6165                    if *resolved {
 6166                        return Ok(());
 6167                    }
 6168                    anyhow::ensure!(
 6169                        server_id == *completion_server_id,
 6170                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6171                    );
 6172                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6173                }
 6174                CompletionSource::BufferWord { .. }
 6175                | CompletionSource::Dap { .. }
 6176                | CompletionSource::Custom => {
 6177                    return Ok(());
 6178                }
 6179            }
 6180        };
 6181        let resolved_completion = request
 6182            .await
 6183            .into_response()
 6184            .context("resolve completion")?;
 6185
 6186        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6187        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6188
 6189        let mut completions = completions.borrow_mut();
 6190        let completion = &mut completions[completion_index];
 6191        if let CompletionSource::Lsp {
 6192            lsp_completion,
 6193            resolved,
 6194            server_id: completion_server_id,
 6195            ..
 6196        } = &mut completion.source
 6197        {
 6198            if *resolved {
 6199                return Ok(());
 6200            }
 6201            anyhow::ensure!(
 6202                server_id == *completion_server_id,
 6203                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6204            );
 6205            *lsp_completion = Box::new(resolved_completion);
 6206            *resolved = true;
 6207        }
 6208        Ok(())
 6209    }
 6210
 6211    async fn regenerate_completion_labels(
 6212        adapter: Arc<CachedLspAdapter>,
 6213        snapshot: &BufferSnapshot,
 6214        completions: Rc<RefCell<Box<[Completion]>>>,
 6215        completion_index: usize,
 6216    ) -> Result<()> {
 6217        let completion_item = completions.borrow()[completion_index]
 6218            .source
 6219            .lsp_completion(true)
 6220            .map(Cow::into_owned);
 6221        if let Some(lsp_documentation) = completion_item
 6222            .as_ref()
 6223            .and_then(|completion_item| completion_item.documentation.clone())
 6224        {
 6225            let mut completions = completions.borrow_mut();
 6226            let completion = &mut completions[completion_index];
 6227            completion.documentation = Some(lsp_documentation.into());
 6228        } else {
 6229            let mut completions = completions.borrow_mut();
 6230            let completion = &mut completions[completion_index];
 6231            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6232        }
 6233
 6234        let mut new_label = match completion_item {
 6235            Some(completion_item) => {
 6236                // NB: Zed does not have `details` inside the completion resolve capabilities, but certain language servers violate the spec and do not return `details` immediately, e.g. https://github.com/yioneko/vtsls/issues/213
 6237                // So we have to update the label here anyway...
 6238                let language = snapshot.language();
 6239                match language {
 6240                    Some(language) => {
 6241                        adapter
 6242                            .labels_for_completions(
 6243                                std::slice::from_ref(&completion_item),
 6244                                language,
 6245                            )
 6246                            .await?
 6247                    }
 6248                    None => Vec::new(),
 6249                }
 6250                .pop()
 6251                .flatten()
 6252                .unwrap_or_else(|| {
 6253                    CodeLabel::fallback_for_completion(
 6254                        &completion_item,
 6255                        language.map(|language| language.as_ref()),
 6256                    )
 6257                })
 6258            }
 6259            None => CodeLabel::plain(
 6260                completions.borrow()[completion_index].new_text.clone(),
 6261                None,
 6262            ),
 6263        };
 6264        ensure_uniform_list_compatible_label(&mut new_label);
 6265
 6266        let mut completions = completions.borrow_mut();
 6267        let completion = &mut completions[completion_index];
 6268        if completion.label.filter_text() == new_label.filter_text() {
 6269            completion.label = new_label;
 6270        } else {
 6271            log::error!(
 6272                "Resolved completion changed display label from {} to {}. \
 6273                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6274                completion.label.text(),
 6275                new_label.text(),
 6276                completion.label.filter_text(),
 6277                new_label.filter_text()
 6278            );
 6279        }
 6280
 6281        Ok(())
 6282    }
 6283
 6284    async fn resolve_completion_remote(
 6285        project_id: u64,
 6286        server_id: LanguageServerId,
 6287        buffer_id: BufferId,
 6288        completions: Rc<RefCell<Box<[Completion]>>>,
 6289        completion_index: usize,
 6290        client: AnyProtoClient,
 6291    ) -> Result<()> {
 6292        let lsp_completion = {
 6293            let completion = &completions.borrow()[completion_index];
 6294            match &completion.source {
 6295                CompletionSource::Lsp {
 6296                    lsp_completion,
 6297                    resolved,
 6298                    server_id: completion_server_id,
 6299                    ..
 6300                } => {
 6301                    anyhow::ensure!(
 6302                        server_id == *completion_server_id,
 6303                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6304                    );
 6305                    if *resolved {
 6306                        return Ok(());
 6307                    }
 6308                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6309                }
 6310                CompletionSource::Custom
 6311                | CompletionSource::Dap { .. }
 6312                | CompletionSource::BufferWord { .. } => {
 6313                    return Ok(());
 6314                }
 6315            }
 6316        };
 6317        let request = proto::ResolveCompletionDocumentation {
 6318            project_id,
 6319            language_server_id: server_id.0 as u64,
 6320            lsp_completion,
 6321            buffer_id: buffer_id.into(),
 6322        };
 6323
 6324        let response = client
 6325            .request(request)
 6326            .await
 6327            .context("completion documentation resolve proto request")?;
 6328        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6329
 6330        let documentation = if response.documentation.is_empty() {
 6331            CompletionDocumentation::Undocumented
 6332        } else if response.documentation_is_markdown {
 6333            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6334        } else if response.documentation.lines().count() <= 1 {
 6335            CompletionDocumentation::SingleLine(response.documentation.into())
 6336        } else {
 6337            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6338        };
 6339
 6340        let mut completions = completions.borrow_mut();
 6341        let completion = &mut completions[completion_index];
 6342        completion.documentation = Some(documentation);
 6343        if let CompletionSource::Lsp {
 6344            insert_range,
 6345            lsp_completion,
 6346            resolved,
 6347            server_id: completion_server_id,
 6348            lsp_defaults: _,
 6349        } = &mut completion.source
 6350        {
 6351            let completion_insert_range = response
 6352                .old_insert_start
 6353                .and_then(deserialize_anchor)
 6354                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6355            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6356
 6357            if *resolved {
 6358                return Ok(());
 6359            }
 6360            anyhow::ensure!(
 6361                server_id == *completion_server_id,
 6362                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6363            );
 6364            *lsp_completion = Box::new(resolved_lsp_completion);
 6365            *resolved = true;
 6366        }
 6367
 6368        let replace_range = response
 6369            .old_replace_start
 6370            .and_then(deserialize_anchor)
 6371            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6372        if let Some((old_replace_start, old_replace_end)) = replace_range
 6373            && !response.new_text.is_empty()
 6374        {
 6375            completion.new_text = response.new_text;
 6376            completion.replace_range = old_replace_start..old_replace_end;
 6377        }
 6378
 6379        Ok(())
 6380    }
 6381
 6382    pub fn apply_additional_edits_for_completion(
 6383        &self,
 6384        buffer_handle: Entity<Buffer>,
 6385        completions: Rc<RefCell<Box<[Completion]>>>,
 6386        completion_index: usize,
 6387        push_to_history: bool,
 6388        cx: &mut Context<Self>,
 6389    ) -> Task<Result<Option<Transaction>>> {
 6390        if let Some((client, project_id)) = self.upstream_client() {
 6391            let buffer = buffer_handle.read(cx);
 6392            let buffer_id = buffer.remote_id();
 6393            cx.spawn(async move |_, cx| {
 6394                let request = {
 6395                    let completion = completions.borrow()[completion_index].clone();
 6396                    proto::ApplyCompletionAdditionalEdits {
 6397                        project_id,
 6398                        buffer_id: buffer_id.into(),
 6399                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6400                            replace_range: completion.replace_range,
 6401                            new_text: completion.new_text,
 6402                            source: completion.source,
 6403                        })),
 6404                    }
 6405                };
 6406
 6407                if let Some(transaction) = client.request(request).await?.transaction {
 6408                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6409                    buffer_handle
 6410                        .update(cx, |buffer, _| {
 6411                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6412                        })?
 6413                        .await?;
 6414                    if push_to_history {
 6415                        buffer_handle.update(cx, |buffer, _| {
 6416                            buffer.push_transaction(transaction.clone(), Instant::now());
 6417                            buffer.finalize_last_transaction();
 6418                        })?;
 6419                    }
 6420                    Ok(Some(transaction))
 6421                } else {
 6422                    Ok(None)
 6423                }
 6424            })
 6425        } else {
 6426            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6427                let completion = &completions.borrow()[completion_index];
 6428                let server_id = completion.source.server_id()?;
 6429                Some(
 6430                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6431                        .1
 6432                        .clone(),
 6433                )
 6434            }) else {
 6435                return Task::ready(Ok(None));
 6436            };
 6437
 6438            cx.spawn(async move |this, cx| {
 6439                Self::resolve_completion_local(
 6440                    server.clone(),
 6441                    completions.clone(),
 6442                    completion_index,
 6443                )
 6444                .await
 6445                .context("resolving completion")?;
 6446                let completion = completions.borrow()[completion_index].clone();
 6447                let additional_text_edits = completion
 6448                    .source
 6449                    .lsp_completion(true)
 6450                    .as_ref()
 6451                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6452                if let Some(edits) = additional_text_edits {
 6453                    let edits = this
 6454                        .update(cx, |this, cx| {
 6455                            this.as_local_mut().unwrap().edits_from_lsp(
 6456                                &buffer_handle,
 6457                                edits,
 6458                                server.server_id(),
 6459                                None,
 6460                                cx,
 6461                            )
 6462                        })?
 6463                        .await?;
 6464
 6465                    buffer_handle.update(cx, |buffer, cx| {
 6466                        buffer.finalize_last_transaction();
 6467                        buffer.start_transaction();
 6468
 6469                        for (range, text) in edits {
 6470                            let primary = &completion.replace_range;
 6471
 6472                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6473                            // and the primary completion is just an insertion (empty range), then this is likely
 6474                            // an auto-import scenario and should not be considered overlapping
 6475                            // https://github.com/zed-industries/zed/issues/26136
 6476                            let is_file_start_auto_import = {
 6477                                let snapshot = buffer.snapshot();
 6478                                let primary_start_point = primary.start.to_point(&snapshot);
 6479                                let range_start_point = range.start.to_point(&snapshot);
 6480
 6481                                let result = primary_start_point.row == 0
 6482                                    && primary_start_point.column == 0
 6483                                    && range_start_point.row == 0
 6484                                    && range_start_point.column == 0;
 6485
 6486                                result
 6487                            };
 6488
 6489                            let has_overlap = if is_file_start_auto_import {
 6490                                false
 6491                            } else {
 6492                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6493                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6494                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6495                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6496                                let result = start_within || end_within;
 6497                                result
 6498                            };
 6499
 6500                            //Skip additional edits which overlap with the primary completion edit
 6501                            //https://github.com/zed-industries/zed/pull/1871
 6502                            if !has_overlap {
 6503                                buffer.edit([(range, text)], None, cx);
 6504                            }
 6505                        }
 6506
 6507                        let transaction = if buffer.end_transaction(cx).is_some() {
 6508                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6509                            if !push_to_history {
 6510                                buffer.forget_transaction(transaction.id);
 6511                            }
 6512                            Some(transaction)
 6513                        } else {
 6514                            None
 6515                        };
 6516                        Ok(transaction)
 6517                    })?
 6518                } else {
 6519                    Ok(None)
 6520                }
 6521            })
 6522        }
 6523    }
 6524
 6525    pub fn pull_diagnostics(
 6526        &mut self,
 6527        buffer: Entity<Buffer>,
 6528        cx: &mut Context<Self>,
 6529    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6530        let buffer_id = buffer.read(cx).remote_id();
 6531
 6532        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6533            let mut suitable_capabilities = None;
 6534            // Are we capable for proto request?
 6535            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6536                &buffer,
 6537                |capabilities| {
 6538                    if let Some(caps) = &capabilities.diagnostic_provider {
 6539                        suitable_capabilities = Some(caps.clone());
 6540                        true
 6541                    } else {
 6542                        false
 6543                    }
 6544                },
 6545                cx,
 6546            );
 6547            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6548            let Some(dynamic_caps) = suitable_capabilities else {
 6549                return Task::ready(Ok(None));
 6550            };
 6551            assert!(any_server_has_diagnostics_provider);
 6552
 6553            let request = GetDocumentDiagnostics {
 6554                previous_result_id: None,
 6555                dynamic_caps,
 6556            };
 6557            let request_task = client.request_lsp(
 6558                upstream_project_id,
 6559                None,
 6560                LSP_REQUEST_TIMEOUT,
 6561                cx.background_executor().clone(),
 6562                request.to_proto(upstream_project_id, buffer.read(cx)),
 6563            );
 6564            cx.background_spawn(async move {
 6565                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6566                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6567                // Do not attempt to further process the dummy responses here.
 6568                let _response = request_task.await?;
 6569                Ok(None)
 6570            })
 6571        } else {
 6572            let servers = buffer.update(cx, |buffer, cx| {
 6573                self.language_servers_for_local_buffer(buffer, cx)
 6574                    .map(|(_, server)| server.clone())
 6575                    .collect::<Vec<_>>()
 6576            });
 6577
 6578            let pull_diagnostics = servers
 6579                .into_iter()
 6580                .flat_map(|server| {
 6581                    let result = maybe!({
 6582                        let local = self.as_local()?;
 6583                        let server_id = server.server_id();
 6584                        let providers_with_identifiers = local
 6585                            .language_server_dynamic_registrations
 6586                            .get(&server_id)
 6587                            .into_iter()
 6588                            .flat_map(|registrations| registrations.diagnostics.values().cloned())
 6589                            .collect::<Vec<_>>();
 6590                        Some(
 6591                            providers_with_identifiers
 6592                                .into_iter()
 6593                                .map(|dynamic_caps| {
 6594                                    let result_id = self.result_id(server_id, buffer_id, cx);
 6595                                    self.request_lsp(
 6596                                        buffer.clone(),
 6597                                        LanguageServerToQuery::Other(server_id),
 6598                                        GetDocumentDiagnostics {
 6599                                            previous_result_id: result_id,
 6600                                            dynamic_caps,
 6601                                        },
 6602                                        cx,
 6603                                    )
 6604                                })
 6605                                .collect::<Vec<_>>(),
 6606                        )
 6607                    });
 6608
 6609                    result.unwrap_or_default()
 6610                })
 6611                .collect::<Vec<_>>();
 6612
 6613            cx.background_spawn(async move {
 6614                let mut responses = Vec::new();
 6615                for diagnostics in join_all(pull_diagnostics).await {
 6616                    responses.extend(diagnostics?);
 6617                }
 6618                Ok(Some(responses))
 6619            })
 6620        }
 6621    }
 6622
 6623    pub fn applicable_inlay_chunks(
 6624        &mut self,
 6625        buffer: &Entity<Buffer>,
 6626        ranges: &[Range<text::Anchor>],
 6627        cx: &mut Context<Self>,
 6628    ) -> Vec<Range<BufferRow>> {
 6629        self.latest_lsp_data(buffer, cx)
 6630            .inlay_hints
 6631            .applicable_chunks(ranges)
 6632            .map(|chunk| chunk.start..chunk.end)
 6633            .collect()
 6634    }
 6635
 6636    pub fn invalidate_inlay_hints<'a>(
 6637        &'a mut self,
 6638        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6639    ) {
 6640        for buffer_id in for_buffers {
 6641            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6642                lsp_data.inlay_hints.clear();
 6643            }
 6644        }
 6645    }
 6646
 6647    pub fn inlay_hints(
 6648        &mut self,
 6649        invalidate: InvalidationStrategy,
 6650        buffer: Entity<Buffer>,
 6651        ranges: Vec<Range<text::Anchor>>,
 6652        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6653        cx: &mut Context<Self>,
 6654    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6655        let buffer_snapshot = buffer.read(cx).snapshot();
 6656        let next_hint_id = self.next_hint_id.clone();
 6657        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6658        let mut lsp_refresh_requested = false;
 6659        let for_server = if let InvalidationStrategy::RefreshRequested {
 6660            server_id,
 6661            request_id,
 6662        } = invalidate
 6663        {
 6664            let invalidated = lsp_data
 6665                .inlay_hints
 6666                .invalidate_for_server_refresh(server_id, request_id);
 6667            lsp_refresh_requested = invalidated;
 6668            Some(server_id)
 6669        } else {
 6670            None
 6671        };
 6672        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6673        let known_chunks = known_chunks
 6674            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6675            .map(|(_, known_chunks)| known_chunks)
 6676            .unwrap_or_default();
 6677
 6678        let mut hint_fetch_tasks = Vec::new();
 6679        let mut cached_inlay_hints = None;
 6680        let mut ranges_to_query = None;
 6681        let applicable_chunks = existing_inlay_hints
 6682            .applicable_chunks(ranges.as_slice())
 6683            .filter(|chunk| !known_chunks.contains(&(chunk.start..chunk.end)))
 6684            .collect::<Vec<_>>();
 6685        if applicable_chunks.is_empty() {
 6686            return HashMap::default();
 6687        }
 6688
 6689        let last_chunk_number = existing_inlay_hints.buffer_chunks_len() - 1;
 6690
 6691        for row_chunk in applicable_chunks {
 6692            match (
 6693                existing_inlay_hints
 6694                    .cached_hints(&row_chunk)
 6695                    .filter(|_| !lsp_refresh_requested)
 6696                    .cloned(),
 6697                existing_inlay_hints
 6698                    .fetched_hints(&row_chunk)
 6699                    .as_ref()
 6700                    .filter(|_| !lsp_refresh_requested)
 6701                    .cloned(),
 6702            ) {
 6703                (None, None) => {
 6704                    let end = if last_chunk_number == row_chunk.id {
 6705                        Point::new(row_chunk.end, buffer_snapshot.line_len(row_chunk.end))
 6706                    } else {
 6707                        Point::new(row_chunk.end, 0)
 6708                    };
 6709                    ranges_to_query.get_or_insert_with(Vec::new).push((
 6710                        row_chunk,
 6711                        buffer_snapshot.anchor_before(Point::new(row_chunk.start, 0))
 6712                            ..buffer_snapshot.anchor_after(end),
 6713                    ));
 6714                }
 6715                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 6716                (Some(cached_hints), None) => {
 6717                    for (server_id, cached_hints) in cached_hints {
 6718                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6719                            cached_inlay_hints
 6720                                .get_or_insert_with(HashMap::default)
 6721                                .entry(row_chunk.start..row_chunk.end)
 6722                                .or_insert_with(HashMap::default)
 6723                                .entry(server_id)
 6724                                .or_insert_with(Vec::new)
 6725                                .extend(cached_hints);
 6726                        }
 6727                    }
 6728                }
 6729                (Some(cached_hints), Some(fetched_hints)) => {
 6730                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 6731                    for (server_id, cached_hints) in cached_hints {
 6732                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6733                            cached_inlay_hints
 6734                                .get_or_insert_with(HashMap::default)
 6735                                .entry(row_chunk.start..row_chunk.end)
 6736                                .or_insert_with(HashMap::default)
 6737                                .entry(server_id)
 6738                                .or_insert_with(Vec::new)
 6739                                .extend(cached_hints);
 6740                        }
 6741                    }
 6742                }
 6743            }
 6744        }
 6745
 6746        if hint_fetch_tasks.is_empty()
 6747            && ranges_to_query
 6748                .as_ref()
 6749                .is_none_or(|ranges| ranges.is_empty())
 6750            && let Some(cached_inlay_hints) = cached_inlay_hints
 6751        {
 6752            cached_inlay_hints
 6753                .into_iter()
 6754                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 6755                .collect()
 6756        } else {
 6757            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 6758                let next_hint_id = next_hint_id.clone();
 6759                let buffer = buffer.clone();
 6760                let new_inlay_hints = cx
 6761                    .spawn(async move |lsp_store, cx| {
 6762                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 6763                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 6764                        })?;
 6765                        new_fetch_task
 6766                            .await
 6767                            .and_then(|new_hints_by_server| {
 6768                                lsp_store.update(cx, |lsp_store, cx| {
 6769                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 6770                                    let update_cache = !lsp_data
 6771                                        .buffer_version
 6772                                        .changed_since(&buffer.read(cx).version());
 6773                                    if new_hints_by_server.is_empty() {
 6774                                        if update_cache {
 6775                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 6776                                        }
 6777                                        HashMap::default()
 6778                                    } else {
 6779                                        new_hints_by_server
 6780                                            .into_iter()
 6781                                            .map(|(server_id, new_hints)| {
 6782                                                let new_hints = new_hints
 6783                                                    .into_iter()
 6784                                                    .map(|new_hint| {
 6785                                                        (
 6786                                                            InlayId::Hint(next_hint_id.fetch_add(
 6787                                                                1,
 6788                                                                atomic::Ordering::AcqRel,
 6789                                                            )),
 6790                                                            new_hint,
 6791                                                        )
 6792                                                    })
 6793                                                    .collect::<Vec<_>>();
 6794                                                if update_cache {
 6795                                                    lsp_data.inlay_hints.insert_new_hints(
 6796                                                        chunk,
 6797                                                        server_id,
 6798                                                        new_hints.clone(),
 6799                                                    );
 6800                                                }
 6801                                                (server_id, new_hints)
 6802                                            })
 6803                                            .collect()
 6804                                    }
 6805                                })
 6806                            })
 6807                            .map_err(Arc::new)
 6808                    })
 6809                    .shared();
 6810
 6811                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 6812                *fetch_task = Some(new_inlay_hints.clone());
 6813                hint_fetch_tasks.push((chunk, new_inlay_hints));
 6814            }
 6815
 6816            cached_inlay_hints
 6817                .unwrap_or_default()
 6818                .into_iter()
 6819                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 6820                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 6821                    (
 6822                        chunk.start..chunk.end,
 6823                        cx.spawn(async move |_, _| {
 6824                            hints_fetch.await.map_err(|e| {
 6825                                if e.error_code() != ErrorCode::Internal {
 6826                                    anyhow!(e.error_code())
 6827                                } else {
 6828                                    anyhow!("{e:#}")
 6829                                }
 6830                            })
 6831                        }),
 6832                    )
 6833                }))
 6834                .collect()
 6835        }
 6836    }
 6837
 6838    fn fetch_inlay_hints(
 6839        &mut self,
 6840        for_server: Option<LanguageServerId>,
 6841        buffer: &Entity<Buffer>,
 6842        range: Range<Anchor>,
 6843        cx: &mut Context<Self>,
 6844    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 6845        let request = InlayHints {
 6846            range: range.clone(),
 6847        };
 6848        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6849            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6850                return Task::ready(Ok(HashMap::default()));
 6851            }
 6852            let request_task = upstream_client.request_lsp(
 6853                project_id,
 6854                for_server.map(|id| id.to_proto()),
 6855                LSP_REQUEST_TIMEOUT,
 6856                cx.background_executor().clone(),
 6857                request.to_proto(project_id, buffer.read(cx)),
 6858            );
 6859            let buffer = buffer.clone();
 6860            cx.spawn(async move |weak_lsp_store, cx| {
 6861                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6862                    return Ok(HashMap::default());
 6863                };
 6864                let Some(responses) = request_task.await? else {
 6865                    return Ok(HashMap::default());
 6866                };
 6867
 6868                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 6869                    let lsp_store = lsp_store.clone();
 6870                    let buffer = buffer.clone();
 6871                    let cx = cx.clone();
 6872                    let request = request.clone();
 6873                    async move {
 6874                        (
 6875                            LanguageServerId::from_proto(response.server_id),
 6876                            request
 6877                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6878                                .await,
 6879                        )
 6880                    }
 6881                }))
 6882                .await;
 6883
 6884                let mut has_errors = false;
 6885                let inlay_hints = inlay_hints
 6886                    .into_iter()
 6887                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 6888                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 6889                        Err(e) => {
 6890                            has_errors = true;
 6891                            log::error!("{e:#}");
 6892                            None
 6893                        }
 6894                    })
 6895                    .collect::<HashMap<_, _>>();
 6896                anyhow::ensure!(
 6897                    !has_errors || !inlay_hints.is_empty(),
 6898                    "Failed to fetch inlay hints"
 6899                );
 6900                Ok(inlay_hints)
 6901            })
 6902        } else {
 6903            let inlay_hints_task = match for_server {
 6904                Some(server_id) => {
 6905                    let server_task = self.request_lsp(
 6906                        buffer.clone(),
 6907                        LanguageServerToQuery::Other(server_id),
 6908                        request,
 6909                        cx,
 6910                    );
 6911                    cx.background_spawn(async move {
 6912                        let mut responses = Vec::new();
 6913                        match server_task.await {
 6914                            Ok(response) => responses.push((server_id, response)),
 6915                            // rust-analyzer likes to error with this when its still loading up
 6916                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 6917                            Err(e) => log::error!(
 6918                                "Error handling response for inlay hints request: {e:#}"
 6919                            ),
 6920                        }
 6921                        responses
 6922                    })
 6923                }
 6924                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 6925            };
 6926            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 6927            cx.background_spawn(async move {
 6928                Ok(inlay_hints_task
 6929                    .await
 6930                    .into_iter()
 6931                    .map(|(server_id, mut new_hints)| {
 6932                        new_hints.retain(|hint| {
 6933                            hint.position.is_valid(&buffer_snapshot)
 6934                                && range.start.is_valid(&buffer_snapshot)
 6935                                && range.end.is_valid(&buffer_snapshot)
 6936                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 6937                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 6938                        });
 6939                        (server_id, new_hints)
 6940                    })
 6941                    .collect())
 6942            })
 6943        }
 6944    }
 6945
 6946    pub fn pull_diagnostics_for_buffer(
 6947        &mut self,
 6948        buffer: Entity<Buffer>,
 6949        cx: &mut Context<Self>,
 6950    ) -> Task<anyhow::Result<()>> {
 6951        let diagnostics = self.pull_diagnostics(buffer, cx);
 6952        cx.spawn(async move |lsp_store, cx| {
 6953            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 6954                return Ok(());
 6955            };
 6956            lsp_store.update(cx, |lsp_store, cx| {
 6957                if lsp_store.as_local().is_none() {
 6958                    return;
 6959                }
 6960
 6961                let mut unchanged_buffers = HashSet::default();
 6962                let mut changed_buffers = HashSet::default();
 6963                let server_diagnostics_updates = diagnostics
 6964                    .into_iter()
 6965                    .filter_map(|diagnostics_set| match diagnostics_set {
 6966                        LspPullDiagnostics::Response {
 6967                            server_id,
 6968                            uri,
 6969                            diagnostics,
 6970                        } => Some((server_id, uri, diagnostics)),
 6971                        LspPullDiagnostics::Default => None,
 6972                    })
 6973                    .fold(
 6974                        HashMap::default(),
 6975                        |mut acc, (server_id, uri, diagnostics)| {
 6976                            let (result_id, diagnostics) = match diagnostics {
 6977                                PulledDiagnostics::Unchanged { result_id } => {
 6978                                    unchanged_buffers.insert(uri.clone());
 6979                                    (Some(result_id), Vec::new())
 6980                                }
 6981                                PulledDiagnostics::Changed {
 6982                                    result_id,
 6983                                    diagnostics,
 6984                                } => {
 6985                                    changed_buffers.insert(uri.clone());
 6986                                    (result_id, diagnostics)
 6987                                }
 6988                            };
 6989                            let disk_based_sources = Cow::Owned(
 6990                                lsp_store
 6991                                    .language_server_adapter_for_id(server_id)
 6992                                    .as_ref()
 6993                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 6994                                    .unwrap_or(&[])
 6995                                    .to_vec(),
 6996                            );
 6997                            acc.entry(server_id).or_insert_with(Vec::new).push(
 6998                                DocumentDiagnosticsUpdate {
 6999                                    server_id,
 7000                                    diagnostics: lsp::PublishDiagnosticsParams {
 7001                                        uri,
 7002                                        diagnostics,
 7003                                        version: None,
 7004                                    },
 7005                                    result_id,
 7006                                    disk_based_sources,
 7007                                },
 7008                            );
 7009                            acc
 7010                        },
 7011                    );
 7012
 7013                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7014                    lsp_store
 7015                        .merge_lsp_diagnostics(
 7016                            DiagnosticSourceKind::Pulled,
 7017                            diagnostic_updates,
 7018                            |buffer, old_diagnostic, cx| {
 7019                                File::from_dyn(buffer.file())
 7020                                    .and_then(|file| {
 7021                                        let abs_path = file.as_local()?.abs_path(cx);
 7022                                        lsp::Uri::from_file_path(abs_path).ok()
 7023                                    })
 7024                                    .is_none_or(|buffer_uri| {
 7025                                        unchanged_buffers.contains(&buffer_uri)
 7026                                            || match old_diagnostic.source_kind {
 7027                                                DiagnosticSourceKind::Pulled => {
 7028                                                    !changed_buffers.contains(&buffer_uri)
 7029                                                }
 7030                                                DiagnosticSourceKind::Other
 7031                                                | DiagnosticSourceKind::Pushed => true,
 7032                                            }
 7033                                    })
 7034                            },
 7035                            cx,
 7036                        )
 7037                        .log_err();
 7038                }
 7039            })
 7040        })
 7041    }
 7042
 7043    pub fn document_colors(
 7044        &mut self,
 7045        known_cache_version: Option<usize>,
 7046        buffer: Entity<Buffer>,
 7047        cx: &mut Context<Self>,
 7048    ) -> Option<DocumentColorTask> {
 7049        let version_queried_for = buffer.read(cx).version();
 7050        let buffer_id = buffer.read(cx).remote_id();
 7051
 7052        let current_language_servers = self.as_local().map(|local| {
 7053            local
 7054                .buffers_opened_in_servers
 7055                .get(&buffer_id)
 7056                .cloned()
 7057                .unwrap_or_default()
 7058        });
 7059
 7060        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7061            if let Some(cached_colors) = &lsp_data.document_colors {
 7062                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7063                    let has_different_servers =
 7064                        current_language_servers.is_some_and(|current_language_servers| {
 7065                            current_language_servers
 7066                                != cached_colors.colors.keys().copied().collect()
 7067                        });
 7068                    if !has_different_servers {
 7069                        let cache_version = cached_colors.cache_version;
 7070                        if Some(cache_version) == known_cache_version {
 7071                            return None;
 7072                        } else {
 7073                            return Some(
 7074                                Task::ready(Ok(DocumentColors {
 7075                                    colors: cached_colors
 7076                                        .colors
 7077                                        .values()
 7078                                        .flatten()
 7079                                        .cloned()
 7080                                        .collect(),
 7081                                    cache_version: Some(cache_version),
 7082                                }))
 7083                                .shared(),
 7084                            );
 7085                        }
 7086                    }
 7087                }
 7088            }
 7089        }
 7090
 7091        let color_lsp_data = self
 7092            .latest_lsp_data(&buffer, cx)
 7093            .document_colors
 7094            .get_or_insert_default();
 7095        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7096            && !version_queried_for.changed_since(updating_for)
 7097        {
 7098            return Some(running_update.clone());
 7099        }
 7100        let buffer_version_queried_for = version_queried_for.clone();
 7101        let new_task = cx
 7102            .spawn(async move |lsp_store, cx| {
 7103                cx.background_executor()
 7104                    .timer(Duration::from_millis(30))
 7105                    .await;
 7106                let fetched_colors = lsp_store
 7107                    .update(cx, |lsp_store, cx| {
 7108                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7109                    })?
 7110                    .await
 7111                    .context("fetching document colors")
 7112                    .map_err(Arc::new);
 7113                let fetched_colors = match fetched_colors {
 7114                    Ok(fetched_colors) => {
 7115                        if Some(true)
 7116                            == buffer
 7117                                .update(cx, |buffer, _| {
 7118                                    buffer.version() != buffer_version_queried_for
 7119                                })
 7120                                .ok()
 7121                        {
 7122                            return Ok(DocumentColors::default());
 7123                        }
 7124                        fetched_colors
 7125                    }
 7126                    Err(e) => {
 7127                        lsp_store
 7128                            .update(cx, |lsp_store, _| {
 7129                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7130                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7131                                        document_colors.colors_update = None;
 7132                                    }
 7133                                }
 7134                            })
 7135                            .ok();
 7136                        return Err(e);
 7137                    }
 7138                };
 7139
 7140                lsp_store
 7141                    .update(cx, |lsp_store, cx| {
 7142                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7143                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7144
 7145                        if let Some(fetched_colors) = fetched_colors {
 7146                            if lsp_data.buffer_version == buffer_version_queried_for {
 7147                                lsp_colors.colors.extend(fetched_colors);
 7148                                lsp_colors.cache_version += 1;
 7149                            } else if !lsp_data
 7150                                .buffer_version
 7151                                .changed_since(&buffer_version_queried_for)
 7152                            {
 7153                                lsp_data.buffer_version = buffer_version_queried_for;
 7154                                lsp_colors.colors = fetched_colors;
 7155                                lsp_colors.cache_version += 1;
 7156                            }
 7157                        }
 7158                        lsp_colors.colors_update = None;
 7159                        let colors = lsp_colors
 7160                            .colors
 7161                            .values()
 7162                            .flatten()
 7163                            .cloned()
 7164                            .collect::<HashSet<_>>();
 7165                        DocumentColors {
 7166                            colors,
 7167                            cache_version: Some(lsp_colors.cache_version),
 7168                        }
 7169                    })
 7170                    .map_err(Arc::new)
 7171            })
 7172            .shared();
 7173        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7174        Some(new_task)
 7175    }
 7176
 7177    fn fetch_document_colors_for_buffer(
 7178        &mut self,
 7179        buffer: &Entity<Buffer>,
 7180        cx: &mut Context<Self>,
 7181    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7182        if let Some((client, project_id)) = self.upstream_client() {
 7183            let request = GetDocumentColor {};
 7184            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7185                return Task::ready(Ok(None));
 7186            }
 7187
 7188            let request_task = client.request_lsp(
 7189                project_id,
 7190                None,
 7191                LSP_REQUEST_TIMEOUT,
 7192                cx.background_executor().clone(),
 7193                request.to_proto(project_id, buffer.read(cx)),
 7194            );
 7195            let buffer = buffer.clone();
 7196            cx.spawn(async move |lsp_store, cx| {
 7197                let Some(lsp_store) = lsp_store.upgrade() else {
 7198                    return Ok(None);
 7199                };
 7200                let colors = join_all(
 7201                    request_task
 7202                        .await
 7203                        .log_err()
 7204                        .flatten()
 7205                        .map(|response| response.payload)
 7206                        .unwrap_or_default()
 7207                        .into_iter()
 7208                        .map(|color_response| {
 7209                            let response = request.response_from_proto(
 7210                                color_response.response,
 7211                                lsp_store.clone(),
 7212                                buffer.clone(),
 7213                                cx.clone(),
 7214                            );
 7215                            async move {
 7216                                (
 7217                                    LanguageServerId::from_proto(color_response.server_id),
 7218                                    response.await.log_err().unwrap_or_default(),
 7219                                )
 7220                            }
 7221                        }),
 7222                )
 7223                .await
 7224                .into_iter()
 7225                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7226                    acc.entry(server_id)
 7227                        .or_insert_with(HashSet::default)
 7228                        .extend(colors);
 7229                    acc
 7230                });
 7231                Ok(Some(colors))
 7232            })
 7233        } else {
 7234            let document_colors_task =
 7235                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7236            cx.background_spawn(async move {
 7237                Ok(Some(
 7238                    document_colors_task
 7239                        .await
 7240                        .into_iter()
 7241                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7242                            acc.entry(server_id)
 7243                                .or_insert_with(HashSet::default)
 7244                                .extend(colors);
 7245                            acc
 7246                        })
 7247                        .into_iter()
 7248                        .collect(),
 7249                ))
 7250            })
 7251        }
 7252    }
 7253
 7254    pub fn signature_help<T: ToPointUtf16>(
 7255        &mut self,
 7256        buffer: &Entity<Buffer>,
 7257        position: T,
 7258        cx: &mut Context<Self>,
 7259    ) -> Task<Option<Vec<SignatureHelp>>> {
 7260        let position = position.to_point_utf16(buffer.read(cx));
 7261
 7262        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7263            let request = GetSignatureHelp { position };
 7264            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7265                return Task::ready(None);
 7266            }
 7267            let request_task = client.request_lsp(
 7268                upstream_project_id,
 7269                None,
 7270                LSP_REQUEST_TIMEOUT,
 7271                cx.background_executor().clone(),
 7272                request.to_proto(upstream_project_id, buffer.read(cx)),
 7273            );
 7274            let buffer = buffer.clone();
 7275            cx.spawn(async move |weak_lsp_store, cx| {
 7276                let lsp_store = weak_lsp_store.upgrade()?;
 7277                let signatures = join_all(
 7278                    request_task
 7279                        .await
 7280                        .log_err()
 7281                        .flatten()
 7282                        .map(|response| response.payload)
 7283                        .unwrap_or_default()
 7284                        .into_iter()
 7285                        .map(|response| {
 7286                            let response = GetSignatureHelp { position }.response_from_proto(
 7287                                response.response,
 7288                                lsp_store.clone(),
 7289                                buffer.clone(),
 7290                                cx.clone(),
 7291                            );
 7292                            async move { response.await.log_err().flatten() }
 7293                        }),
 7294                )
 7295                .await
 7296                .into_iter()
 7297                .flatten()
 7298                .collect();
 7299                Some(signatures)
 7300            })
 7301        } else {
 7302            let all_actions_task = self.request_multiple_lsp_locally(
 7303                buffer,
 7304                Some(position),
 7305                GetSignatureHelp { position },
 7306                cx,
 7307            );
 7308            cx.background_spawn(async move {
 7309                Some(
 7310                    all_actions_task
 7311                        .await
 7312                        .into_iter()
 7313                        .flat_map(|(_, actions)| actions)
 7314                        .collect::<Vec<_>>(),
 7315                )
 7316            })
 7317        }
 7318    }
 7319
 7320    pub fn hover(
 7321        &mut self,
 7322        buffer: &Entity<Buffer>,
 7323        position: PointUtf16,
 7324        cx: &mut Context<Self>,
 7325    ) -> Task<Option<Vec<Hover>>> {
 7326        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7327            let request = GetHover { position };
 7328            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7329                return Task::ready(None);
 7330            }
 7331            let request_task = client.request_lsp(
 7332                upstream_project_id,
 7333                None,
 7334                LSP_REQUEST_TIMEOUT,
 7335                cx.background_executor().clone(),
 7336                request.to_proto(upstream_project_id, buffer.read(cx)),
 7337            );
 7338            let buffer = buffer.clone();
 7339            cx.spawn(async move |weak_lsp_store, cx| {
 7340                let lsp_store = weak_lsp_store.upgrade()?;
 7341                let hovers = join_all(
 7342                    request_task
 7343                        .await
 7344                        .log_err()
 7345                        .flatten()
 7346                        .map(|response| response.payload)
 7347                        .unwrap_or_default()
 7348                        .into_iter()
 7349                        .map(|response| {
 7350                            let response = GetHover { position }.response_from_proto(
 7351                                response.response,
 7352                                lsp_store.clone(),
 7353                                buffer.clone(),
 7354                                cx.clone(),
 7355                            );
 7356                            async move {
 7357                                response
 7358                                    .await
 7359                                    .log_err()
 7360                                    .flatten()
 7361                                    .and_then(remove_empty_hover_blocks)
 7362                            }
 7363                        }),
 7364                )
 7365                .await
 7366                .into_iter()
 7367                .flatten()
 7368                .collect();
 7369                Some(hovers)
 7370            })
 7371        } else {
 7372            let all_actions_task = self.request_multiple_lsp_locally(
 7373                buffer,
 7374                Some(position),
 7375                GetHover { position },
 7376                cx,
 7377            );
 7378            cx.background_spawn(async move {
 7379                Some(
 7380                    all_actions_task
 7381                        .await
 7382                        .into_iter()
 7383                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7384                        .collect::<Vec<Hover>>(),
 7385                )
 7386            })
 7387        }
 7388    }
 7389
 7390    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7391        let language_registry = self.languages.clone();
 7392
 7393        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7394            let request = upstream_client.request(proto::GetProjectSymbols {
 7395                project_id: *project_id,
 7396                query: query.to_string(),
 7397            });
 7398            cx.foreground_executor().spawn(async move {
 7399                let response = request.await?;
 7400                let mut symbols = Vec::new();
 7401                let core_symbols = response
 7402                    .symbols
 7403                    .into_iter()
 7404                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7405                    .collect::<Vec<_>>();
 7406                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7407                    .await;
 7408                Ok(symbols)
 7409            })
 7410        } else if let Some(local) = self.as_local() {
 7411            struct WorkspaceSymbolsResult {
 7412                server_id: LanguageServerId,
 7413                lsp_adapter: Arc<CachedLspAdapter>,
 7414                worktree: WeakEntity<Worktree>,
 7415                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7416            }
 7417
 7418            let mut requests = Vec::new();
 7419            let mut requested_servers = BTreeSet::new();
 7420            for (seed, state) in local.language_server_ids.iter() {
 7421                let Some(worktree_handle) = self
 7422                    .worktree_store
 7423                    .read(cx)
 7424                    .worktree_for_id(seed.worktree_id, cx)
 7425                else {
 7426                    continue;
 7427                };
 7428                let worktree = worktree_handle.read(cx);
 7429                if !worktree.is_visible() {
 7430                    continue;
 7431                }
 7432
 7433                if !requested_servers.insert(state.id) {
 7434                    continue;
 7435                }
 7436
 7437                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7438                    Some(LanguageServerState::Running {
 7439                        adapter, server, ..
 7440                    }) => (adapter.clone(), server),
 7441
 7442                    _ => continue,
 7443                };
 7444                let supports_workspace_symbol_request =
 7445                    match server.capabilities().workspace_symbol_provider {
 7446                        Some(OneOf::Left(supported)) => supported,
 7447                        Some(OneOf::Right(_)) => true,
 7448                        None => false,
 7449                    };
 7450                if !supports_workspace_symbol_request {
 7451                    continue;
 7452                }
 7453                let worktree_handle = worktree_handle.clone();
 7454                let server_id = server.server_id();
 7455                requests.push(
 7456                        server
 7457                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7458                                lsp::WorkspaceSymbolParams {
 7459                                    query: query.to_string(),
 7460                                    ..Default::default()
 7461                                },
 7462                            )
 7463                            .map(move |response| {
 7464                                let lsp_symbols = response.into_response()
 7465                                    .context("workspace symbols request")
 7466                                    .log_err()
 7467                                    .flatten()
 7468                                    .map(|symbol_response| match symbol_response {
 7469                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7470                                            flat_responses.into_iter().map(|lsp_symbol| {
 7471                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7472                                            }).collect::<Vec<_>>()
 7473                                        }
 7474                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7475                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7476                                                let location = match lsp_symbol.location {
 7477                                                    OneOf::Left(location) => location,
 7478                                                    OneOf::Right(_) => {
 7479                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7480                                                        return None
 7481                                                    }
 7482                                                };
 7483                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7484                                            }).collect::<Vec<_>>()
 7485                                        }
 7486                                    }).unwrap_or_default();
 7487
 7488                                WorkspaceSymbolsResult {
 7489                                    server_id,
 7490                                    lsp_adapter,
 7491                                    worktree: worktree_handle.downgrade(),
 7492                                    lsp_symbols,
 7493                                }
 7494                            }),
 7495                    );
 7496            }
 7497
 7498            cx.spawn(async move |this, cx| {
 7499                let responses = futures::future::join_all(requests).await;
 7500                let this = match this.upgrade() {
 7501                    Some(this) => this,
 7502                    None => return Ok(Vec::new()),
 7503                };
 7504
 7505                let mut symbols = Vec::new();
 7506                for result in responses {
 7507                    let core_symbols = this.update(cx, |this, cx| {
 7508                        result
 7509                            .lsp_symbols
 7510                            .into_iter()
 7511                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7512                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7513                                let source_worktree = result.worktree.upgrade()?;
 7514                                let source_worktree_id = source_worktree.read(cx).id();
 7515
 7516                                let path = if let Some((tree, rel_path)) =
 7517                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7518                                {
 7519                                    let worktree_id = tree.read(cx).id();
 7520                                    SymbolLocation::InProject(ProjectPath {
 7521                                        worktree_id,
 7522                                        path: rel_path,
 7523                                    })
 7524                                } else {
 7525                                    SymbolLocation::OutsideProject {
 7526                                        signature: this.symbol_signature(&abs_path),
 7527                                        abs_path: abs_path.into(),
 7528                                    }
 7529                                };
 7530
 7531                                Some(CoreSymbol {
 7532                                    source_language_server_id: result.server_id,
 7533                                    language_server_name: result.lsp_adapter.name.clone(),
 7534                                    source_worktree_id,
 7535                                    path,
 7536                                    kind: symbol_kind,
 7537                                    name: symbol_name,
 7538                                    range: range_from_lsp(symbol_location.range),
 7539                                })
 7540                            })
 7541                            .collect()
 7542                    })?;
 7543
 7544                    populate_labels_for_symbols(
 7545                        core_symbols,
 7546                        &language_registry,
 7547                        Some(result.lsp_adapter),
 7548                        &mut symbols,
 7549                    )
 7550                    .await;
 7551                }
 7552
 7553                Ok(symbols)
 7554            })
 7555        } else {
 7556            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7557        }
 7558    }
 7559
 7560    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7561        let mut summary = DiagnosticSummary::default();
 7562        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7563            summary.error_count += path_summary.error_count;
 7564            summary.warning_count += path_summary.warning_count;
 7565        }
 7566        summary
 7567    }
 7568
 7569    /// Returns the diagnostic summary for a specific project path.
 7570    pub fn diagnostic_summary_for_path(
 7571        &self,
 7572        project_path: &ProjectPath,
 7573        _: &App,
 7574    ) -> DiagnosticSummary {
 7575        if let Some(summaries) = self
 7576            .diagnostic_summaries
 7577            .get(&project_path.worktree_id)
 7578            .and_then(|map| map.get(&project_path.path))
 7579        {
 7580            let (error_count, warning_count) = summaries.iter().fold(
 7581                (0, 0),
 7582                |(error_count, warning_count), (_language_server_id, summary)| {
 7583                    (
 7584                        error_count + summary.error_count,
 7585                        warning_count + summary.warning_count,
 7586                    )
 7587                },
 7588            );
 7589
 7590            DiagnosticSummary {
 7591                error_count,
 7592                warning_count,
 7593            }
 7594        } else {
 7595            DiagnosticSummary::default()
 7596        }
 7597    }
 7598
 7599    pub fn diagnostic_summaries<'a>(
 7600        &'a self,
 7601        include_ignored: bool,
 7602        cx: &'a App,
 7603    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7604        self.worktree_store
 7605            .read(cx)
 7606            .visible_worktrees(cx)
 7607            .filter_map(|worktree| {
 7608                let worktree = worktree.read(cx);
 7609                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7610            })
 7611            .flat_map(move |(worktree, summaries)| {
 7612                let worktree_id = worktree.id();
 7613                summaries
 7614                    .iter()
 7615                    .filter(move |(path, _)| {
 7616                        include_ignored
 7617                            || worktree
 7618                                .entry_for_path(path.as_ref())
 7619                                .is_some_and(|entry| !entry.is_ignored)
 7620                    })
 7621                    .flat_map(move |(path, summaries)| {
 7622                        summaries.iter().map(move |(server_id, summary)| {
 7623                            (
 7624                                ProjectPath {
 7625                                    worktree_id,
 7626                                    path: path.clone(),
 7627                                },
 7628                                *server_id,
 7629                                *summary,
 7630                            )
 7631                        })
 7632                    })
 7633            })
 7634    }
 7635
 7636    pub fn on_buffer_edited(
 7637        &mut self,
 7638        buffer: Entity<Buffer>,
 7639        cx: &mut Context<Self>,
 7640    ) -> Option<()> {
 7641        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7642            Some(
 7643                self.as_local()?
 7644                    .language_servers_for_buffer(buffer, cx)
 7645                    .map(|i| i.1.clone())
 7646                    .collect(),
 7647            )
 7648        })?;
 7649
 7650        let buffer = buffer.read(cx);
 7651        let file = File::from_dyn(buffer.file())?;
 7652        let abs_path = file.as_local()?.abs_path(cx);
 7653        let uri = lsp::Uri::from_file_path(abs_path).unwrap();
 7654        let next_snapshot = buffer.text_snapshot();
 7655        for language_server in language_servers {
 7656            let language_server = language_server.clone();
 7657
 7658            let buffer_snapshots = self
 7659                .as_local_mut()
 7660                .unwrap()
 7661                .buffer_snapshots
 7662                .get_mut(&buffer.remote_id())
 7663                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7664            let previous_snapshot = buffer_snapshots.last()?;
 7665
 7666            let build_incremental_change = || {
 7667                buffer
 7668                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7669                        previous_snapshot.snapshot.version(),
 7670                    )
 7671                    .map(|edit| {
 7672                        let edit_start = edit.new.start.0;
 7673                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7674                        let new_text = next_snapshot
 7675                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7676                            .collect();
 7677                        lsp::TextDocumentContentChangeEvent {
 7678                            range: Some(lsp::Range::new(
 7679                                point_to_lsp(edit_start),
 7680                                point_to_lsp(edit_end),
 7681                            )),
 7682                            range_length: None,
 7683                            text: new_text,
 7684                        }
 7685                    })
 7686                    .collect()
 7687            };
 7688
 7689            let document_sync_kind = language_server
 7690                .capabilities()
 7691                .text_document_sync
 7692                .as_ref()
 7693                .and_then(|sync| match sync {
 7694                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7695                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7696                });
 7697
 7698            let content_changes: Vec<_> = match document_sync_kind {
 7699                Some(lsp::TextDocumentSyncKind::FULL) => {
 7700                    vec![lsp::TextDocumentContentChangeEvent {
 7701                        range: None,
 7702                        range_length: None,
 7703                        text: next_snapshot.text(),
 7704                    }]
 7705                }
 7706                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7707                _ => {
 7708                    #[cfg(any(test, feature = "test-support"))]
 7709                    {
 7710                        build_incremental_change()
 7711                    }
 7712
 7713                    #[cfg(not(any(test, feature = "test-support")))]
 7714                    {
 7715                        continue;
 7716                    }
 7717                }
 7718            };
 7719
 7720            let next_version = previous_snapshot.version + 1;
 7721            buffer_snapshots.push(LspBufferSnapshot {
 7722                version: next_version,
 7723                snapshot: next_snapshot.clone(),
 7724            });
 7725
 7726            language_server
 7727                .notify::<lsp::notification::DidChangeTextDocument>(
 7728                    lsp::DidChangeTextDocumentParams {
 7729                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7730                            uri.clone(),
 7731                            next_version,
 7732                        ),
 7733                        content_changes,
 7734                    },
 7735                )
 7736                .ok();
 7737            self.pull_workspace_diagnostics(language_server.server_id());
 7738        }
 7739
 7740        None
 7741    }
 7742
 7743    pub fn on_buffer_saved(
 7744        &mut self,
 7745        buffer: Entity<Buffer>,
 7746        cx: &mut Context<Self>,
 7747    ) -> Option<()> {
 7748        let file = File::from_dyn(buffer.read(cx).file())?;
 7749        let worktree_id = file.worktree_id(cx);
 7750        let abs_path = file.as_local()?.abs_path(cx);
 7751        let text_document = lsp::TextDocumentIdentifier {
 7752            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7753        };
 7754        let local = self.as_local()?;
 7755
 7756        for server in local.language_servers_for_worktree(worktree_id) {
 7757            if let Some(include_text) = include_text(server.as_ref()) {
 7758                let text = if include_text {
 7759                    Some(buffer.read(cx).text())
 7760                } else {
 7761                    None
 7762                };
 7763                server
 7764                    .notify::<lsp::notification::DidSaveTextDocument>(
 7765                        lsp::DidSaveTextDocumentParams {
 7766                            text_document: text_document.clone(),
 7767                            text,
 7768                        },
 7769                    )
 7770                    .ok();
 7771            }
 7772        }
 7773
 7774        let language_servers = buffer.update(cx, |buffer, cx| {
 7775            local.language_server_ids_for_buffer(buffer, cx)
 7776        });
 7777        for language_server_id in language_servers {
 7778            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7779        }
 7780
 7781        None
 7782    }
 7783
 7784    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 7785        maybe!(async move {
 7786            let mut refreshed_servers = HashSet::default();
 7787            let servers = lsp_store
 7788                .update(cx, |lsp_store, cx| {
 7789                    let local = lsp_store.as_local()?;
 7790
 7791                    let servers = local
 7792                        .language_server_ids
 7793                        .iter()
 7794                        .filter_map(|(seed, state)| {
 7795                            let worktree = lsp_store
 7796                                .worktree_store
 7797                                .read(cx)
 7798                                .worktree_for_id(seed.worktree_id, cx);
 7799                            let delegate: Arc<dyn LspAdapterDelegate> =
 7800                                worktree.map(|worktree| {
 7801                                    LocalLspAdapterDelegate::new(
 7802                                        local.languages.clone(),
 7803                                        &local.environment,
 7804                                        cx.weak_entity(),
 7805                                        &worktree,
 7806                                        local.http_client.clone(),
 7807                                        local.fs.clone(),
 7808                                        cx,
 7809                                    )
 7810                                })?;
 7811                            let server_id = state.id;
 7812
 7813                            let states = local.language_servers.get(&server_id)?;
 7814
 7815                            match states {
 7816                                LanguageServerState::Starting { .. } => None,
 7817                                LanguageServerState::Running {
 7818                                    adapter, server, ..
 7819                                } => {
 7820                                    let adapter = adapter.clone();
 7821                                    let server = server.clone();
 7822                                    refreshed_servers.insert(server.name());
 7823                                    let toolchain = seed.toolchain.clone();
 7824                                    Some(cx.spawn(async move |_, cx| {
 7825                                        let settings =
 7826                                            LocalLspStore::workspace_configuration_for_adapter(
 7827                                                adapter.adapter.clone(),
 7828                                                &delegate,
 7829                                                toolchain,
 7830                                                cx,
 7831                                            )
 7832                                            .await
 7833                                            .ok()?;
 7834                                        server
 7835                                            .notify::<lsp::notification::DidChangeConfiguration>(
 7836                                                lsp::DidChangeConfigurationParams { settings },
 7837                                            )
 7838                                            .ok()?;
 7839                                        Some(())
 7840                                    }))
 7841                                }
 7842                            }
 7843                        })
 7844                        .collect::<Vec<_>>();
 7845
 7846                    Some(servers)
 7847                })
 7848                .ok()
 7849                .flatten()?;
 7850
 7851            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 7852            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 7853            // to stop and unregister its language server wrapper.
 7854            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 7855            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 7856            let _: Vec<Option<()>> = join_all(servers).await;
 7857
 7858            Some(())
 7859        })
 7860        .await;
 7861    }
 7862
 7863    fn maintain_workspace_config(
 7864        external_refresh_requests: watch::Receiver<()>,
 7865        cx: &mut Context<Self>,
 7866    ) -> Task<Result<()>> {
 7867        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 7868        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 7869
 7870        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 7871            *settings_changed_tx.borrow_mut() = ();
 7872        });
 7873
 7874        let mut joint_future =
 7875            futures::stream::select(settings_changed_rx, external_refresh_requests);
 7876        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 7877        // - 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).
 7878        // - 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.
 7879        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 7880        // - 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,
 7881        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 7882        cx.spawn(async move |this, cx| {
 7883            while let Some(()) = joint_future.next().await {
 7884                this.update(cx, |this, cx| {
 7885                    this.refresh_server_tree(cx);
 7886                })
 7887                .ok();
 7888
 7889                Self::refresh_workspace_configurations(&this, cx).await;
 7890            }
 7891
 7892            drop(settings_observation);
 7893            anyhow::Ok(())
 7894        })
 7895    }
 7896
 7897    pub fn language_servers_for_local_buffer<'a>(
 7898        &'a self,
 7899        buffer: &Buffer,
 7900        cx: &mut App,
 7901    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7902        let local = self.as_local();
 7903        let language_server_ids = local
 7904            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 7905            .unwrap_or_default();
 7906
 7907        language_server_ids
 7908            .into_iter()
 7909            .filter_map(
 7910                move |server_id| match local?.language_servers.get(&server_id)? {
 7911                    LanguageServerState::Running {
 7912                        adapter, server, ..
 7913                    } => Some((adapter, server)),
 7914                    _ => None,
 7915                },
 7916            )
 7917    }
 7918
 7919    pub fn language_server_for_local_buffer<'a>(
 7920        &'a self,
 7921        buffer: &'a Buffer,
 7922        server_id: LanguageServerId,
 7923        cx: &'a mut App,
 7924    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7925        self.as_local()?
 7926            .language_servers_for_buffer(buffer, cx)
 7927            .find(|(_, s)| s.server_id() == server_id)
 7928    }
 7929
 7930    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 7931        self.diagnostic_summaries.remove(&id_to_remove);
 7932        if let Some(local) = self.as_local_mut() {
 7933            let to_remove = local.remove_worktree(id_to_remove, cx);
 7934            for server in to_remove {
 7935                self.language_server_statuses.remove(&server);
 7936            }
 7937        }
 7938    }
 7939
 7940    pub fn shared(
 7941        &mut self,
 7942        project_id: u64,
 7943        downstream_client: AnyProtoClient,
 7944        _: &mut Context<Self>,
 7945    ) {
 7946        self.downstream_client = Some((downstream_client.clone(), project_id));
 7947
 7948        for (server_id, status) in &self.language_server_statuses {
 7949            if let Some(server) = self.language_server_for_id(*server_id) {
 7950                downstream_client
 7951                    .send(proto::StartLanguageServer {
 7952                        project_id,
 7953                        server: Some(proto::LanguageServer {
 7954                            id: server_id.to_proto(),
 7955                            name: status.name.to_string(),
 7956                            worktree_id: status.worktree.map(|id| id.to_proto()),
 7957                        }),
 7958                        capabilities: serde_json::to_string(&server.capabilities())
 7959                            .expect("serializing server LSP capabilities"),
 7960                    })
 7961                    .log_err();
 7962            }
 7963        }
 7964    }
 7965
 7966    pub fn disconnected_from_host(&mut self) {
 7967        self.downstream_client.take();
 7968    }
 7969
 7970    pub fn disconnected_from_ssh_remote(&mut self) {
 7971        if let LspStoreMode::Remote(RemoteLspStore {
 7972            upstream_client, ..
 7973        }) = &mut self.mode
 7974        {
 7975            upstream_client.take();
 7976        }
 7977    }
 7978
 7979    pub(crate) fn set_language_server_statuses_from_proto(
 7980        &mut self,
 7981        project: WeakEntity<Project>,
 7982        language_servers: Vec<proto::LanguageServer>,
 7983        server_capabilities: Vec<String>,
 7984        cx: &mut Context<Self>,
 7985    ) {
 7986        let lsp_logs = cx
 7987            .try_global::<GlobalLogStore>()
 7988            .map(|lsp_store| lsp_store.0.clone());
 7989
 7990        self.language_server_statuses = language_servers
 7991            .into_iter()
 7992            .zip(server_capabilities)
 7993            .map(|(server, server_capabilities)| {
 7994                let server_id = LanguageServerId(server.id as usize);
 7995                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 7996                    self.lsp_server_capabilities
 7997                        .insert(server_id, server_capabilities);
 7998                }
 7999
 8000                let name = LanguageServerName::from_proto(server.name);
 8001                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8002
 8003                if let Some(lsp_logs) = &lsp_logs {
 8004                    lsp_logs.update(cx, |lsp_logs, cx| {
 8005                        lsp_logs.add_language_server(
 8006                            // Only remote clients get their language servers set from proto
 8007                            LanguageServerKind::Remote {
 8008                                project: project.clone(),
 8009                            },
 8010                            server_id,
 8011                            Some(name.clone()),
 8012                            worktree,
 8013                            None,
 8014                            cx,
 8015                        );
 8016                    });
 8017                }
 8018
 8019                (
 8020                    server_id,
 8021                    LanguageServerStatus {
 8022                        name,
 8023                        pending_work: Default::default(),
 8024                        has_pending_diagnostic_updates: false,
 8025                        progress_tokens: Default::default(),
 8026                        worktree,
 8027                    },
 8028                )
 8029            })
 8030            .collect();
 8031    }
 8032
 8033    #[cfg(test)]
 8034    pub fn update_diagnostic_entries(
 8035        &mut self,
 8036        server_id: LanguageServerId,
 8037        abs_path: PathBuf,
 8038        result_id: Option<String>,
 8039        version: Option<i32>,
 8040        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8041        cx: &mut Context<Self>,
 8042    ) -> anyhow::Result<()> {
 8043        self.merge_diagnostic_entries(
 8044            vec![DocumentDiagnosticsUpdate {
 8045                diagnostics: DocumentDiagnostics {
 8046                    diagnostics,
 8047                    document_abs_path: abs_path,
 8048                    version,
 8049                },
 8050                result_id,
 8051                server_id,
 8052                disk_based_sources: Cow::Borrowed(&[]),
 8053            }],
 8054            |_, _, _| false,
 8055            cx,
 8056        )?;
 8057        Ok(())
 8058    }
 8059
 8060    pub fn merge_diagnostic_entries<'a>(
 8061        &mut self,
 8062        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8063        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
 8064        cx: &mut Context<Self>,
 8065    ) -> anyhow::Result<()> {
 8066        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8067        let mut updated_diagnostics_paths = HashMap::default();
 8068        for mut update in diagnostic_updates {
 8069            let abs_path = &update.diagnostics.document_abs_path;
 8070            let server_id = update.server_id;
 8071            let Some((worktree, relative_path)) =
 8072                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8073            else {
 8074                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8075                return Ok(());
 8076            };
 8077
 8078            let worktree_id = worktree.read(cx).id();
 8079            let project_path = ProjectPath {
 8080                worktree_id,
 8081                path: relative_path,
 8082            };
 8083
 8084            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8085                let snapshot = buffer_handle.read(cx).snapshot();
 8086                let buffer = buffer_handle.read(cx);
 8087                let reused_diagnostics = buffer
 8088                    .buffer_diagnostics(Some(server_id))
 8089                    .iter()
 8090                    .filter(|v| merge(buffer, &v.diagnostic, cx))
 8091                    .map(|v| {
 8092                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8093                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8094                        DiagnosticEntry {
 8095                            range: start..end,
 8096                            diagnostic: v.diagnostic.clone(),
 8097                        }
 8098                    })
 8099                    .collect::<Vec<_>>();
 8100
 8101                self.as_local_mut()
 8102                    .context("cannot merge diagnostics on a remote LspStore")?
 8103                    .update_buffer_diagnostics(
 8104                        &buffer_handle,
 8105                        server_id,
 8106                        update.result_id,
 8107                        update.diagnostics.version,
 8108                        update.diagnostics.diagnostics.clone(),
 8109                        reused_diagnostics.clone(),
 8110                        cx,
 8111                    )?;
 8112
 8113                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8114            }
 8115
 8116            let updated = worktree.update(cx, |worktree, cx| {
 8117                self.update_worktree_diagnostics(
 8118                    worktree.id(),
 8119                    server_id,
 8120                    project_path.path.clone(),
 8121                    update.diagnostics.diagnostics,
 8122                    cx,
 8123                )
 8124            })?;
 8125            match updated {
 8126                ControlFlow::Continue(new_summary) => {
 8127                    if let Some((project_id, new_summary)) = new_summary {
 8128                        match &mut diagnostics_summary {
 8129                            Some(diagnostics_summary) => {
 8130                                diagnostics_summary
 8131                                    .more_summaries
 8132                                    .push(proto::DiagnosticSummary {
 8133                                        path: project_path.path.as_ref().to_proto(),
 8134                                        language_server_id: server_id.0 as u64,
 8135                                        error_count: new_summary.error_count,
 8136                                        warning_count: new_summary.warning_count,
 8137                                    })
 8138                            }
 8139                            None => {
 8140                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8141                                    project_id,
 8142                                    worktree_id: worktree_id.to_proto(),
 8143                                    summary: Some(proto::DiagnosticSummary {
 8144                                        path: project_path.path.as_ref().to_proto(),
 8145                                        language_server_id: server_id.0 as u64,
 8146                                        error_count: new_summary.error_count,
 8147                                        warning_count: new_summary.warning_count,
 8148                                    }),
 8149                                    more_summaries: Vec::new(),
 8150                                })
 8151                            }
 8152                        }
 8153                    }
 8154                    updated_diagnostics_paths
 8155                        .entry(server_id)
 8156                        .or_insert_with(Vec::new)
 8157                        .push(project_path);
 8158                }
 8159                ControlFlow::Break(()) => {}
 8160            }
 8161        }
 8162
 8163        if let Some((diagnostics_summary, (downstream_client, _))) =
 8164            diagnostics_summary.zip(self.downstream_client.as_ref())
 8165        {
 8166            downstream_client.send(diagnostics_summary).log_err();
 8167        }
 8168        for (server_id, paths) in updated_diagnostics_paths {
 8169            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8170        }
 8171        Ok(())
 8172    }
 8173
 8174    fn update_worktree_diagnostics(
 8175        &mut self,
 8176        worktree_id: WorktreeId,
 8177        server_id: LanguageServerId,
 8178        path_in_worktree: Arc<RelPath>,
 8179        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8180        _: &mut Context<Worktree>,
 8181    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8182        let local = match &mut self.mode {
 8183            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8184            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8185        };
 8186
 8187        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8188        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8189        let summaries_by_server_id = summaries_for_tree
 8190            .entry(path_in_worktree.clone())
 8191            .or_default();
 8192
 8193        let old_summary = summaries_by_server_id
 8194            .remove(&server_id)
 8195            .unwrap_or_default();
 8196
 8197        let new_summary = DiagnosticSummary::new(&diagnostics);
 8198        if new_summary.is_empty() {
 8199            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8200            {
 8201                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8202                    diagnostics_by_server_id.remove(ix);
 8203                }
 8204                if diagnostics_by_server_id.is_empty() {
 8205                    diagnostics_for_tree.remove(&path_in_worktree);
 8206                }
 8207            }
 8208        } else {
 8209            summaries_by_server_id.insert(server_id, new_summary);
 8210            let diagnostics_by_server_id = diagnostics_for_tree
 8211                .entry(path_in_worktree.clone())
 8212                .or_default();
 8213            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8214                Ok(ix) => {
 8215                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8216                }
 8217                Err(ix) => {
 8218                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8219                }
 8220            }
 8221        }
 8222
 8223        if !old_summary.is_empty() || !new_summary.is_empty() {
 8224            if let Some((_, project_id)) = &self.downstream_client {
 8225                Ok(ControlFlow::Continue(Some((
 8226                    *project_id,
 8227                    proto::DiagnosticSummary {
 8228                        path: path_in_worktree.to_proto(),
 8229                        language_server_id: server_id.0 as u64,
 8230                        error_count: new_summary.error_count as u32,
 8231                        warning_count: new_summary.warning_count as u32,
 8232                    },
 8233                ))))
 8234            } else {
 8235                Ok(ControlFlow::Continue(None))
 8236            }
 8237        } else {
 8238            Ok(ControlFlow::Break(()))
 8239        }
 8240    }
 8241
 8242    pub fn open_buffer_for_symbol(
 8243        &mut self,
 8244        symbol: &Symbol,
 8245        cx: &mut Context<Self>,
 8246    ) -> Task<Result<Entity<Buffer>>> {
 8247        if let Some((client, project_id)) = self.upstream_client() {
 8248            let request = client.request(proto::OpenBufferForSymbol {
 8249                project_id,
 8250                symbol: Some(Self::serialize_symbol(symbol)),
 8251            });
 8252            cx.spawn(async move |this, cx| {
 8253                let response = request.await?;
 8254                let buffer_id = BufferId::new(response.buffer_id)?;
 8255                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8256                    .await
 8257            })
 8258        } else if let Some(local) = self.as_local() {
 8259            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8260                seed.worktree_id == symbol.source_worktree_id
 8261                    && state.id == symbol.source_language_server_id
 8262                    && symbol.language_server_name == seed.name
 8263            });
 8264            if !is_valid {
 8265                return Task::ready(Err(anyhow!(
 8266                    "language server for worktree and language not found"
 8267                )));
 8268            };
 8269
 8270            let symbol_abs_path = match &symbol.path {
 8271                SymbolLocation::InProject(project_path) => self
 8272                    .worktree_store
 8273                    .read(cx)
 8274                    .absolutize(&project_path, cx)
 8275                    .context("no such worktree"),
 8276                SymbolLocation::OutsideProject {
 8277                    abs_path,
 8278                    signature: _,
 8279                } => Ok(abs_path.to_path_buf()),
 8280            };
 8281            let symbol_abs_path = match symbol_abs_path {
 8282                Ok(abs_path) => abs_path,
 8283                Err(err) => return Task::ready(Err(err)),
 8284            };
 8285            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8286                uri
 8287            } else {
 8288                return Task::ready(Err(anyhow!("invalid symbol path")));
 8289            };
 8290
 8291            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8292        } else {
 8293            Task::ready(Err(anyhow!("no upstream client or local store")))
 8294        }
 8295    }
 8296
 8297    pub(crate) fn open_local_buffer_via_lsp(
 8298        &mut self,
 8299        abs_path: lsp::Uri,
 8300        language_server_id: LanguageServerId,
 8301        cx: &mut Context<Self>,
 8302    ) -> Task<Result<Entity<Buffer>>> {
 8303        cx.spawn(async move |lsp_store, cx| {
 8304            // Escape percent-encoded string.
 8305            let current_scheme = abs_path.scheme().to_owned();
 8306            // Uri is immutable, so we can't modify the scheme
 8307
 8308            let abs_path = abs_path
 8309                .to_file_path()
 8310                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8311            let p = abs_path.clone();
 8312            let yarn_worktree = lsp_store
 8313                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8314                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8315                        cx.spawn(async move |this, cx| {
 8316                            let t = this
 8317                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8318                                .ok()?;
 8319                            t.await
 8320                        })
 8321                    }),
 8322                    None => Task::ready(None),
 8323                })?
 8324                .await;
 8325            let (worktree_root_target, known_relative_path) =
 8326                if let Some((zip_root, relative_path)) = yarn_worktree {
 8327                    (zip_root, Some(relative_path))
 8328                } else {
 8329                    (Arc::<Path>::from(abs_path.as_path()), None)
 8330                };
 8331            let (worktree, relative_path) = if let Some(result) =
 8332                lsp_store.update(cx, |lsp_store, cx| {
 8333                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8334                        worktree_store.find_worktree(&worktree_root_target, cx)
 8335                    })
 8336                })? {
 8337                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8338                (result.0, relative_path)
 8339            } else {
 8340                let worktree = lsp_store
 8341                    .update(cx, |lsp_store, cx| {
 8342                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8343                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8344                        })
 8345                    })?
 8346                    .await?;
 8347                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8348                    lsp_store
 8349                        .update(cx, |lsp_store, cx| {
 8350                            if let Some(local) = lsp_store.as_local_mut() {
 8351                                local.register_language_server_for_invisible_worktree(
 8352                                    &worktree,
 8353                                    language_server_id,
 8354                                    cx,
 8355                                )
 8356                            }
 8357                        })
 8358                        .ok();
 8359                }
 8360                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8361                let relative_path = if let Some(known_path) = known_relative_path {
 8362                    known_path
 8363                } else {
 8364                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8365                        .into_arc()
 8366                };
 8367                (worktree, relative_path)
 8368            };
 8369            let project_path = ProjectPath {
 8370                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8371                path: relative_path,
 8372            };
 8373            lsp_store
 8374                .update(cx, |lsp_store, cx| {
 8375                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8376                        buffer_store.open_buffer(project_path, cx)
 8377                    })
 8378                })?
 8379                .await
 8380        })
 8381    }
 8382
 8383    fn request_multiple_lsp_locally<P, R>(
 8384        &mut self,
 8385        buffer: &Entity<Buffer>,
 8386        position: Option<P>,
 8387        request: R,
 8388        cx: &mut Context<Self>,
 8389    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8390    where
 8391        P: ToOffset,
 8392        R: LspCommand + Clone,
 8393        <R::LspRequest as lsp::request::Request>::Result: Send,
 8394        <R::LspRequest as lsp::request::Request>::Params: Send,
 8395    {
 8396        let Some(local) = self.as_local() else {
 8397            return Task::ready(Vec::new());
 8398        };
 8399
 8400        let snapshot = buffer.read(cx).snapshot();
 8401        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8402
 8403        let server_ids = buffer.update(cx, |buffer, cx| {
 8404            local
 8405                .language_servers_for_buffer(buffer, cx)
 8406                .filter(|(adapter, _)| {
 8407                    scope
 8408                        .as_ref()
 8409                        .map(|scope| scope.language_allowed(&adapter.name))
 8410                        .unwrap_or(true)
 8411                })
 8412                .map(|(_, server)| server.server_id())
 8413                .filter(|server_id| {
 8414                    self.as_local().is_none_or(|local| {
 8415                        local
 8416                            .buffers_opened_in_servers
 8417                            .get(&snapshot.remote_id())
 8418                            .is_some_and(|servers| servers.contains(server_id))
 8419                    })
 8420                })
 8421                .collect::<Vec<_>>()
 8422        });
 8423
 8424        let mut response_results = server_ids
 8425            .into_iter()
 8426            .map(|server_id| {
 8427                let task = self.request_lsp(
 8428                    buffer.clone(),
 8429                    LanguageServerToQuery::Other(server_id),
 8430                    request.clone(),
 8431                    cx,
 8432                );
 8433                async move { (server_id, task.await) }
 8434            })
 8435            .collect::<FuturesUnordered<_>>();
 8436
 8437        cx.background_spawn(async move {
 8438            let mut responses = Vec::with_capacity(response_results.len());
 8439            while let Some((server_id, response_result)) = response_results.next().await {
 8440                match response_result {
 8441                    Ok(response) => responses.push((server_id, response)),
 8442                    // rust-analyzer likes to error with this when its still loading up
 8443                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8444                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8445                }
 8446            }
 8447            responses
 8448        })
 8449    }
 8450
 8451    async fn handle_lsp_command<T: LspCommand>(
 8452        this: Entity<Self>,
 8453        envelope: TypedEnvelope<T::ProtoRequest>,
 8454        mut cx: AsyncApp,
 8455    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8456    where
 8457        <T::LspRequest as lsp::request::Request>::Params: Send,
 8458        <T::LspRequest as lsp::request::Request>::Result: Send,
 8459    {
 8460        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8461        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8462        let buffer_handle = this.update(&mut cx, |this, cx| {
 8463            this.buffer_store.read(cx).get_existing(buffer_id)
 8464        })??;
 8465        let request = T::from_proto(
 8466            envelope.payload,
 8467            this.clone(),
 8468            buffer_handle.clone(),
 8469            cx.clone(),
 8470        )
 8471        .await?;
 8472        let response = this
 8473            .update(&mut cx, |this, cx| {
 8474                this.request_lsp(
 8475                    buffer_handle.clone(),
 8476                    LanguageServerToQuery::FirstCapable,
 8477                    request,
 8478                    cx,
 8479                )
 8480            })?
 8481            .await?;
 8482        this.update(&mut cx, |this, cx| {
 8483            Ok(T::response_to_proto(
 8484                response,
 8485                this,
 8486                sender_id,
 8487                &buffer_handle.read(cx).version(),
 8488                cx,
 8489            ))
 8490        })?
 8491    }
 8492
 8493    async fn handle_lsp_query(
 8494        lsp_store: Entity<Self>,
 8495        envelope: TypedEnvelope<proto::LspQuery>,
 8496        mut cx: AsyncApp,
 8497    ) -> Result<proto::Ack> {
 8498        use proto::lsp_query::Request;
 8499        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8500        let lsp_query = envelope.payload;
 8501        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8502        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8503        match lsp_query.request.context("invalid LSP query request")? {
 8504            Request::GetReferences(get_references) => {
 8505                let position = get_references.position.clone().and_then(deserialize_anchor);
 8506                Self::query_lsp_locally::<GetReferences>(
 8507                    lsp_store,
 8508                    server_id,
 8509                    sender_id,
 8510                    lsp_request_id,
 8511                    get_references,
 8512                    position,
 8513                    &mut cx,
 8514                )
 8515                .await?;
 8516            }
 8517            Request::GetDocumentColor(get_document_color) => {
 8518                Self::query_lsp_locally::<GetDocumentColor>(
 8519                    lsp_store,
 8520                    server_id,
 8521                    sender_id,
 8522                    lsp_request_id,
 8523                    get_document_color,
 8524                    None,
 8525                    &mut cx,
 8526                )
 8527                .await?;
 8528            }
 8529            Request::GetHover(get_hover) => {
 8530                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8531                Self::query_lsp_locally::<GetHover>(
 8532                    lsp_store,
 8533                    server_id,
 8534                    sender_id,
 8535                    lsp_request_id,
 8536                    get_hover,
 8537                    position,
 8538                    &mut cx,
 8539                )
 8540                .await?;
 8541            }
 8542            Request::GetCodeActions(get_code_actions) => {
 8543                Self::query_lsp_locally::<GetCodeActions>(
 8544                    lsp_store,
 8545                    server_id,
 8546                    sender_id,
 8547                    lsp_request_id,
 8548                    get_code_actions,
 8549                    None,
 8550                    &mut cx,
 8551                )
 8552                .await?;
 8553            }
 8554            Request::GetSignatureHelp(get_signature_help) => {
 8555                let position = get_signature_help
 8556                    .position
 8557                    .clone()
 8558                    .and_then(deserialize_anchor);
 8559                Self::query_lsp_locally::<GetSignatureHelp>(
 8560                    lsp_store,
 8561                    server_id,
 8562                    sender_id,
 8563                    lsp_request_id,
 8564                    get_signature_help,
 8565                    position,
 8566                    &mut cx,
 8567                )
 8568                .await?;
 8569            }
 8570            Request::GetCodeLens(get_code_lens) => {
 8571                Self::query_lsp_locally::<GetCodeLens>(
 8572                    lsp_store,
 8573                    server_id,
 8574                    sender_id,
 8575                    lsp_request_id,
 8576                    get_code_lens,
 8577                    None,
 8578                    &mut cx,
 8579                )
 8580                .await?;
 8581            }
 8582            Request::GetDefinition(get_definition) => {
 8583                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8584                Self::query_lsp_locally::<GetDefinitions>(
 8585                    lsp_store,
 8586                    server_id,
 8587                    sender_id,
 8588                    lsp_request_id,
 8589                    get_definition,
 8590                    position,
 8591                    &mut cx,
 8592                )
 8593                .await?;
 8594            }
 8595            Request::GetDeclaration(get_declaration) => {
 8596                let position = get_declaration
 8597                    .position
 8598                    .clone()
 8599                    .and_then(deserialize_anchor);
 8600                Self::query_lsp_locally::<GetDeclarations>(
 8601                    lsp_store,
 8602                    server_id,
 8603                    sender_id,
 8604                    lsp_request_id,
 8605                    get_declaration,
 8606                    position,
 8607                    &mut cx,
 8608                )
 8609                .await?;
 8610            }
 8611            Request::GetTypeDefinition(get_type_definition) => {
 8612                let position = get_type_definition
 8613                    .position
 8614                    .clone()
 8615                    .and_then(deserialize_anchor);
 8616                Self::query_lsp_locally::<GetTypeDefinitions>(
 8617                    lsp_store,
 8618                    server_id,
 8619                    sender_id,
 8620                    lsp_request_id,
 8621                    get_type_definition,
 8622                    position,
 8623                    &mut cx,
 8624                )
 8625                .await?;
 8626            }
 8627            Request::GetImplementation(get_implementation) => {
 8628                let position = get_implementation
 8629                    .position
 8630                    .clone()
 8631                    .and_then(deserialize_anchor);
 8632                Self::query_lsp_locally::<GetImplementations>(
 8633                    lsp_store,
 8634                    server_id,
 8635                    sender_id,
 8636                    lsp_request_id,
 8637                    get_implementation,
 8638                    position,
 8639                    &mut cx,
 8640                )
 8641                .await?;
 8642            }
 8643            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 8644                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 8645                let version = deserialize_version(get_document_diagnostics.buffer_version());
 8646                let buffer = lsp_store.update(&mut cx, |this, cx| {
 8647                    this.buffer_store.read(cx).get_existing(buffer_id)
 8648                })??;
 8649                buffer
 8650                    .update(&mut cx, |buffer, _| {
 8651                        buffer.wait_for_version(version.clone())
 8652                    })?
 8653                    .await?;
 8654                lsp_store.update(&mut cx, |lsp_store, cx| {
 8655                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 8656                    let key = LspKey {
 8657                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 8658                        server_queried: server_id,
 8659                    };
 8660                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 8661                    ) {
 8662                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 8663                            lsp_requests.clear();
 8664                        };
 8665                    }
 8666
 8667                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 8668                    existing_queries.insert(
 8669                        lsp_request_id,
 8670                        cx.spawn(async move |lsp_store, cx| {
 8671                            let diagnostics_pull = lsp_store
 8672                                .update(cx, |lsp_store, cx| {
 8673                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8674                                })
 8675                                .ok();
 8676                            if let Some(diagnostics_pull) = diagnostics_pull {
 8677                                match diagnostics_pull.await {
 8678                                    Ok(()) => {}
 8679                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 8680                                };
 8681                            }
 8682                        }),
 8683                    );
 8684                })?;
 8685            }
 8686            Request::InlayHints(inlay_hints) => {
 8687                let query_start = inlay_hints
 8688                    .start
 8689                    .clone()
 8690                    .and_then(deserialize_anchor)
 8691                    .context("invalid inlay hints range start")?;
 8692                let query_end = inlay_hints
 8693                    .end
 8694                    .clone()
 8695                    .and_then(deserialize_anchor)
 8696                    .context("invalid inlay hints range end")?;
 8697                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 8698                    &lsp_store,
 8699                    server_id,
 8700                    lsp_request_id,
 8701                    &inlay_hints,
 8702                    query_start..query_end,
 8703                    &mut cx,
 8704                )
 8705                .await
 8706                .context("preparing inlay hints request")?;
 8707                Self::query_lsp_locally::<InlayHints>(
 8708                    lsp_store,
 8709                    server_id,
 8710                    sender_id,
 8711                    lsp_request_id,
 8712                    inlay_hints,
 8713                    None,
 8714                    &mut cx,
 8715                )
 8716                .await
 8717                .context("querying for inlay hints")?
 8718            }
 8719        }
 8720        Ok(proto::Ack {})
 8721    }
 8722
 8723    async fn handle_lsp_query_response(
 8724        lsp_store: Entity<Self>,
 8725        envelope: TypedEnvelope<proto::LspQueryResponse>,
 8726        cx: AsyncApp,
 8727    ) -> Result<()> {
 8728        lsp_store.read_with(&cx, |lsp_store, _| {
 8729            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 8730                upstream_client.handle_lsp_response(envelope.clone());
 8731            }
 8732        })?;
 8733        Ok(())
 8734    }
 8735
 8736    async fn handle_apply_code_action(
 8737        this: Entity<Self>,
 8738        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 8739        mut cx: AsyncApp,
 8740    ) -> Result<proto::ApplyCodeActionResponse> {
 8741        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8742        let action =
 8743            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 8744        let apply_code_action = this.update(&mut cx, |this, cx| {
 8745            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8746            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 8747            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 8748        })??;
 8749
 8750        let project_transaction = apply_code_action.await?;
 8751        let project_transaction = this.update(&mut cx, |this, cx| {
 8752            this.buffer_store.update(cx, |buffer_store, cx| {
 8753                buffer_store.serialize_project_transaction_for_peer(
 8754                    project_transaction,
 8755                    sender_id,
 8756                    cx,
 8757                )
 8758            })
 8759        })?;
 8760        Ok(proto::ApplyCodeActionResponse {
 8761            transaction: Some(project_transaction),
 8762        })
 8763    }
 8764
 8765    async fn handle_register_buffer_with_language_servers(
 8766        this: Entity<Self>,
 8767        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 8768        mut cx: AsyncApp,
 8769    ) -> Result<proto::Ack> {
 8770        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8771        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 8772        this.update(&mut cx, |this, cx| {
 8773            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 8774                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 8775                    project_id: upstream_project_id,
 8776                    buffer_id: buffer_id.to_proto(),
 8777                    only_servers: envelope.payload.only_servers,
 8778                });
 8779            }
 8780
 8781            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 8782                anyhow::bail!("buffer is not open");
 8783            };
 8784
 8785            let handle = this.register_buffer_with_language_servers(
 8786                &buffer,
 8787                envelope
 8788                    .payload
 8789                    .only_servers
 8790                    .into_iter()
 8791                    .filter_map(|selector| {
 8792                        Some(match selector.selector? {
 8793                            proto::language_server_selector::Selector::ServerId(server_id) => {
 8794                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 8795                            }
 8796                            proto::language_server_selector::Selector::Name(name) => {
 8797                                LanguageServerSelector::Name(LanguageServerName(
 8798                                    SharedString::from(name),
 8799                                ))
 8800                            }
 8801                        })
 8802                    })
 8803                    .collect(),
 8804                false,
 8805                cx,
 8806            );
 8807            this.buffer_store().update(cx, |buffer_store, _| {
 8808                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 8809            });
 8810
 8811            Ok(())
 8812        })??;
 8813        Ok(proto::Ack {})
 8814    }
 8815
 8816    async fn handle_rename_project_entry(
 8817        this: Entity<Self>,
 8818        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 8819        mut cx: AsyncApp,
 8820    ) -> Result<proto::ProjectEntryResponse> {
 8821        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 8822        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 8823        let new_path =
 8824            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 8825
 8826        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 8827            .update(&mut cx, |this, cx| {
 8828                let (worktree, entry) = this
 8829                    .worktree_store
 8830                    .read(cx)
 8831                    .worktree_and_entry_for_id(entry_id, cx)?;
 8832                let new_worktree = this
 8833                    .worktree_store
 8834                    .read(cx)
 8835                    .worktree_for_id(new_worktree_id, cx)?;
 8836                Some((
 8837                    this.worktree_store.clone(),
 8838                    worktree,
 8839                    new_worktree,
 8840                    entry.clone(),
 8841                ))
 8842            })?
 8843            .context("worktree not found")?;
 8844        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 8845            (worktree.absolutize(&old_entry.path), worktree.id())
 8846        })?;
 8847        let new_abs_path =
 8848            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 8849
 8850        let _transaction = Self::will_rename_entry(
 8851            this.downgrade(),
 8852            old_worktree_id,
 8853            &old_abs_path,
 8854            &new_abs_path,
 8855            old_entry.is_dir(),
 8856            cx.clone(),
 8857        )
 8858        .await;
 8859        let response = WorktreeStore::handle_rename_project_entry(
 8860            worktree_store,
 8861            envelope.payload,
 8862            cx.clone(),
 8863        )
 8864        .await;
 8865        this.read_with(&cx, |this, _| {
 8866            this.did_rename_entry(
 8867                old_worktree_id,
 8868                &old_abs_path,
 8869                &new_abs_path,
 8870                old_entry.is_dir(),
 8871            );
 8872        })
 8873        .ok();
 8874        response
 8875    }
 8876
 8877    async fn handle_update_diagnostic_summary(
 8878        this: Entity<Self>,
 8879        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 8880        mut cx: AsyncApp,
 8881    ) -> Result<()> {
 8882        this.update(&mut cx, |lsp_store, cx| {
 8883            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 8884            let mut updated_diagnostics_paths = HashMap::default();
 8885            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8886            for message_summary in envelope
 8887                .payload
 8888                .summary
 8889                .into_iter()
 8890                .chain(envelope.payload.more_summaries)
 8891            {
 8892                let project_path = ProjectPath {
 8893                    worktree_id,
 8894                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 8895                };
 8896                let path = project_path.path.clone();
 8897                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 8898                let summary = DiagnosticSummary {
 8899                    error_count: message_summary.error_count as usize,
 8900                    warning_count: message_summary.warning_count as usize,
 8901                };
 8902
 8903                if summary.is_empty() {
 8904                    if let Some(worktree_summaries) =
 8905                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 8906                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 8907                    {
 8908                        summaries.remove(&server_id);
 8909                        if summaries.is_empty() {
 8910                            worktree_summaries.remove(&path);
 8911                        }
 8912                    }
 8913                } else {
 8914                    lsp_store
 8915                        .diagnostic_summaries
 8916                        .entry(worktree_id)
 8917                        .or_default()
 8918                        .entry(path)
 8919                        .or_default()
 8920                        .insert(server_id, summary);
 8921                }
 8922
 8923                if let Some((_, project_id)) = &lsp_store.downstream_client {
 8924                    match &mut diagnostics_summary {
 8925                        Some(diagnostics_summary) => {
 8926                            diagnostics_summary
 8927                                .more_summaries
 8928                                .push(proto::DiagnosticSummary {
 8929                                    path: project_path.path.as_ref().to_proto(),
 8930                                    language_server_id: server_id.0 as u64,
 8931                                    error_count: summary.error_count as u32,
 8932                                    warning_count: summary.warning_count as u32,
 8933                                })
 8934                        }
 8935                        None => {
 8936                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8937                                project_id: *project_id,
 8938                                worktree_id: worktree_id.to_proto(),
 8939                                summary: Some(proto::DiagnosticSummary {
 8940                                    path: project_path.path.as_ref().to_proto(),
 8941                                    language_server_id: server_id.0 as u64,
 8942                                    error_count: summary.error_count as u32,
 8943                                    warning_count: summary.warning_count as u32,
 8944                                }),
 8945                                more_summaries: Vec::new(),
 8946                            })
 8947                        }
 8948                    }
 8949                }
 8950                updated_diagnostics_paths
 8951                    .entry(server_id)
 8952                    .or_insert_with(Vec::new)
 8953                    .push(project_path);
 8954            }
 8955
 8956            if let Some((diagnostics_summary, (downstream_client, _))) =
 8957                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 8958            {
 8959                downstream_client.send(diagnostics_summary).log_err();
 8960            }
 8961            for (server_id, paths) in updated_diagnostics_paths {
 8962                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8963            }
 8964            Ok(())
 8965        })?
 8966    }
 8967
 8968    async fn handle_start_language_server(
 8969        lsp_store: Entity<Self>,
 8970        envelope: TypedEnvelope<proto::StartLanguageServer>,
 8971        mut cx: AsyncApp,
 8972    ) -> Result<()> {
 8973        let server = envelope.payload.server.context("invalid server")?;
 8974        let server_capabilities =
 8975            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 8976                .with_context(|| {
 8977                    format!(
 8978                        "incorrect server capabilities {}",
 8979                        envelope.payload.capabilities
 8980                    )
 8981                })?;
 8982        lsp_store.update(&mut cx, |lsp_store, cx| {
 8983            let server_id = LanguageServerId(server.id as usize);
 8984            let server_name = LanguageServerName::from_proto(server.name.clone());
 8985            lsp_store
 8986                .lsp_server_capabilities
 8987                .insert(server_id, server_capabilities);
 8988            lsp_store.language_server_statuses.insert(
 8989                server_id,
 8990                LanguageServerStatus {
 8991                    name: server_name.clone(),
 8992                    pending_work: Default::default(),
 8993                    has_pending_diagnostic_updates: false,
 8994                    progress_tokens: Default::default(),
 8995                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 8996                },
 8997            );
 8998            cx.emit(LspStoreEvent::LanguageServerAdded(
 8999                server_id,
 9000                server_name,
 9001                server.worktree_id.map(WorktreeId::from_proto),
 9002            ));
 9003            cx.notify();
 9004        })?;
 9005        Ok(())
 9006    }
 9007
 9008    async fn handle_update_language_server(
 9009        lsp_store: Entity<Self>,
 9010        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9011        mut cx: AsyncApp,
 9012    ) -> Result<()> {
 9013        lsp_store.update(&mut cx, |lsp_store, cx| {
 9014            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9015
 9016            match envelope.payload.variant.context("invalid variant")? {
 9017                proto::update_language_server::Variant::WorkStart(payload) => {
 9018                    lsp_store.on_lsp_work_start(
 9019                        language_server_id,
 9020                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9021                            .context("invalid progress token value")?,
 9022                        LanguageServerProgress {
 9023                            title: payload.title,
 9024                            is_disk_based_diagnostics_progress: false,
 9025                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9026                            message: payload.message,
 9027                            percentage: payload.percentage.map(|p| p as usize),
 9028                            last_update_at: cx.background_executor().now(),
 9029                        },
 9030                        cx,
 9031                    );
 9032                }
 9033                proto::update_language_server::Variant::WorkProgress(payload) => {
 9034                    lsp_store.on_lsp_work_progress(
 9035                        language_server_id,
 9036                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9037                            .context("invalid progress token value")?,
 9038                        LanguageServerProgress {
 9039                            title: None,
 9040                            is_disk_based_diagnostics_progress: false,
 9041                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9042                            message: payload.message,
 9043                            percentage: payload.percentage.map(|p| p as usize),
 9044                            last_update_at: cx.background_executor().now(),
 9045                        },
 9046                        cx,
 9047                    );
 9048                }
 9049
 9050                proto::update_language_server::Variant::WorkEnd(payload) => {
 9051                    lsp_store.on_lsp_work_end(
 9052                        language_server_id,
 9053                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9054                            .context("invalid progress token value")?,
 9055                        cx,
 9056                    );
 9057                }
 9058
 9059                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9060                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9061                }
 9062
 9063                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9064                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9065                }
 9066
 9067                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9068                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9069                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9070                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9071                        language_server_id,
 9072                        name: envelope
 9073                            .payload
 9074                            .server_name
 9075                            .map(SharedString::new)
 9076                            .map(LanguageServerName),
 9077                        message: non_lsp,
 9078                    });
 9079                }
 9080            }
 9081
 9082            Ok(())
 9083        })?
 9084    }
 9085
 9086    async fn handle_language_server_log(
 9087        this: Entity<Self>,
 9088        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9089        mut cx: AsyncApp,
 9090    ) -> Result<()> {
 9091        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9092        let log_type = envelope
 9093            .payload
 9094            .log_type
 9095            .map(LanguageServerLogType::from_proto)
 9096            .context("invalid language server log type")?;
 9097
 9098        let message = envelope.payload.message;
 9099
 9100        this.update(&mut cx, |_, cx| {
 9101            cx.emit(LspStoreEvent::LanguageServerLog(
 9102                language_server_id,
 9103                log_type,
 9104                message,
 9105            ));
 9106        })
 9107    }
 9108
 9109    async fn handle_lsp_ext_cancel_flycheck(
 9110        lsp_store: Entity<Self>,
 9111        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9112        cx: AsyncApp,
 9113    ) -> Result<proto::Ack> {
 9114        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9115        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9116            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9117                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9118            } else {
 9119                None
 9120            }
 9121        })?;
 9122        if let Some(task) = task {
 9123            task.context("handling lsp ext cancel flycheck")?;
 9124        }
 9125
 9126        Ok(proto::Ack {})
 9127    }
 9128
 9129    async fn handle_lsp_ext_run_flycheck(
 9130        lsp_store: Entity<Self>,
 9131        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9132        mut cx: AsyncApp,
 9133    ) -> Result<proto::Ack> {
 9134        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9135        lsp_store.update(&mut cx, |lsp_store, cx| {
 9136            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9137                let text_document = if envelope.payload.current_file_only {
 9138                    let buffer_id = envelope
 9139                        .payload
 9140                        .buffer_id
 9141                        .map(|id| BufferId::new(id))
 9142                        .transpose()?;
 9143                    buffer_id
 9144                        .and_then(|buffer_id| {
 9145                            lsp_store
 9146                                .buffer_store()
 9147                                .read(cx)
 9148                                .get(buffer_id)
 9149                                .and_then(|buffer| {
 9150                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9151                                })
 9152                                .map(|path| make_text_document_identifier(&path))
 9153                        })
 9154                        .transpose()?
 9155                } else {
 9156                    None
 9157                };
 9158                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9159                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9160                )?;
 9161            }
 9162            anyhow::Ok(())
 9163        })??;
 9164
 9165        Ok(proto::Ack {})
 9166    }
 9167
 9168    async fn handle_lsp_ext_clear_flycheck(
 9169        lsp_store: Entity<Self>,
 9170        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9171        cx: AsyncApp,
 9172    ) -> Result<proto::Ack> {
 9173        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9174        lsp_store
 9175            .read_with(&cx, |lsp_store, _| {
 9176                if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9177                    Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9178                } else {
 9179                    None
 9180                }
 9181            })
 9182            .context("handling lsp ext clear flycheck")?;
 9183
 9184        Ok(proto::Ack {})
 9185    }
 9186
 9187    pub fn disk_based_diagnostics_started(
 9188        &mut self,
 9189        language_server_id: LanguageServerId,
 9190        cx: &mut Context<Self>,
 9191    ) {
 9192        if let Some(language_server_status) =
 9193            self.language_server_statuses.get_mut(&language_server_id)
 9194        {
 9195            language_server_status.has_pending_diagnostic_updates = true;
 9196        }
 9197
 9198        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9199        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9200            language_server_id,
 9201            name: self
 9202                .language_server_adapter_for_id(language_server_id)
 9203                .map(|adapter| adapter.name()),
 9204            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9205                Default::default(),
 9206            ),
 9207        })
 9208    }
 9209
 9210    pub fn disk_based_diagnostics_finished(
 9211        &mut self,
 9212        language_server_id: LanguageServerId,
 9213        cx: &mut Context<Self>,
 9214    ) {
 9215        if let Some(language_server_status) =
 9216            self.language_server_statuses.get_mut(&language_server_id)
 9217        {
 9218            language_server_status.has_pending_diagnostic_updates = false;
 9219        }
 9220
 9221        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9222        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9223            language_server_id,
 9224            name: self
 9225                .language_server_adapter_for_id(language_server_id)
 9226                .map(|adapter| adapter.name()),
 9227            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9228                Default::default(),
 9229            ),
 9230        })
 9231    }
 9232
 9233    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9234    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9235    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9236    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9237    // the language server might take some time to publish diagnostics.
 9238    fn simulate_disk_based_diagnostics_events_if_needed(
 9239        &mut self,
 9240        language_server_id: LanguageServerId,
 9241        cx: &mut Context<Self>,
 9242    ) {
 9243        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9244
 9245        let Some(LanguageServerState::Running {
 9246            simulate_disk_based_diagnostics_completion,
 9247            adapter,
 9248            ..
 9249        }) = self
 9250            .as_local_mut()
 9251            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9252        else {
 9253            return;
 9254        };
 9255
 9256        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9257            return;
 9258        }
 9259
 9260        let prev_task =
 9261            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9262                cx.background_executor()
 9263                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9264                    .await;
 9265
 9266                this.update(cx, |this, cx| {
 9267                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9268
 9269                    if let Some(LanguageServerState::Running {
 9270                        simulate_disk_based_diagnostics_completion,
 9271                        ..
 9272                    }) = this.as_local_mut().and_then(|local_store| {
 9273                        local_store.language_servers.get_mut(&language_server_id)
 9274                    }) {
 9275                        *simulate_disk_based_diagnostics_completion = None;
 9276                    }
 9277                })
 9278                .ok();
 9279            }));
 9280
 9281        if prev_task.is_none() {
 9282            self.disk_based_diagnostics_started(language_server_id, cx);
 9283        }
 9284    }
 9285
 9286    pub fn language_server_statuses(
 9287        &self,
 9288    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9289        self.language_server_statuses
 9290            .iter()
 9291            .map(|(key, value)| (*key, value))
 9292    }
 9293
 9294    pub(super) fn did_rename_entry(
 9295        &self,
 9296        worktree_id: WorktreeId,
 9297        old_path: &Path,
 9298        new_path: &Path,
 9299        is_dir: bool,
 9300    ) {
 9301        maybe!({
 9302            let local_store = self.as_local()?;
 9303
 9304            let old_uri = lsp::Uri::from_file_path(old_path)
 9305                .ok()
 9306                .map(|uri| uri.to_string())?;
 9307            let new_uri = lsp::Uri::from_file_path(new_path)
 9308                .ok()
 9309                .map(|uri| uri.to_string())?;
 9310
 9311            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9312                let Some(filter) = local_store
 9313                    .language_server_paths_watched_for_rename
 9314                    .get(&language_server.server_id())
 9315                else {
 9316                    continue;
 9317                };
 9318
 9319                if filter.should_send_did_rename(&old_uri, is_dir) {
 9320                    language_server
 9321                        .notify::<DidRenameFiles>(RenameFilesParams {
 9322                            files: vec![FileRename {
 9323                                old_uri: old_uri.clone(),
 9324                                new_uri: new_uri.clone(),
 9325                            }],
 9326                        })
 9327                        .ok();
 9328                }
 9329            }
 9330            Some(())
 9331        });
 9332    }
 9333
 9334    pub(super) fn will_rename_entry(
 9335        this: WeakEntity<Self>,
 9336        worktree_id: WorktreeId,
 9337        old_path: &Path,
 9338        new_path: &Path,
 9339        is_dir: bool,
 9340        cx: AsyncApp,
 9341    ) -> Task<ProjectTransaction> {
 9342        let old_uri = lsp::Uri::from_file_path(old_path)
 9343            .ok()
 9344            .map(|uri| uri.to_string());
 9345        let new_uri = lsp::Uri::from_file_path(new_path)
 9346            .ok()
 9347            .map(|uri| uri.to_string());
 9348        cx.spawn(async move |cx| {
 9349            let mut tasks = vec![];
 9350            this.update(cx, |this, cx| {
 9351                let local_store = this.as_local()?;
 9352                let old_uri = old_uri?;
 9353                let new_uri = new_uri?;
 9354                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9355                    let Some(filter) = local_store
 9356                        .language_server_paths_watched_for_rename
 9357                        .get(&language_server.server_id())
 9358                    else {
 9359                        continue;
 9360                    };
 9361
 9362                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9363                        let apply_edit = cx.spawn({
 9364                            let old_uri = old_uri.clone();
 9365                            let new_uri = new_uri.clone();
 9366                            let language_server = language_server.clone();
 9367                            async move |this, cx| {
 9368                                let edit = language_server
 9369                                    .request::<WillRenameFiles>(RenameFilesParams {
 9370                                        files: vec![FileRename { old_uri, new_uri }],
 9371                                    })
 9372                                    .await
 9373                                    .into_response()
 9374                                    .context("will rename files")
 9375                                    .log_err()
 9376                                    .flatten()?;
 9377
 9378                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9379                                    this.upgrade()?,
 9380                                    edit,
 9381                                    false,
 9382                                    language_server.clone(),
 9383                                    cx,
 9384                                )
 9385                                .await
 9386                                .ok()?;
 9387                                Some(transaction)
 9388                            }
 9389                        });
 9390                        tasks.push(apply_edit);
 9391                    }
 9392                }
 9393                Some(())
 9394            })
 9395            .ok()
 9396            .flatten();
 9397            let mut merged_transaction = ProjectTransaction::default();
 9398            for task in tasks {
 9399                // Await on tasks sequentially so that the order of application of edits is deterministic
 9400                // (at least with regards to the order of registration of language servers)
 9401                if let Some(transaction) = task.await {
 9402                    for (buffer, buffer_transaction) in transaction.0 {
 9403                        merged_transaction.0.insert(buffer, buffer_transaction);
 9404                    }
 9405                }
 9406            }
 9407            merged_transaction
 9408        })
 9409    }
 9410
 9411    fn lsp_notify_abs_paths_changed(
 9412        &mut self,
 9413        server_id: LanguageServerId,
 9414        changes: Vec<PathEvent>,
 9415    ) {
 9416        maybe!({
 9417            let server = self.language_server_for_id(server_id)?;
 9418            let changes = changes
 9419                .into_iter()
 9420                .filter_map(|event| {
 9421                    let typ = match event.kind? {
 9422                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9423                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9424                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9425                    };
 9426                    Some(lsp::FileEvent {
 9427                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9428                        typ,
 9429                    })
 9430                })
 9431                .collect::<Vec<_>>();
 9432            if !changes.is_empty() {
 9433                server
 9434                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9435                        lsp::DidChangeWatchedFilesParams { changes },
 9436                    )
 9437                    .ok();
 9438            }
 9439            Some(())
 9440        });
 9441    }
 9442
 9443    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9444        self.as_local()?.language_server_for_id(id)
 9445    }
 9446
 9447    fn on_lsp_progress(
 9448        &mut self,
 9449        progress_params: lsp::ProgressParams,
 9450        language_server_id: LanguageServerId,
 9451        disk_based_diagnostics_progress_token: Option<String>,
 9452        cx: &mut Context<Self>,
 9453    ) {
 9454        match progress_params.value {
 9455            lsp::ProgressParamsValue::WorkDone(progress) => {
 9456                self.handle_work_done_progress(
 9457                    progress,
 9458                    language_server_id,
 9459                    disk_based_diagnostics_progress_token,
 9460                    ProgressToken::from_lsp(progress_params.token),
 9461                    cx,
 9462                );
 9463            }
 9464            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9465                let identifier = match progress_params.token {
 9466                    lsp::NumberOrString::Number(_) => None,
 9467                    lsp::NumberOrString::String(token) => token
 9468                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9469                        .map(|(_, id)| id.to_owned()),
 9470                };
 9471                if let Some(LanguageServerState::Running {
 9472                    workspace_diagnostics_refresh_tasks,
 9473                    ..
 9474                }) = self
 9475                    .as_local_mut()
 9476                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9477                    && let Some(workspace_diagnostics) =
 9478                        workspace_diagnostics_refresh_tasks.get_mut(&identifier)
 9479                {
 9480                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9481                    self.apply_workspace_diagnostic_report(language_server_id, report, cx)
 9482                }
 9483            }
 9484        }
 9485    }
 9486
 9487    fn handle_work_done_progress(
 9488        &mut self,
 9489        progress: lsp::WorkDoneProgress,
 9490        language_server_id: LanguageServerId,
 9491        disk_based_diagnostics_progress_token: Option<String>,
 9492        token: ProgressToken,
 9493        cx: &mut Context<Self>,
 9494    ) {
 9495        let language_server_status =
 9496            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9497                status
 9498            } else {
 9499                return;
 9500            };
 9501
 9502        if !language_server_status.progress_tokens.contains(&token) {
 9503            return;
 9504        }
 9505
 9506        let is_disk_based_diagnostics_progress =
 9507            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9508                (&disk_based_diagnostics_progress_token, &token)
 9509            {
 9510                token.starts_with(disk_based_token)
 9511            } else {
 9512                false
 9513            };
 9514
 9515        match progress {
 9516            lsp::WorkDoneProgress::Begin(report) => {
 9517                if is_disk_based_diagnostics_progress {
 9518                    self.disk_based_diagnostics_started(language_server_id, cx);
 9519                }
 9520                self.on_lsp_work_start(
 9521                    language_server_id,
 9522                    token.clone(),
 9523                    LanguageServerProgress {
 9524                        title: Some(report.title),
 9525                        is_disk_based_diagnostics_progress,
 9526                        is_cancellable: report.cancellable.unwrap_or(false),
 9527                        message: report.message.clone(),
 9528                        percentage: report.percentage.map(|p| p as usize),
 9529                        last_update_at: cx.background_executor().now(),
 9530                    },
 9531                    cx,
 9532                );
 9533            }
 9534            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9535                language_server_id,
 9536                token,
 9537                LanguageServerProgress {
 9538                    title: None,
 9539                    is_disk_based_diagnostics_progress,
 9540                    is_cancellable: report.cancellable.unwrap_or(false),
 9541                    message: report.message,
 9542                    percentage: report.percentage.map(|p| p as usize),
 9543                    last_update_at: cx.background_executor().now(),
 9544                },
 9545                cx,
 9546            ),
 9547            lsp::WorkDoneProgress::End(_) => {
 9548                language_server_status.progress_tokens.remove(&token);
 9549                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9550                if is_disk_based_diagnostics_progress {
 9551                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9552                }
 9553            }
 9554        }
 9555    }
 9556
 9557    fn on_lsp_work_start(
 9558        &mut self,
 9559        language_server_id: LanguageServerId,
 9560        token: ProgressToken,
 9561        progress: LanguageServerProgress,
 9562        cx: &mut Context<Self>,
 9563    ) {
 9564        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9565            status.pending_work.insert(token.clone(), progress.clone());
 9566            cx.notify();
 9567        }
 9568        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9569            language_server_id,
 9570            name: self
 9571                .language_server_adapter_for_id(language_server_id)
 9572                .map(|adapter| adapter.name()),
 9573            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9574                token: Some(token.to_proto()),
 9575                title: progress.title,
 9576                message: progress.message,
 9577                percentage: progress.percentage.map(|p| p as u32),
 9578                is_cancellable: Some(progress.is_cancellable),
 9579            }),
 9580        })
 9581    }
 9582
 9583    fn on_lsp_work_progress(
 9584        &mut self,
 9585        language_server_id: LanguageServerId,
 9586        token: ProgressToken,
 9587        progress: LanguageServerProgress,
 9588        cx: &mut Context<Self>,
 9589    ) {
 9590        let mut did_update = false;
 9591        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9592            match status.pending_work.entry(token.clone()) {
 9593                btree_map::Entry::Vacant(entry) => {
 9594                    entry.insert(progress.clone());
 9595                    did_update = true;
 9596                }
 9597                btree_map::Entry::Occupied(mut entry) => {
 9598                    let entry = entry.get_mut();
 9599                    if (progress.last_update_at - entry.last_update_at)
 9600                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9601                    {
 9602                        entry.last_update_at = progress.last_update_at;
 9603                        if progress.message.is_some() {
 9604                            entry.message = progress.message.clone();
 9605                        }
 9606                        if progress.percentage.is_some() {
 9607                            entry.percentage = progress.percentage;
 9608                        }
 9609                        if progress.is_cancellable != entry.is_cancellable {
 9610                            entry.is_cancellable = progress.is_cancellable;
 9611                        }
 9612                        did_update = true;
 9613                    }
 9614                }
 9615            }
 9616        }
 9617
 9618        if did_update {
 9619            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9620                language_server_id,
 9621                name: self
 9622                    .language_server_adapter_for_id(language_server_id)
 9623                    .map(|adapter| adapter.name()),
 9624                message: proto::update_language_server::Variant::WorkProgress(
 9625                    proto::LspWorkProgress {
 9626                        token: Some(token.to_proto()),
 9627                        message: progress.message,
 9628                        percentage: progress.percentage.map(|p| p as u32),
 9629                        is_cancellable: Some(progress.is_cancellable),
 9630                    },
 9631                ),
 9632            })
 9633        }
 9634    }
 9635
 9636    fn on_lsp_work_end(
 9637        &mut self,
 9638        language_server_id: LanguageServerId,
 9639        token: ProgressToken,
 9640        cx: &mut Context<Self>,
 9641    ) {
 9642        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9643            if let Some(work) = status.pending_work.remove(&token)
 9644                && !work.is_disk_based_diagnostics_progress
 9645            {
 9646                cx.emit(LspStoreEvent::RefreshInlayHints {
 9647                    server_id: language_server_id,
 9648                    request_id: None,
 9649                });
 9650            }
 9651            cx.notify();
 9652        }
 9653
 9654        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9655            language_server_id,
 9656            name: self
 9657                .language_server_adapter_for_id(language_server_id)
 9658                .map(|adapter| adapter.name()),
 9659            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
 9660                token: Some(token.to_proto()),
 9661            }),
 9662        })
 9663    }
 9664
 9665    pub async fn handle_resolve_completion_documentation(
 9666        this: Entity<Self>,
 9667        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
 9668        mut cx: AsyncApp,
 9669    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
 9670        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
 9671
 9672        let completion = this
 9673            .read_with(&cx, |this, cx| {
 9674                let id = LanguageServerId(envelope.payload.language_server_id as usize);
 9675                let server = this
 9676                    .language_server_for_id(id)
 9677                    .with_context(|| format!("No language server {id}"))?;
 9678
 9679                anyhow::Ok(cx.background_spawn(async move {
 9680                    let can_resolve = server
 9681                        .capabilities()
 9682                        .completion_provider
 9683                        .as_ref()
 9684                        .and_then(|options| options.resolve_provider)
 9685                        .unwrap_or(false);
 9686                    if can_resolve {
 9687                        server
 9688                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
 9689                            .await
 9690                            .into_response()
 9691                            .context("resolve completion item")
 9692                    } else {
 9693                        anyhow::Ok(lsp_completion)
 9694                    }
 9695                }))
 9696            })??
 9697            .await?;
 9698
 9699        let mut documentation_is_markdown = false;
 9700        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
 9701        let documentation = match completion.documentation {
 9702            Some(lsp::Documentation::String(text)) => text,
 9703
 9704            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
 9705                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
 9706                value
 9707            }
 9708
 9709            _ => String::new(),
 9710        };
 9711
 9712        // If we have a new buffer_id, that means we're talking to a new client
 9713        // and want to check for new text_edits in the completion too.
 9714        let mut old_replace_start = None;
 9715        let mut old_replace_end = None;
 9716        let mut old_insert_start = None;
 9717        let mut old_insert_end = None;
 9718        let mut new_text = String::default();
 9719        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
 9720            let buffer_snapshot = this.update(&mut cx, |this, cx| {
 9721                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9722                anyhow::Ok(buffer.read(cx).snapshot())
 9723            })??;
 9724
 9725            if let Some(text_edit) = completion.text_edit.as_ref() {
 9726                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
 9727
 9728                if let Some(mut edit) = edit {
 9729                    LineEnding::normalize(&mut edit.new_text);
 9730
 9731                    new_text = edit.new_text;
 9732                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
 9733                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
 9734                    if let Some(insert_range) = edit.insert_range {
 9735                        old_insert_start = Some(serialize_anchor(&insert_range.start));
 9736                        old_insert_end = Some(serialize_anchor(&insert_range.end));
 9737                    }
 9738                }
 9739            }
 9740        }
 9741
 9742        Ok(proto::ResolveCompletionDocumentationResponse {
 9743            documentation,
 9744            documentation_is_markdown,
 9745            old_replace_start,
 9746            old_replace_end,
 9747            new_text,
 9748            lsp_completion,
 9749            old_insert_start,
 9750            old_insert_end,
 9751        })
 9752    }
 9753
 9754    async fn handle_on_type_formatting(
 9755        this: Entity<Self>,
 9756        envelope: TypedEnvelope<proto::OnTypeFormatting>,
 9757        mut cx: AsyncApp,
 9758    ) -> Result<proto::OnTypeFormattingResponse> {
 9759        let on_type_formatting = this.update(&mut cx, |this, cx| {
 9760            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9761            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9762            let position = envelope
 9763                .payload
 9764                .position
 9765                .and_then(deserialize_anchor)
 9766                .context("invalid position")?;
 9767            anyhow::Ok(this.apply_on_type_formatting(
 9768                buffer,
 9769                position,
 9770                envelope.payload.trigger.clone(),
 9771                cx,
 9772            ))
 9773        })??;
 9774
 9775        let transaction = on_type_formatting
 9776            .await?
 9777            .as_ref()
 9778            .map(language::proto::serialize_transaction);
 9779        Ok(proto::OnTypeFormattingResponse { transaction })
 9780    }
 9781
 9782    async fn handle_refresh_inlay_hints(
 9783        lsp_store: Entity<Self>,
 9784        envelope: TypedEnvelope<proto::RefreshInlayHints>,
 9785        mut cx: AsyncApp,
 9786    ) -> Result<proto::Ack> {
 9787        lsp_store.update(&mut cx, |_, cx| {
 9788            cx.emit(LspStoreEvent::RefreshInlayHints {
 9789                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
 9790                request_id: envelope.payload.request_id.map(|id| id as usize),
 9791            });
 9792        })?;
 9793        Ok(proto::Ack {})
 9794    }
 9795
 9796    async fn handle_pull_workspace_diagnostics(
 9797        lsp_store: Entity<Self>,
 9798        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
 9799        mut cx: AsyncApp,
 9800    ) -> Result<proto::Ack> {
 9801        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
 9802        lsp_store.update(&mut cx, |lsp_store, _| {
 9803            lsp_store.pull_workspace_diagnostics(server_id);
 9804        })?;
 9805        Ok(proto::Ack {})
 9806    }
 9807
 9808    async fn handle_get_color_presentation(
 9809        lsp_store: Entity<Self>,
 9810        envelope: TypedEnvelope<proto::GetColorPresentation>,
 9811        mut cx: AsyncApp,
 9812    ) -> Result<proto::GetColorPresentationResponse> {
 9813        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9814        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9815            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9816        })??;
 9817
 9818        let color = envelope
 9819            .payload
 9820            .color
 9821            .context("invalid color resolve request")?;
 9822        let start = color
 9823            .lsp_range_start
 9824            .context("invalid color resolve request")?;
 9825        let end = color
 9826            .lsp_range_end
 9827            .context("invalid color resolve request")?;
 9828
 9829        let color = DocumentColor {
 9830            lsp_range: lsp::Range {
 9831                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
 9832                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
 9833            },
 9834            color: lsp::Color {
 9835                red: color.red,
 9836                green: color.green,
 9837                blue: color.blue,
 9838                alpha: color.alpha,
 9839            },
 9840            resolved: false,
 9841            color_presentations: Vec::new(),
 9842        };
 9843        let resolved_color = lsp_store
 9844            .update(&mut cx, |lsp_store, cx| {
 9845                lsp_store.resolve_color_presentation(
 9846                    color,
 9847                    buffer.clone(),
 9848                    LanguageServerId(envelope.payload.server_id as usize),
 9849                    cx,
 9850                )
 9851            })?
 9852            .await
 9853            .context("resolving color presentation")?;
 9854
 9855        Ok(proto::GetColorPresentationResponse {
 9856            presentations: resolved_color
 9857                .color_presentations
 9858                .into_iter()
 9859                .map(|presentation| proto::ColorPresentation {
 9860                    label: presentation.label.to_string(),
 9861                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
 9862                    additional_text_edits: presentation
 9863                        .additional_text_edits
 9864                        .into_iter()
 9865                        .map(serialize_lsp_edit)
 9866                        .collect(),
 9867                })
 9868                .collect(),
 9869        })
 9870    }
 9871
 9872    async fn handle_resolve_inlay_hint(
 9873        lsp_store: Entity<Self>,
 9874        envelope: TypedEnvelope<proto::ResolveInlayHint>,
 9875        mut cx: AsyncApp,
 9876    ) -> Result<proto::ResolveInlayHintResponse> {
 9877        let proto_hint = envelope
 9878            .payload
 9879            .hint
 9880            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
 9881        let hint = InlayHints::proto_to_project_hint(proto_hint)
 9882            .context("resolved proto inlay hint conversion")?;
 9883        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9884            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9885            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9886        })??;
 9887        let response_hint = lsp_store
 9888            .update(&mut cx, |lsp_store, cx| {
 9889                lsp_store.resolve_inlay_hint(
 9890                    hint,
 9891                    buffer,
 9892                    LanguageServerId(envelope.payload.language_server_id as usize),
 9893                    cx,
 9894                )
 9895            })?
 9896            .await
 9897            .context("inlay hints fetch")?;
 9898        Ok(proto::ResolveInlayHintResponse {
 9899            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
 9900        })
 9901    }
 9902
 9903    async fn handle_refresh_code_lens(
 9904        this: Entity<Self>,
 9905        _: TypedEnvelope<proto::RefreshCodeLens>,
 9906        mut cx: AsyncApp,
 9907    ) -> Result<proto::Ack> {
 9908        this.update(&mut cx, |_, cx| {
 9909            cx.emit(LspStoreEvent::RefreshCodeLens);
 9910        })?;
 9911        Ok(proto::Ack {})
 9912    }
 9913
 9914    async fn handle_open_buffer_for_symbol(
 9915        this: Entity<Self>,
 9916        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
 9917        mut cx: AsyncApp,
 9918    ) -> Result<proto::OpenBufferForSymbolResponse> {
 9919        let peer_id = envelope.original_sender_id().unwrap_or_default();
 9920        let symbol = envelope.payload.symbol.context("invalid symbol")?;
 9921        let symbol = Self::deserialize_symbol(symbol)?;
 9922        this.read_with(&cx, |this, _| {
 9923            if let SymbolLocation::OutsideProject {
 9924                abs_path,
 9925                signature,
 9926            } = &symbol.path
 9927            {
 9928                let new_signature = this.symbol_signature(&abs_path);
 9929                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
 9930            }
 9931            Ok(())
 9932        })??;
 9933        let buffer = this
 9934            .update(&mut cx, |this, cx| {
 9935                this.open_buffer_for_symbol(
 9936                    &Symbol {
 9937                        language_server_name: symbol.language_server_name,
 9938                        source_worktree_id: symbol.source_worktree_id,
 9939                        source_language_server_id: symbol.source_language_server_id,
 9940                        path: symbol.path,
 9941                        name: symbol.name,
 9942                        kind: symbol.kind,
 9943                        range: symbol.range,
 9944                        label: CodeLabel::default(),
 9945                    },
 9946                    cx,
 9947                )
 9948            })?
 9949            .await?;
 9950
 9951        this.update(&mut cx, |this, cx| {
 9952            let is_private = buffer
 9953                .read(cx)
 9954                .file()
 9955                .map(|f| f.is_private())
 9956                .unwrap_or_default();
 9957            if is_private {
 9958                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
 9959            } else {
 9960                this.buffer_store
 9961                    .update(cx, |buffer_store, cx| {
 9962                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
 9963                    })
 9964                    .detach_and_log_err(cx);
 9965                let buffer_id = buffer.read(cx).remote_id().to_proto();
 9966                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
 9967            }
 9968        })?
 9969    }
 9970
 9971    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
 9972        let mut hasher = Sha256::new();
 9973        hasher.update(abs_path.to_string_lossy().as_bytes());
 9974        hasher.update(self.nonce.to_be_bytes());
 9975        hasher.finalize().as_slice().try_into().unwrap()
 9976    }
 9977
 9978    pub async fn handle_get_project_symbols(
 9979        this: Entity<Self>,
 9980        envelope: TypedEnvelope<proto::GetProjectSymbols>,
 9981        mut cx: AsyncApp,
 9982    ) -> Result<proto::GetProjectSymbolsResponse> {
 9983        let symbols = this
 9984            .update(&mut cx, |this, cx| {
 9985                this.symbols(&envelope.payload.query, cx)
 9986            })?
 9987            .await?;
 9988
 9989        Ok(proto::GetProjectSymbolsResponse {
 9990            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
 9991        })
 9992    }
 9993
 9994    pub async fn handle_restart_language_servers(
 9995        this: Entity<Self>,
 9996        envelope: TypedEnvelope<proto::RestartLanguageServers>,
 9997        mut cx: AsyncApp,
 9998    ) -> Result<proto::Ack> {
 9999        this.update(&mut cx, |lsp_store, cx| {
10000            let buffers =
10001                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10002            lsp_store.restart_language_servers_for_buffers(
10003                buffers,
10004                envelope
10005                    .payload
10006                    .only_servers
10007                    .into_iter()
10008                    .filter_map(|selector| {
10009                        Some(match selector.selector? {
10010                            proto::language_server_selector::Selector::ServerId(server_id) => {
10011                                LanguageServerSelector::Id(LanguageServerId::from_proto(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        })?;
10024
10025        Ok(proto::Ack {})
10026    }
10027
10028    pub async fn handle_stop_language_servers(
10029        lsp_store: Entity<Self>,
10030        envelope: TypedEnvelope<proto::StopLanguageServers>,
10031        mut cx: AsyncApp,
10032    ) -> Result<proto::Ack> {
10033        lsp_store.update(&mut cx, |lsp_store, cx| {
10034            if envelope.payload.all
10035                && envelope.payload.also_servers.is_empty()
10036                && envelope.payload.buffer_ids.is_empty()
10037            {
10038                lsp_store.stop_all_language_servers(cx);
10039            } else {
10040                let buffers =
10041                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10042                lsp_store
10043                    .stop_language_servers_for_buffers(
10044                        buffers,
10045                        envelope
10046                            .payload
10047                            .also_servers
10048                            .into_iter()
10049                            .filter_map(|selector| {
10050                                Some(match selector.selector? {
10051                                    proto::language_server_selector::Selector::ServerId(
10052                                        server_id,
10053                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10054                                        server_id,
10055                                    )),
10056                                    proto::language_server_selector::Selector::Name(name) => {
10057                                        LanguageServerSelector::Name(LanguageServerName(
10058                                            SharedString::from(name),
10059                                        ))
10060                                    }
10061                                })
10062                            })
10063                            .collect(),
10064                        cx,
10065                    )
10066                    .detach_and_log_err(cx);
10067            }
10068        })?;
10069
10070        Ok(proto::Ack {})
10071    }
10072
10073    pub async fn handle_cancel_language_server_work(
10074        lsp_store: Entity<Self>,
10075        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10076        mut cx: AsyncApp,
10077    ) -> Result<proto::Ack> {
10078        lsp_store.update(&mut cx, |lsp_store, cx| {
10079            if let Some(work) = envelope.payload.work {
10080                match work {
10081                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10082                        let buffers =
10083                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10084                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10085                    }
10086                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10087                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10088                        let token = work
10089                            .token
10090                            .map(|token| {
10091                                ProgressToken::from_proto(token)
10092                                    .context("invalid work progress token")
10093                            })
10094                            .transpose()?;
10095                        lsp_store.cancel_language_server_work(server_id, token, cx);
10096                    }
10097                }
10098            }
10099            anyhow::Ok(())
10100        })??;
10101
10102        Ok(proto::Ack {})
10103    }
10104
10105    fn buffer_ids_to_buffers(
10106        &mut self,
10107        buffer_ids: impl Iterator<Item = u64>,
10108        cx: &mut Context<Self>,
10109    ) -> Vec<Entity<Buffer>> {
10110        buffer_ids
10111            .into_iter()
10112            .flat_map(|buffer_id| {
10113                self.buffer_store
10114                    .read(cx)
10115                    .get(BufferId::new(buffer_id).log_err()?)
10116            })
10117            .collect::<Vec<_>>()
10118    }
10119
10120    async fn handle_apply_additional_edits_for_completion(
10121        this: Entity<Self>,
10122        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10123        mut cx: AsyncApp,
10124    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10125        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10126            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10127            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10128            let completion = Self::deserialize_completion(
10129                envelope.payload.completion.context("invalid completion")?,
10130            )?;
10131            anyhow::Ok((buffer, completion))
10132        })??;
10133
10134        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10135            this.apply_additional_edits_for_completion(
10136                buffer,
10137                Rc::new(RefCell::new(Box::new([Completion {
10138                    replace_range: completion.replace_range,
10139                    new_text: completion.new_text,
10140                    source: completion.source,
10141                    documentation: None,
10142                    label: CodeLabel::default(),
10143                    insert_text_mode: None,
10144                    icon_path: None,
10145                    confirm: None,
10146                }]))),
10147                0,
10148                false,
10149                cx,
10150            )
10151        })?;
10152
10153        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10154            transaction: apply_additional_edits
10155                .await?
10156                .as_ref()
10157                .map(language::proto::serialize_transaction),
10158        })
10159    }
10160
10161    pub fn last_formatting_failure(&self) -> Option<&str> {
10162        self.last_formatting_failure.as_deref()
10163    }
10164
10165    pub fn reset_last_formatting_failure(&mut self) {
10166        self.last_formatting_failure = None;
10167    }
10168
10169    pub fn environment_for_buffer(
10170        &self,
10171        buffer: &Entity<Buffer>,
10172        cx: &mut Context<Self>,
10173    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10174        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10175            environment.update(cx, |env, cx| {
10176                env.buffer_environment(buffer, &self.worktree_store, cx)
10177            })
10178        } else {
10179            Task::ready(None).shared()
10180        }
10181    }
10182
10183    pub fn format(
10184        &mut self,
10185        buffers: HashSet<Entity<Buffer>>,
10186        target: LspFormatTarget,
10187        push_to_history: bool,
10188        trigger: FormatTrigger,
10189        cx: &mut Context<Self>,
10190    ) -> Task<anyhow::Result<ProjectTransaction>> {
10191        let logger = zlog::scoped!("format");
10192        if self.as_local().is_some() {
10193            zlog::trace!(logger => "Formatting locally");
10194            let logger = zlog::scoped!(logger => "local");
10195            let buffers = buffers
10196                .into_iter()
10197                .map(|buffer_handle| {
10198                    let buffer = buffer_handle.read(cx);
10199                    let buffer_abs_path = File::from_dyn(buffer.file())
10200                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10201
10202                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10203                })
10204                .collect::<Vec<_>>();
10205
10206            cx.spawn(async move |lsp_store, cx| {
10207                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10208
10209                for (handle, abs_path, id) in buffers {
10210                    let env = lsp_store
10211                        .update(cx, |lsp_store, cx| {
10212                            lsp_store.environment_for_buffer(&handle, cx)
10213                        })?
10214                        .await;
10215
10216                    let ranges = match &target {
10217                        LspFormatTarget::Buffers => None,
10218                        LspFormatTarget::Ranges(ranges) => {
10219                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10220                        }
10221                    };
10222
10223                    formattable_buffers.push(FormattableBuffer {
10224                        handle,
10225                        abs_path,
10226                        env,
10227                        ranges,
10228                    });
10229                }
10230                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10231
10232                let format_timer = zlog::time!(logger => "Formatting buffers");
10233                let result = LocalLspStore::format_locally(
10234                    lsp_store.clone(),
10235                    formattable_buffers,
10236                    push_to_history,
10237                    trigger,
10238                    logger,
10239                    cx,
10240                )
10241                .await;
10242                format_timer.end();
10243
10244                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10245
10246                lsp_store.update(cx, |lsp_store, _| {
10247                    lsp_store.update_last_formatting_failure(&result);
10248                })?;
10249
10250                result
10251            })
10252        } else if let Some((client, project_id)) = self.upstream_client() {
10253            zlog::trace!(logger => "Formatting remotely");
10254            let logger = zlog::scoped!(logger => "remote");
10255            // Don't support formatting ranges via remote
10256            match target {
10257                LspFormatTarget::Buffers => {}
10258                LspFormatTarget::Ranges(_) => {
10259                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10260                    return Task::ready(Ok(ProjectTransaction::default()));
10261                }
10262            }
10263
10264            let buffer_store = self.buffer_store();
10265            cx.spawn(async move |lsp_store, cx| {
10266                zlog::trace!(logger => "Sending remote format request");
10267                let request_timer = zlog::time!(logger => "remote format request");
10268                let result = client
10269                    .request(proto::FormatBuffers {
10270                        project_id,
10271                        trigger: trigger as i32,
10272                        buffer_ids: buffers
10273                            .iter()
10274                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10275                            .collect::<Result<_>>()?,
10276                    })
10277                    .await
10278                    .and_then(|result| result.transaction.context("missing transaction"));
10279                request_timer.end();
10280
10281                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10282
10283                lsp_store.update(cx, |lsp_store, _| {
10284                    lsp_store.update_last_formatting_failure(&result);
10285                })?;
10286
10287                let transaction_response = result?;
10288                let _timer = zlog::time!(logger => "deserializing project transaction");
10289                buffer_store
10290                    .update(cx, |buffer_store, cx| {
10291                        buffer_store.deserialize_project_transaction(
10292                            transaction_response,
10293                            push_to_history,
10294                            cx,
10295                        )
10296                    })?
10297                    .await
10298            })
10299        } else {
10300            zlog::trace!(logger => "Not formatting");
10301            Task::ready(Ok(ProjectTransaction::default()))
10302        }
10303    }
10304
10305    async fn handle_format_buffers(
10306        this: Entity<Self>,
10307        envelope: TypedEnvelope<proto::FormatBuffers>,
10308        mut cx: AsyncApp,
10309    ) -> Result<proto::FormatBuffersResponse> {
10310        let sender_id = envelope.original_sender_id().unwrap_or_default();
10311        let format = this.update(&mut cx, |this, cx| {
10312            let mut buffers = HashSet::default();
10313            for buffer_id in &envelope.payload.buffer_ids {
10314                let buffer_id = BufferId::new(*buffer_id)?;
10315                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10316            }
10317            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10318            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10319        })??;
10320
10321        let project_transaction = format.await?;
10322        let project_transaction = this.update(&mut cx, |this, cx| {
10323            this.buffer_store.update(cx, |buffer_store, cx| {
10324                buffer_store.serialize_project_transaction_for_peer(
10325                    project_transaction,
10326                    sender_id,
10327                    cx,
10328                )
10329            })
10330        })?;
10331        Ok(proto::FormatBuffersResponse {
10332            transaction: Some(project_transaction),
10333        })
10334    }
10335
10336    async fn handle_apply_code_action_kind(
10337        this: Entity<Self>,
10338        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10339        mut cx: AsyncApp,
10340    ) -> Result<proto::ApplyCodeActionKindResponse> {
10341        let sender_id = envelope.original_sender_id().unwrap_or_default();
10342        let format = this.update(&mut cx, |this, cx| {
10343            let mut buffers = HashSet::default();
10344            for buffer_id in &envelope.payload.buffer_ids {
10345                let buffer_id = BufferId::new(*buffer_id)?;
10346                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10347            }
10348            let kind = match envelope.payload.kind.as_str() {
10349                "" => CodeActionKind::EMPTY,
10350                "quickfix" => CodeActionKind::QUICKFIX,
10351                "refactor" => CodeActionKind::REFACTOR,
10352                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10353                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10354                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10355                "source" => CodeActionKind::SOURCE,
10356                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10357                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10358                _ => anyhow::bail!(
10359                    "Invalid code action kind {}",
10360                    envelope.payload.kind.as_str()
10361                ),
10362            };
10363            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10364        })??;
10365
10366        let project_transaction = format.await?;
10367        let project_transaction = this.update(&mut cx, |this, cx| {
10368            this.buffer_store.update(cx, |buffer_store, cx| {
10369                buffer_store.serialize_project_transaction_for_peer(
10370                    project_transaction,
10371                    sender_id,
10372                    cx,
10373                )
10374            })
10375        })?;
10376        Ok(proto::ApplyCodeActionKindResponse {
10377            transaction: Some(project_transaction),
10378        })
10379    }
10380
10381    async fn shutdown_language_server(
10382        server_state: Option<LanguageServerState>,
10383        name: LanguageServerName,
10384        cx: &mut AsyncApp,
10385    ) {
10386        let server = match server_state {
10387            Some(LanguageServerState::Starting { startup, .. }) => {
10388                let mut timer = cx
10389                    .background_executor()
10390                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10391                    .fuse();
10392
10393                select! {
10394                    server = startup.fuse() => server,
10395                    () = timer => {
10396                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10397                        None
10398                    },
10399                }
10400            }
10401
10402            Some(LanguageServerState::Running { server, .. }) => Some(server),
10403
10404            None => None,
10405        };
10406
10407        if let Some(server) = server
10408            && let Some(shutdown) = server.shutdown()
10409        {
10410            shutdown.await;
10411        }
10412    }
10413
10414    // Returns a list of all of the worktrees which no longer have a language server and the root path
10415    // for the stopped server
10416    fn stop_local_language_server(
10417        &mut self,
10418        server_id: LanguageServerId,
10419        cx: &mut Context<Self>,
10420    ) -> Task<()> {
10421        let local = match &mut self.mode {
10422            LspStoreMode::Local(local) => local,
10423            _ => {
10424                return Task::ready(());
10425            }
10426        };
10427
10428        // Remove this server ID from all entries in the given worktree.
10429        local
10430            .language_server_ids
10431            .retain(|_, state| state.id != server_id);
10432        self.buffer_store.update(cx, |buffer_store, cx| {
10433            for buffer in buffer_store.buffers() {
10434                buffer.update(cx, |buffer, cx| {
10435                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10436                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10437                });
10438            }
10439        });
10440
10441        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10442            summaries.retain(|path, summaries_by_server_id| {
10443                if summaries_by_server_id.remove(&server_id).is_some() {
10444                    if let Some((client, project_id)) = self.downstream_client.clone() {
10445                        client
10446                            .send(proto::UpdateDiagnosticSummary {
10447                                project_id,
10448                                worktree_id: worktree_id.to_proto(),
10449                                summary: Some(proto::DiagnosticSummary {
10450                                    path: path.as_ref().to_proto(),
10451                                    language_server_id: server_id.0 as u64,
10452                                    error_count: 0,
10453                                    warning_count: 0,
10454                                }),
10455                                more_summaries: Vec::new(),
10456                            })
10457                            .log_err();
10458                    }
10459                    !summaries_by_server_id.is_empty()
10460                } else {
10461                    true
10462                }
10463            });
10464        }
10465
10466        let local = self.as_local_mut().unwrap();
10467        for diagnostics in local.diagnostics.values_mut() {
10468            diagnostics.retain(|_, diagnostics_by_server_id| {
10469                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10470                    diagnostics_by_server_id.remove(ix);
10471                    !diagnostics_by_server_id.is_empty()
10472                } else {
10473                    true
10474                }
10475            });
10476        }
10477        local.language_server_watched_paths.remove(&server_id);
10478
10479        let server_state = local.language_servers.remove(&server_id);
10480        self.cleanup_lsp_data(server_id);
10481        let name = self
10482            .language_server_statuses
10483            .remove(&server_id)
10484            .map(|status| status.name)
10485            .or_else(|| {
10486                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10487                    Some(adapter.name())
10488                } else {
10489                    None
10490                }
10491            });
10492
10493        if let Some(name) = name {
10494            log::info!("stopping language server {name}");
10495            self.languages
10496                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10497            cx.notify();
10498
10499            return cx.spawn(async move |lsp_store, cx| {
10500                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10501                lsp_store
10502                    .update(cx, |lsp_store, cx| {
10503                        lsp_store
10504                            .languages
10505                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10506                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10507                        cx.notify();
10508                    })
10509                    .ok();
10510            });
10511        }
10512
10513        if server_state.is_some() {
10514            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10515        }
10516        Task::ready(())
10517    }
10518
10519    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10520        if let Some((client, project_id)) = self.upstream_client() {
10521            let request = client.request(proto::StopLanguageServers {
10522                project_id,
10523                buffer_ids: Vec::new(),
10524                also_servers: Vec::new(),
10525                all: true,
10526            });
10527            cx.background_spawn(request).detach_and_log_err(cx);
10528        } else {
10529            let Some(local) = self.as_local_mut() else {
10530                return;
10531            };
10532            let language_servers_to_stop = local
10533                .language_server_ids
10534                .values()
10535                .map(|state| state.id)
10536                .collect();
10537            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10538            let tasks = language_servers_to_stop
10539                .into_iter()
10540                .map(|server| self.stop_local_language_server(server, cx))
10541                .collect::<Vec<_>>();
10542            cx.background_spawn(async move {
10543                futures::future::join_all(tasks).await;
10544            })
10545            .detach();
10546        }
10547    }
10548
10549    pub fn restart_language_servers_for_buffers(
10550        &mut self,
10551        buffers: Vec<Entity<Buffer>>,
10552        only_restart_servers: HashSet<LanguageServerSelector>,
10553        cx: &mut Context<Self>,
10554    ) {
10555        if let Some((client, project_id)) = self.upstream_client() {
10556            let request = client.request(proto::RestartLanguageServers {
10557                project_id,
10558                buffer_ids: buffers
10559                    .into_iter()
10560                    .map(|b| b.read(cx).remote_id().to_proto())
10561                    .collect(),
10562                only_servers: only_restart_servers
10563                    .into_iter()
10564                    .map(|selector| {
10565                        let selector = match selector {
10566                            LanguageServerSelector::Id(language_server_id) => {
10567                                proto::language_server_selector::Selector::ServerId(
10568                                    language_server_id.to_proto(),
10569                                )
10570                            }
10571                            LanguageServerSelector::Name(language_server_name) => {
10572                                proto::language_server_selector::Selector::Name(
10573                                    language_server_name.to_string(),
10574                                )
10575                            }
10576                        };
10577                        proto::LanguageServerSelector {
10578                            selector: Some(selector),
10579                        }
10580                    })
10581                    .collect(),
10582                all: false,
10583            });
10584            cx.background_spawn(request).detach_and_log_err(cx);
10585        } else {
10586            let stop_task = if only_restart_servers.is_empty() {
10587                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10588            } else {
10589                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10590            };
10591            cx.spawn(async move |lsp_store, cx| {
10592                stop_task.await;
10593                lsp_store
10594                    .update(cx, |lsp_store, cx| {
10595                        for buffer in buffers {
10596                            lsp_store.register_buffer_with_language_servers(
10597                                &buffer,
10598                                only_restart_servers.clone(),
10599                                true,
10600                                cx,
10601                            );
10602                        }
10603                    })
10604                    .ok()
10605            })
10606            .detach();
10607        }
10608    }
10609
10610    pub fn stop_language_servers_for_buffers(
10611        &mut self,
10612        buffers: Vec<Entity<Buffer>>,
10613        also_stop_servers: HashSet<LanguageServerSelector>,
10614        cx: &mut Context<Self>,
10615    ) -> Task<Result<()>> {
10616        if let Some((client, project_id)) = self.upstream_client() {
10617            let request = client.request(proto::StopLanguageServers {
10618                project_id,
10619                buffer_ids: buffers
10620                    .into_iter()
10621                    .map(|b| b.read(cx).remote_id().to_proto())
10622                    .collect(),
10623                also_servers: also_stop_servers
10624                    .into_iter()
10625                    .map(|selector| {
10626                        let selector = match selector {
10627                            LanguageServerSelector::Id(language_server_id) => {
10628                                proto::language_server_selector::Selector::ServerId(
10629                                    language_server_id.to_proto(),
10630                                )
10631                            }
10632                            LanguageServerSelector::Name(language_server_name) => {
10633                                proto::language_server_selector::Selector::Name(
10634                                    language_server_name.to_string(),
10635                                )
10636                            }
10637                        };
10638                        proto::LanguageServerSelector {
10639                            selector: Some(selector),
10640                        }
10641                    })
10642                    .collect(),
10643                all: false,
10644            });
10645            cx.background_spawn(async move {
10646                let _ = request.await?;
10647                Ok(())
10648            })
10649        } else {
10650            let task =
10651                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10652            cx.background_spawn(async move {
10653                task.await;
10654                Ok(())
10655            })
10656        }
10657    }
10658
10659    fn stop_local_language_servers_for_buffers(
10660        &mut self,
10661        buffers: &[Entity<Buffer>],
10662        also_stop_servers: HashSet<LanguageServerSelector>,
10663        cx: &mut Context<Self>,
10664    ) -> Task<()> {
10665        let Some(local) = self.as_local_mut() else {
10666            return Task::ready(());
10667        };
10668        let mut language_server_names_to_stop = BTreeSet::default();
10669        let mut language_servers_to_stop = also_stop_servers
10670            .into_iter()
10671            .flat_map(|selector| match selector {
10672                LanguageServerSelector::Id(id) => Some(id),
10673                LanguageServerSelector::Name(name) => {
10674                    language_server_names_to_stop.insert(name);
10675                    None
10676                }
10677            })
10678            .collect::<BTreeSet<_>>();
10679
10680        let mut covered_worktrees = HashSet::default();
10681        for buffer in buffers {
10682            buffer.update(cx, |buffer, cx| {
10683                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
10684                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
10685                    && covered_worktrees.insert(worktree_id)
10686                {
10687                    language_server_names_to_stop.retain(|name| {
10688                        let old_ids_count = language_servers_to_stop.len();
10689                        let all_language_servers_with_this_name = local
10690                            .language_server_ids
10691                            .iter()
10692                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
10693                        language_servers_to_stop.extend(all_language_servers_with_this_name);
10694                        old_ids_count == language_servers_to_stop.len()
10695                    });
10696                }
10697            });
10698        }
10699        for name in language_server_names_to_stop {
10700            language_servers_to_stop.extend(
10701                local
10702                    .language_server_ids
10703                    .iter()
10704                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
10705            );
10706        }
10707
10708        local.lsp_tree.remove_nodes(&language_servers_to_stop);
10709        let tasks = language_servers_to_stop
10710            .into_iter()
10711            .map(|server| self.stop_local_language_server(server, cx))
10712            .collect::<Vec<_>>();
10713
10714        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
10715    }
10716
10717    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
10718        let (worktree, relative_path) =
10719            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
10720
10721        let project_path = ProjectPath {
10722            worktree_id: worktree.read(cx).id(),
10723            path: relative_path,
10724        };
10725
10726        Some(
10727            self.buffer_store()
10728                .read(cx)
10729                .get_by_path(&project_path)?
10730                .read(cx),
10731        )
10732    }
10733
10734    #[cfg(any(test, feature = "test-support"))]
10735    pub fn update_diagnostics(
10736        &mut self,
10737        server_id: LanguageServerId,
10738        diagnostics: lsp::PublishDiagnosticsParams,
10739        result_id: Option<String>,
10740        source_kind: DiagnosticSourceKind,
10741        disk_based_sources: &[String],
10742        cx: &mut Context<Self>,
10743    ) -> Result<()> {
10744        self.merge_lsp_diagnostics(
10745            source_kind,
10746            vec![DocumentDiagnosticsUpdate {
10747                diagnostics,
10748                result_id,
10749                server_id,
10750                disk_based_sources: Cow::Borrowed(disk_based_sources),
10751            }],
10752            |_, _, _| false,
10753            cx,
10754        )
10755    }
10756
10757    pub fn merge_lsp_diagnostics(
10758        &mut self,
10759        source_kind: DiagnosticSourceKind,
10760        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
10761        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
10762        cx: &mut Context<Self>,
10763    ) -> Result<()> {
10764        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
10765        let updates = lsp_diagnostics
10766            .into_iter()
10767            .filter_map(|update| {
10768                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
10769                Some(DocumentDiagnosticsUpdate {
10770                    diagnostics: self.lsp_to_document_diagnostics(
10771                        abs_path,
10772                        source_kind,
10773                        update.server_id,
10774                        update.diagnostics,
10775                        &update.disk_based_sources,
10776                    ),
10777                    result_id: update.result_id,
10778                    server_id: update.server_id,
10779                    disk_based_sources: update.disk_based_sources,
10780                })
10781            })
10782            .collect();
10783        self.merge_diagnostic_entries(updates, merge, cx)?;
10784        Ok(())
10785    }
10786
10787    fn lsp_to_document_diagnostics(
10788        &mut self,
10789        document_abs_path: PathBuf,
10790        source_kind: DiagnosticSourceKind,
10791        server_id: LanguageServerId,
10792        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
10793        disk_based_sources: &[String],
10794    ) -> DocumentDiagnostics {
10795        let mut diagnostics = Vec::default();
10796        let mut primary_diagnostic_group_ids = HashMap::default();
10797        let mut sources_by_group_id = HashMap::default();
10798        let mut supporting_diagnostics = HashMap::default();
10799
10800        let adapter = self.language_server_adapter_for_id(server_id);
10801
10802        // Ensure that primary diagnostics are always the most severe
10803        lsp_diagnostics
10804            .diagnostics
10805            .sort_by_key(|item| item.severity);
10806
10807        for diagnostic in &lsp_diagnostics.diagnostics {
10808            let source = diagnostic.source.as_ref();
10809            let range = range_from_lsp(diagnostic.range);
10810            let is_supporting = diagnostic
10811                .related_information
10812                .as_ref()
10813                .is_some_and(|infos| {
10814                    infos.iter().any(|info| {
10815                        primary_diagnostic_group_ids.contains_key(&(
10816                            source,
10817                            diagnostic.code.clone(),
10818                            range_from_lsp(info.location.range),
10819                        ))
10820                    })
10821                });
10822
10823            let is_unnecessary = diagnostic
10824                .tags
10825                .as_ref()
10826                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
10827
10828            let underline = self
10829                .language_server_adapter_for_id(server_id)
10830                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
10831
10832            if is_supporting {
10833                supporting_diagnostics.insert(
10834                    (source, diagnostic.code.clone(), range),
10835                    (diagnostic.severity, is_unnecessary),
10836                );
10837            } else {
10838                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
10839                let is_disk_based =
10840                    source.is_some_and(|source| disk_based_sources.contains(source));
10841
10842                sources_by_group_id.insert(group_id, source);
10843                primary_diagnostic_group_ids
10844                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
10845
10846                diagnostics.push(DiagnosticEntry {
10847                    range,
10848                    diagnostic: Diagnostic {
10849                        source: diagnostic.source.clone(),
10850                        source_kind,
10851                        code: diagnostic.code.clone(),
10852                        code_description: diagnostic
10853                            .code_description
10854                            .as_ref()
10855                            .and_then(|d| d.href.clone()),
10856                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
10857                        markdown: adapter.as_ref().and_then(|adapter| {
10858                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
10859                        }),
10860                        message: diagnostic.message.trim().to_string(),
10861                        group_id,
10862                        is_primary: true,
10863                        is_disk_based,
10864                        is_unnecessary,
10865                        underline,
10866                        data: diagnostic.data.clone(),
10867                    },
10868                });
10869                if let Some(infos) = &diagnostic.related_information {
10870                    for info in infos {
10871                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
10872                            let range = range_from_lsp(info.location.range);
10873                            diagnostics.push(DiagnosticEntry {
10874                                range,
10875                                diagnostic: Diagnostic {
10876                                    source: diagnostic.source.clone(),
10877                                    source_kind,
10878                                    code: diagnostic.code.clone(),
10879                                    code_description: diagnostic
10880                                        .code_description
10881                                        .as_ref()
10882                                        .and_then(|d| d.href.clone()),
10883                                    severity: DiagnosticSeverity::INFORMATION,
10884                                    markdown: adapter.as_ref().and_then(|adapter| {
10885                                        adapter.diagnostic_message_to_markdown(&info.message)
10886                                    }),
10887                                    message: info.message.trim().to_string(),
10888                                    group_id,
10889                                    is_primary: false,
10890                                    is_disk_based,
10891                                    is_unnecessary: false,
10892                                    underline,
10893                                    data: diagnostic.data.clone(),
10894                                },
10895                            });
10896                        }
10897                    }
10898                }
10899            }
10900        }
10901
10902        for entry in &mut diagnostics {
10903            let diagnostic = &mut entry.diagnostic;
10904            if !diagnostic.is_primary {
10905                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
10906                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
10907                    source,
10908                    diagnostic.code.clone(),
10909                    entry.range.clone(),
10910                )) {
10911                    if let Some(severity) = severity {
10912                        diagnostic.severity = severity;
10913                    }
10914                    diagnostic.is_unnecessary = is_unnecessary;
10915                }
10916            }
10917        }
10918
10919        DocumentDiagnostics {
10920            diagnostics,
10921            document_abs_path,
10922            version: lsp_diagnostics.version,
10923        }
10924    }
10925
10926    fn insert_newly_running_language_server(
10927        &mut self,
10928        adapter: Arc<CachedLspAdapter>,
10929        language_server: Arc<LanguageServer>,
10930        server_id: LanguageServerId,
10931        key: LanguageServerSeed,
10932        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
10933        cx: &mut Context<Self>,
10934    ) {
10935        let Some(local) = self.as_local_mut() else {
10936            return;
10937        };
10938        // If the language server for this key doesn't match the server id, don't store the
10939        // server. Which will cause it to be dropped, killing the process
10940        if local
10941            .language_server_ids
10942            .get(&key)
10943            .map(|state| state.id != server_id)
10944            .unwrap_or(false)
10945        {
10946            return;
10947        }
10948
10949        // Update language_servers collection with Running variant of LanguageServerState
10950        // indicating that the server is up and running and ready
10951        let workspace_folders = workspace_folders.lock().clone();
10952        language_server.set_workspace_folders(workspace_folders);
10953
10954        let workspace_diagnostics_refresh_tasks = language_server
10955            .capabilities()
10956            .diagnostic_provider
10957            .and_then(|provider| {
10958                local
10959                    .language_server_dynamic_registrations
10960                    .entry(server_id)
10961                    .or_default()
10962                    .diagnostics
10963                    .entry(None)
10964                    .or_insert(provider.clone());
10965                let workspace_refresher =
10966                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
10967
10968                Some((None, workspace_refresher))
10969            })
10970            .into_iter()
10971            .collect();
10972        local.language_servers.insert(
10973            server_id,
10974            LanguageServerState::Running {
10975                workspace_diagnostics_refresh_tasks,
10976                adapter: adapter.clone(),
10977                server: language_server.clone(),
10978                simulate_disk_based_diagnostics_completion: None,
10979            },
10980        );
10981        local
10982            .languages
10983            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
10984        if let Some(file_ops_caps) = language_server
10985            .capabilities()
10986            .workspace
10987            .as_ref()
10988            .and_then(|ws| ws.file_operations.as_ref())
10989        {
10990            let did_rename_caps = file_ops_caps.did_rename.as_ref();
10991            let will_rename_caps = file_ops_caps.will_rename.as_ref();
10992            if did_rename_caps.or(will_rename_caps).is_some() {
10993                let watcher = RenamePathsWatchedForServer::default()
10994                    .with_did_rename_patterns(did_rename_caps)
10995                    .with_will_rename_patterns(will_rename_caps);
10996                local
10997                    .language_server_paths_watched_for_rename
10998                    .insert(server_id, watcher);
10999            }
11000        }
11001
11002        self.language_server_statuses.insert(
11003            server_id,
11004            LanguageServerStatus {
11005                name: language_server.name(),
11006                pending_work: Default::default(),
11007                has_pending_diagnostic_updates: false,
11008                progress_tokens: Default::default(),
11009                worktree: Some(key.worktree_id),
11010            },
11011        );
11012
11013        cx.emit(LspStoreEvent::LanguageServerAdded(
11014            server_id,
11015            language_server.name(),
11016            Some(key.worktree_id),
11017        ));
11018
11019        let server_capabilities = language_server.capabilities();
11020        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11021            downstream_client
11022                .send(proto::StartLanguageServer {
11023                    project_id: *project_id,
11024                    server: Some(proto::LanguageServer {
11025                        id: server_id.to_proto(),
11026                        name: language_server.name().to_string(),
11027                        worktree_id: Some(key.worktree_id.to_proto()),
11028                    }),
11029                    capabilities: serde_json::to_string(&server_capabilities)
11030                        .expect("serializing server LSP capabilities"),
11031                })
11032                .log_err();
11033        }
11034        self.lsp_server_capabilities
11035            .insert(server_id, server_capabilities);
11036
11037        // Tell the language server about every open buffer in the worktree that matches the language.
11038        // Also check for buffers in worktrees that reused this server
11039        let mut worktrees_using_server = vec![key.worktree_id];
11040        if let Some(local) = self.as_local() {
11041            // Find all worktrees that have this server in their language server tree
11042            for (worktree_id, servers) in &local.lsp_tree.instances {
11043                if *worktree_id != key.worktree_id {
11044                    for server_map in servers.roots.values() {
11045                        if server_map
11046                            .values()
11047                            .any(|(node, _)| node.id() == Some(server_id))
11048                        {
11049                            worktrees_using_server.push(*worktree_id);
11050                        }
11051                    }
11052                }
11053            }
11054        }
11055
11056        let mut buffer_paths_registered = Vec::new();
11057        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11058            let mut lsp_adapters = HashMap::default();
11059            for buffer_handle in buffer_store.buffers() {
11060                let buffer = buffer_handle.read(cx);
11061                let file = match File::from_dyn(buffer.file()) {
11062                    Some(file) => file,
11063                    None => continue,
11064                };
11065                let language = match buffer.language() {
11066                    Some(language) => language,
11067                    None => continue,
11068                };
11069
11070                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11071                    || !lsp_adapters
11072                        .entry(language.name())
11073                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11074                        .iter()
11075                        .any(|a| a.name == key.name)
11076                {
11077                    continue;
11078                }
11079                // didOpen
11080                let file = match file.as_local() {
11081                    Some(file) => file,
11082                    None => continue,
11083                };
11084
11085                let local = self.as_local_mut().unwrap();
11086
11087                let buffer_id = buffer.remote_id();
11088                if local.registered_buffers.contains_key(&buffer_id) {
11089                    let versions = local
11090                        .buffer_snapshots
11091                        .entry(buffer_id)
11092                        .or_default()
11093                        .entry(server_id)
11094                        .and_modify(|_| {
11095                            assert!(
11096                            false,
11097                            "There should not be an existing snapshot for a newly inserted buffer"
11098                        )
11099                        })
11100                        .or_insert_with(|| {
11101                            vec![LspBufferSnapshot {
11102                                version: 0,
11103                                snapshot: buffer.text_snapshot(),
11104                            }]
11105                        });
11106
11107                    let snapshot = versions.last().unwrap();
11108                    let version = snapshot.version;
11109                    let initial_snapshot = &snapshot.snapshot;
11110                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11111                    language_server.register_buffer(
11112                        uri,
11113                        adapter.language_id(&language.name()),
11114                        version,
11115                        initial_snapshot.text(),
11116                    );
11117                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11118                    local
11119                        .buffers_opened_in_servers
11120                        .entry(buffer_id)
11121                        .or_default()
11122                        .insert(server_id);
11123                }
11124                buffer_handle.update(cx, |buffer, cx| {
11125                    buffer.set_completion_triggers(
11126                        server_id,
11127                        language_server
11128                            .capabilities()
11129                            .completion_provider
11130                            .as_ref()
11131                            .and_then(|provider| {
11132                                provider
11133                                    .trigger_characters
11134                                    .as_ref()
11135                                    .map(|characters| characters.iter().cloned().collect())
11136                            })
11137                            .unwrap_or_default(),
11138                        cx,
11139                    )
11140                });
11141            }
11142        });
11143
11144        for (buffer_id, abs_path) in buffer_paths_registered {
11145            cx.emit(LspStoreEvent::LanguageServerUpdate {
11146                language_server_id: server_id,
11147                name: Some(adapter.name()),
11148                message: proto::update_language_server::Variant::RegisteredForBuffer(
11149                    proto::RegisteredForBuffer {
11150                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11151                        buffer_id: buffer_id.to_proto(),
11152                    },
11153                ),
11154            });
11155        }
11156
11157        cx.notify();
11158    }
11159
11160    pub fn language_servers_running_disk_based_diagnostics(
11161        &self,
11162    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11163        self.language_server_statuses
11164            .iter()
11165            .filter_map(|(id, status)| {
11166                if status.has_pending_diagnostic_updates {
11167                    Some(*id)
11168                } else {
11169                    None
11170                }
11171            })
11172    }
11173
11174    pub(crate) fn cancel_language_server_work_for_buffers(
11175        &mut self,
11176        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11177        cx: &mut Context<Self>,
11178    ) {
11179        if let Some((client, project_id)) = self.upstream_client() {
11180            let request = client.request(proto::CancelLanguageServerWork {
11181                project_id,
11182                work: Some(proto::cancel_language_server_work::Work::Buffers(
11183                    proto::cancel_language_server_work::Buffers {
11184                        buffer_ids: buffers
11185                            .into_iter()
11186                            .map(|b| b.read(cx).remote_id().to_proto())
11187                            .collect(),
11188                    },
11189                )),
11190            });
11191            cx.background_spawn(request).detach_and_log_err(cx);
11192        } else if let Some(local) = self.as_local() {
11193            let servers = buffers
11194                .into_iter()
11195                .flat_map(|buffer| {
11196                    buffer.update(cx, |buffer, cx| {
11197                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11198                    })
11199                })
11200                .collect::<HashSet<_>>();
11201            for server_id in servers {
11202                self.cancel_language_server_work(server_id, None, cx);
11203            }
11204        }
11205    }
11206
11207    pub(crate) fn cancel_language_server_work(
11208        &mut self,
11209        server_id: LanguageServerId,
11210        token_to_cancel: Option<ProgressToken>,
11211        cx: &mut Context<Self>,
11212    ) {
11213        if let Some(local) = self.as_local() {
11214            let status = self.language_server_statuses.get(&server_id);
11215            let server = local.language_servers.get(&server_id);
11216            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11217            {
11218                for (token, progress) in &status.pending_work {
11219                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11220                        && token != token_to_cancel
11221                    {
11222                        continue;
11223                    }
11224                    if progress.is_cancellable {
11225                        server
11226                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11227                                WorkDoneProgressCancelParams {
11228                                    token: token.to_lsp(),
11229                                },
11230                            )
11231                            .ok();
11232                    }
11233                }
11234            }
11235        } else if let Some((client, project_id)) = self.upstream_client() {
11236            let request = client.request(proto::CancelLanguageServerWork {
11237                project_id,
11238                work: Some(
11239                    proto::cancel_language_server_work::Work::LanguageServerWork(
11240                        proto::cancel_language_server_work::LanguageServerWork {
11241                            language_server_id: server_id.to_proto(),
11242                            token: token_to_cancel.map(|token| token.to_proto()),
11243                        },
11244                    ),
11245                ),
11246            });
11247            cx.background_spawn(request).detach_and_log_err(cx);
11248        }
11249    }
11250
11251    fn register_supplementary_language_server(
11252        &mut self,
11253        id: LanguageServerId,
11254        name: LanguageServerName,
11255        server: Arc<LanguageServer>,
11256        cx: &mut Context<Self>,
11257    ) {
11258        if let Some(local) = self.as_local_mut() {
11259            local
11260                .supplementary_language_servers
11261                .insert(id, (name.clone(), server));
11262            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11263        }
11264    }
11265
11266    fn unregister_supplementary_language_server(
11267        &mut self,
11268        id: LanguageServerId,
11269        cx: &mut Context<Self>,
11270    ) {
11271        if let Some(local) = self.as_local_mut() {
11272            local.supplementary_language_servers.remove(&id);
11273            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11274        }
11275    }
11276
11277    pub(crate) fn supplementary_language_servers(
11278        &self,
11279    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11280        self.as_local().into_iter().flat_map(|local| {
11281            local
11282                .supplementary_language_servers
11283                .iter()
11284                .map(|(id, (name, _))| (*id, name.clone()))
11285        })
11286    }
11287
11288    pub fn language_server_adapter_for_id(
11289        &self,
11290        id: LanguageServerId,
11291    ) -> Option<Arc<CachedLspAdapter>> {
11292        self.as_local()
11293            .and_then(|local| local.language_servers.get(&id))
11294            .and_then(|language_server_state| match language_server_state {
11295                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11296                _ => None,
11297            })
11298    }
11299
11300    pub(super) fn update_local_worktree_language_servers(
11301        &mut self,
11302        worktree_handle: &Entity<Worktree>,
11303        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11304        cx: &mut Context<Self>,
11305    ) {
11306        if changes.is_empty() {
11307            return;
11308        }
11309
11310        let Some(local) = self.as_local() else { return };
11311
11312        local.prettier_store.update(cx, |prettier_store, cx| {
11313            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11314        });
11315
11316        let worktree_id = worktree_handle.read(cx).id();
11317        let mut language_server_ids = local
11318            .language_server_ids
11319            .iter()
11320            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11321            .collect::<Vec<_>>();
11322        language_server_ids.sort();
11323        language_server_ids.dedup();
11324
11325        // let abs_path = worktree_handle.read(cx).abs_path();
11326        for server_id in &language_server_ids {
11327            if let Some(LanguageServerState::Running { server, .. }) =
11328                local.language_servers.get(server_id)
11329                && let Some(watched_paths) = local
11330                    .language_server_watched_paths
11331                    .get(server_id)
11332                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11333            {
11334                let params = lsp::DidChangeWatchedFilesParams {
11335                    changes: changes
11336                        .iter()
11337                        .filter_map(|(path, _, change)| {
11338                            if !watched_paths.is_match(path.as_std_path()) {
11339                                return None;
11340                            }
11341                            let typ = match change {
11342                                PathChange::Loaded => return None,
11343                                PathChange::Added => lsp::FileChangeType::CREATED,
11344                                PathChange::Removed => lsp::FileChangeType::DELETED,
11345                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11346                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11347                            };
11348                            let uri = lsp::Uri::from_file_path(
11349                                worktree_handle.read(cx).absolutize(&path),
11350                            )
11351                            .ok()?;
11352                            Some(lsp::FileEvent { uri, typ })
11353                        })
11354                        .collect(),
11355                };
11356                if !params.changes.is_empty() {
11357                    server
11358                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11359                        .ok();
11360                }
11361            }
11362        }
11363        for (path, _, _) in changes {
11364            if let Some(file_name) = path.file_name()
11365                && local.watched_manifest_filenames.contains(file_name)
11366            {
11367                self.request_workspace_config_refresh();
11368                break;
11369            }
11370        }
11371    }
11372
11373    pub fn wait_for_remote_buffer(
11374        &mut self,
11375        id: BufferId,
11376        cx: &mut Context<Self>,
11377    ) -> Task<Result<Entity<Buffer>>> {
11378        self.buffer_store.update(cx, |buffer_store, cx| {
11379            buffer_store.wait_for_remote_buffer(id, cx)
11380        })
11381    }
11382
11383    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11384        let mut result = proto::Symbol {
11385            language_server_name: symbol.language_server_name.0.to_string(),
11386            source_worktree_id: symbol.source_worktree_id.to_proto(),
11387            language_server_id: symbol.source_language_server_id.to_proto(),
11388            name: symbol.name.clone(),
11389            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11390            start: Some(proto::PointUtf16 {
11391                row: symbol.range.start.0.row,
11392                column: symbol.range.start.0.column,
11393            }),
11394            end: Some(proto::PointUtf16 {
11395                row: symbol.range.end.0.row,
11396                column: symbol.range.end.0.column,
11397            }),
11398            worktree_id: Default::default(),
11399            path: Default::default(),
11400            signature: Default::default(),
11401        };
11402        match &symbol.path {
11403            SymbolLocation::InProject(path) => {
11404                result.worktree_id = path.worktree_id.to_proto();
11405                result.path = path.path.to_proto();
11406            }
11407            SymbolLocation::OutsideProject {
11408                abs_path,
11409                signature,
11410            } => {
11411                result.path = abs_path.to_string_lossy().into_owned();
11412                result.signature = signature.to_vec();
11413            }
11414        }
11415        result
11416    }
11417
11418    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11419        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11420        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11421        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11422
11423        let path = if serialized_symbol.signature.is_empty() {
11424            SymbolLocation::InProject(ProjectPath {
11425                worktree_id,
11426                path: RelPath::from_proto(&serialized_symbol.path)
11427                    .context("invalid symbol path")?,
11428            })
11429        } else {
11430            SymbolLocation::OutsideProject {
11431                abs_path: Path::new(&serialized_symbol.path).into(),
11432                signature: serialized_symbol
11433                    .signature
11434                    .try_into()
11435                    .map_err(|_| anyhow!("invalid signature"))?,
11436            }
11437        };
11438
11439        let start = serialized_symbol.start.context("invalid start")?;
11440        let end = serialized_symbol.end.context("invalid end")?;
11441        Ok(CoreSymbol {
11442            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11443            source_worktree_id,
11444            source_language_server_id: LanguageServerId::from_proto(
11445                serialized_symbol.language_server_id,
11446            ),
11447            path,
11448            name: serialized_symbol.name,
11449            range: Unclipped(PointUtf16::new(start.row, start.column))
11450                ..Unclipped(PointUtf16::new(end.row, end.column)),
11451            kind,
11452        })
11453    }
11454
11455    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11456        let mut serialized_completion = proto::Completion {
11457            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11458            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11459            new_text: completion.new_text.clone(),
11460            ..proto::Completion::default()
11461        };
11462        match &completion.source {
11463            CompletionSource::Lsp {
11464                insert_range,
11465                server_id,
11466                lsp_completion,
11467                lsp_defaults,
11468                resolved,
11469            } => {
11470                let (old_insert_start, old_insert_end) = insert_range
11471                    .as_ref()
11472                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11473                    .unzip();
11474
11475                serialized_completion.old_insert_start = old_insert_start;
11476                serialized_completion.old_insert_end = old_insert_end;
11477                serialized_completion.source = proto::completion::Source::Lsp as i32;
11478                serialized_completion.server_id = server_id.0 as u64;
11479                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11480                serialized_completion.lsp_defaults = lsp_defaults
11481                    .as_deref()
11482                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11483                serialized_completion.resolved = *resolved;
11484            }
11485            CompletionSource::BufferWord {
11486                word_range,
11487                resolved,
11488            } => {
11489                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11490                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11491                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11492                serialized_completion.resolved = *resolved;
11493            }
11494            CompletionSource::Custom => {
11495                serialized_completion.source = proto::completion::Source::Custom as i32;
11496                serialized_completion.resolved = true;
11497            }
11498            CompletionSource::Dap { sort_text } => {
11499                serialized_completion.source = proto::completion::Source::Dap as i32;
11500                serialized_completion.sort_text = Some(sort_text.clone());
11501            }
11502        }
11503
11504        serialized_completion
11505    }
11506
11507    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11508        let old_replace_start = completion
11509            .old_replace_start
11510            .and_then(deserialize_anchor)
11511            .context("invalid old start")?;
11512        let old_replace_end = completion
11513            .old_replace_end
11514            .and_then(deserialize_anchor)
11515            .context("invalid old end")?;
11516        let insert_range = {
11517            match completion.old_insert_start.zip(completion.old_insert_end) {
11518                Some((start, end)) => {
11519                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11520                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11521                    Some(start..end)
11522                }
11523                None => None,
11524            }
11525        };
11526        Ok(CoreCompletion {
11527            replace_range: old_replace_start..old_replace_end,
11528            new_text: completion.new_text,
11529            source: match proto::completion::Source::from_i32(completion.source) {
11530                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11531                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11532                    insert_range,
11533                    server_id: LanguageServerId::from_proto(completion.server_id),
11534                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11535                    lsp_defaults: completion
11536                        .lsp_defaults
11537                        .as_deref()
11538                        .map(serde_json::from_slice)
11539                        .transpose()?,
11540                    resolved: completion.resolved,
11541                },
11542                Some(proto::completion::Source::BufferWord) => {
11543                    let word_range = completion
11544                        .buffer_word_start
11545                        .and_then(deserialize_anchor)
11546                        .context("invalid buffer word start")?
11547                        ..completion
11548                            .buffer_word_end
11549                            .and_then(deserialize_anchor)
11550                            .context("invalid buffer word end")?;
11551                    CompletionSource::BufferWord {
11552                        word_range,
11553                        resolved: completion.resolved,
11554                    }
11555                }
11556                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11557                    sort_text: completion
11558                        .sort_text
11559                        .context("expected sort text to exist")?,
11560                },
11561                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11562            },
11563        })
11564    }
11565
11566    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11567        let (kind, lsp_action) = match &action.lsp_action {
11568            LspAction::Action(code_action) => (
11569                proto::code_action::Kind::Action as i32,
11570                serde_json::to_vec(code_action).unwrap(),
11571            ),
11572            LspAction::Command(command) => (
11573                proto::code_action::Kind::Command as i32,
11574                serde_json::to_vec(command).unwrap(),
11575            ),
11576            LspAction::CodeLens(code_lens) => (
11577                proto::code_action::Kind::CodeLens as i32,
11578                serde_json::to_vec(code_lens).unwrap(),
11579            ),
11580        };
11581
11582        proto::CodeAction {
11583            server_id: action.server_id.0 as u64,
11584            start: Some(serialize_anchor(&action.range.start)),
11585            end: Some(serialize_anchor(&action.range.end)),
11586            lsp_action,
11587            kind,
11588            resolved: action.resolved,
11589        }
11590    }
11591
11592    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11593        let start = action
11594            .start
11595            .and_then(deserialize_anchor)
11596            .context("invalid start")?;
11597        let end = action
11598            .end
11599            .and_then(deserialize_anchor)
11600            .context("invalid end")?;
11601        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11602            Some(proto::code_action::Kind::Action) => {
11603                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11604            }
11605            Some(proto::code_action::Kind::Command) => {
11606                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11607            }
11608            Some(proto::code_action::Kind::CodeLens) => {
11609                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11610            }
11611            None => anyhow::bail!("Unknown action kind {}", action.kind),
11612        };
11613        Ok(CodeAction {
11614            server_id: LanguageServerId(action.server_id as usize),
11615            range: start..end,
11616            resolved: action.resolved,
11617            lsp_action,
11618        })
11619    }
11620
11621    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11622        match &formatting_result {
11623            Ok(_) => self.last_formatting_failure = None,
11624            Err(error) => {
11625                let error_string = format!("{error:#}");
11626                log::error!("Formatting failed: {error_string}");
11627                self.last_formatting_failure
11628                    .replace(error_string.lines().join(" "));
11629            }
11630        }
11631    }
11632
11633    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11634        self.lsp_server_capabilities.remove(&for_server);
11635        for lsp_data in self.lsp_data.values_mut() {
11636            lsp_data.remove_server_data(for_server);
11637        }
11638        if let Some(local) = self.as_local_mut() {
11639            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11640            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11641                buffer_servers.remove(&for_server);
11642            }
11643        }
11644    }
11645
11646    pub fn result_id(
11647        &self,
11648        server_id: LanguageServerId,
11649        buffer_id: BufferId,
11650        cx: &App,
11651    ) -> Option<String> {
11652        let abs_path = self
11653            .buffer_store
11654            .read(cx)
11655            .get(buffer_id)
11656            .and_then(|b| File::from_dyn(b.read(cx).file()))
11657            .map(|f| f.abs_path(cx))?;
11658        self.as_local()?
11659            .buffer_pull_diagnostics_result_ids
11660            .get(&server_id)?
11661            .get(&abs_path)?
11662            .clone()
11663    }
11664
11665    pub fn all_result_ids(&self, server_id: LanguageServerId) -> HashMap<PathBuf, String> {
11666        let Some(local) = self.as_local() else {
11667            return HashMap::default();
11668        };
11669        local
11670            .buffer_pull_diagnostics_result_ids
11671            .get(&server_id)
11672            .into_iter()
11673            .flatten()
11674            .filter_map(|(abs_path, result_id)| Some((abs_path.clone(), result_id.clone()?)))
11675            .collect()
11676    }
11677
11678    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
11679        if let Some(LanguageServerState::Running {
11680            workspace_diagnostics_refresh_tasks,
11681            ..
11682        }) = self
11683            .as_local_mut()
11684            .and_then(|local| local.language_servers.get_mut(&server_id))
11685        {
11686            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
11687                diagnostics.refresh_tx.try_send(()).ok();
11688            }
11689        }
11690    }
11691
11692    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
11693        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
11694            return;
11695        };
11696        let Some(local) = self.as_local_mut() else {
11697            return;
11698        };
11699
11700        for server_id in buffer.update(cx, |buffer, cx| {
11701            local.language_server_ids_for_buffer(buffer, cx)
11702        }) {
11703            if let Some(LanguageServerState::Running {
11704                workspace_diagnostics_refresh_tasks,
11705                ..
11706            }) = local.language_servers.get_mut(&server_id)
11707            {
11708                for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
11709                    diagnostics.refresh_tx.try_send(()).ok();
11710                }
11711            }
11712        }
11713    }
11714
11715    fn apply_workspace_diagnostic_report(
11716        &mut self,
11717        server_id: LanguageServerId,
11718        report: lsp::WorkspaceDiagnosticReportResult,
11719        cx: &mut Context<Self>,
11720    ) {
11721        let workspace_diagnostics =
11722            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(report, server_id);
11723        let mut unchanged_buffers = HashSet::default();
11724        let mut changed_buffers = HashSet::default();
11725        let workspace_diagnostics_updates = workspace_diagnostics
11726            .into_iter()
11727            .filter_map(
11728                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
11729                    LspPullDiagnostics::Response {
11730                        server_id,
11731                        uri,
11732                        diagnostics,
11733                    } => Some((server_id, uri, diagnostics, workspace_diagnostics.version)),
11734                    LspPullDiagnostics::Default => None,
11735                },
11736            )
11737            .fold(
11738                HashMap::default(),
11739                |mut acc, (server_id, uri, diagnostics, version)| {
11740                    let (result_id, diagnostics) = match diagnostics {
11741                        PulledDiagnostics::Unchanged { result_id } => {
11742                            unchanged_buffers.insert(uri.clone());
11743                            (Some(result_id), Vec::new())
11744                        }
11745                        PulledDiagnostics::Changed {
11746                            result_id,
11747                            diagnostics,
11748                        } => {
11749                            changed_buffers.insert(uri.clone());
11750                            (result_id, diagnostics)
11751                        }
11752                    };
11753                    let disk_based_sources = Cow::Owned(
11754                        self.language_server_adapter_for_id(server_id)
11755                            .as_ref()
11756                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
11757                            .unwrap_or(&[])
11758                            .to_vec(),
11759                    );
11760                    acc.entry(server_id)
11761                        .or_insert_with(Vec::new)
11762                        .push(DocumentDiagnosticsUpdate {
11763                            server_id,
11764                            diagnostics: lsp::PublishDiagnosticsParams {
11765                                uri,
11766                                diagnostics,
11767                                version,
11768                            },
11769                            result_id,
11770                            disk_based_sources,
11771                        });
11772                    acc
11773                },
11774            );
11775
11776        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
11777            self.merge_lsp_diagnostics(
11778                DiagnosticSourceKind::Pulled,
11779                diagnostic_updates,
11780                |buffer, old_diagnostic, cx| {
11781                    File::from_dyn(buffer.file())
11782                        .and_then(|file| {
11783                            let abs_path = file.as_local()?.abs_path(cx);
11784                            lsp::Uri::from_file_path(abs_path).ok()
11785                        })
11786                        .is_none_or(|buffer_uri| {
11787                            unchanged_buffers.contains(&buffer_uri)
11788                                || match old_diagnostic.source_kind {
11789                                    DiagnosticSourceKind::Pulled => {
11790                                        !changed_buffers.contains(&buffer_uri)
11791                                    }
11792                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
11793                                        true
11794                                    }
11795                                }
11796                        })
11797                },
11798                cx,
11799            )
11800            .log_err();
11801        }
11802    }
11803
11804    fn register_server_capabilities(
11805        &mut self,
11806        server_id: LanguageServerId,
11807        params: lsp::RegistrationParams,
11808        cx: &mut Context<Self>,
11809    ) -> anyhow::Result<()> {
11810        let server = self
11811            .language_server_for_id(server_id)
11812            .with_context(|| format!("no server {server_id} found"))?;
11813        for reg in params.registrations {
11814            match reg.method.as_str() {
11815                "workspace/didChangeWatchedFiles" => {
11816                    if let Some(options) = reg.register_options {
11817                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11818                            let caps = serde_json::from_value(options)?;
11819                            local_lsp_store
11820                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
11821                            true
11822                        } else {
11823                            false
11824                        };
11825                        if notify {
11826                            notify_server_capabilities_updated(&server, cx);
11827                        }
11828                    }
11829                }
11830                "workspace/didChangeConfiguration" => {
11831                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11832                }
11833                "workspace/didChangeWorkspaceFolders" => {
11834                    // In this case register options is an empty object, we can ignore it
11835                    let caps = lsp::WorkspaceFoldersServerCapabilities {
11836                        supported: Some(true),
11837                        change_notifications: Some(OneOf::Right(reg.id)),
11838                    };
11839                    server.update_capabilities(|capabilities| {
11840                        capabilities
11841                            .workspace
11842                            .get_or_insert_default()
11843                            .workspace_folders = Some(caps);
11844                    });
11845                    notify_server_capabilities_updated(&server, cx);
11846                }
11847                "workspace/symbol" => {
11848                    let options = parse_register_capabilities(reg)?;
11849                    server.update_capabilities(|capabilities| {
11850                        capabilities.workspace_symbol_provider = Some(options);
11851                    });
11852                    notify_server_capabilities_updated(&server, cx);
11853                }
11854                "workspace/fileOperations" => {
11855                    if let Some(options) = reg.register_options {
11856                        let caps = serde_json::from_value(options)?;
11857                        server.update_capabilities(|capabilities| {
11858                            capabilities
11859                                .workspace
11860                                .get_or_insert_default()
11861                                .file_operations = Some(caps);
11862                        });
11863                        notify_server_capabilities_updated(&server, cx);
11864                    }
11865                }
11866                "workspace/executeCommand" => {
11867                    if let Some(options) = reg.register_options {
11868                        let options = serde_json::from_value(options)?;
11869                        server.update_capabilities(|capabilities| {
11870                            capabilities.execute_command_provider = Some(options);
11871                        });
11872                        notify_server_capabilities_updated(&server, cx);
11873                    }
11874                }
11875                "textDocument/rangeFormatting" => {
11876                    let options = parse_register_capabilities(reg)?;
11877                    server.update_capabilities(|capabilities| {
11878                        capabilities.document_range_formatting_provider = Some(options);
11879                    });
11880                    notify_server_capabilities_updated(&server, cx);
11881                }
11882                "textDocument/onTypeFormatting" => {
11883                    if let Some(options) = reg
11884                        .register_options
11885                        .map(serde_json::from_value)
11886                        .transpose()?
11887                    {
11888                        server.update_capabilities(|capabilities| {
11889                            capabilities.document_on_type_formatting_provider = Some(options);
11890                        });
11891                        notify_server_capabilities_updated(&server, cx);
11892                    }
11893                }
11894                "textDocument/formatting" => {
11895                    let options = parse_register_capabilities(reg)?;
11896                    server.update_capabilities(|capabilities| {
11897                        capabilities.document_formatting_provider = Some(options);
11898                    });
11899                    notify_server_capabilities_updated(&server, cx);
11900                }
11901                "textDocument/rename" => {
11902                    let options = parse_register_capabilities(reg)?;
11903                    server.update_capabilities(|capabilities| {
11904                        capabilities.rename_provider = Some(options);
11905                    });
11906                    notify_server_capabilities_updated(&server, cx);
11907                }
11908                "textDocument/inlayHint" => {
11909                    let options = parse_register_capabilities(reg)?;
11910                    server.update_capabilities(|capabilities| {
11911                        capabilities.inlay_hint_provider = Some(options);
11912                    });
11913                    notify_server_capabilities_updated(&server, cx);
11914                }
11915                "textDocument/documentSymbol" => {
11916                    let options = parse_register_capabilities(reg)?;
11917                    server.update_capabilities(|capabilities| {
11918                        capabilities.document_symbol_provider = Some(options);
11919                    });
11920                    notify_server_capabilities_updated(&server, cx);
11921                }
11922                "textDocument/codeAction" => {
11923                    let options = parse_register_capabilities(reg)?;
11924                    let provider = match options {
11925                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
11926                        OneOf::Right(caps) => caps,
11927                    };
11928                    server.update_capabilities(|capabilities| {
11929                        capabilities.code_action_provider = Some(provider);
11930                    });
11931                    notify_server_capabilities_updated(&server, cx);
11932                }
11933                "textDocument/definition" => {
11934                    let options = parse_register_capabilities(reg)?;
11935                    server.update_capabilities(|capabilities| {
11936                        capabilities.definition_provider = Some(options);
11937                    });
11938                    notify_server_capabilities_updated(&server, cx);
11939                }
11940                "textDocument/completion" => {
11941                    if let Some(caps) = reg
11942                        .register_options
11943                        .map(serde_json::from_value::<CompletionOptions>)
11944                        .transpose()?
11945                    {
11946                        server.update_capabilities(|capabilities| {
11947                            capabilities.completion_provider = Some(caps.clone());
11948                        });
11949
11950                        if let Some(local) = self.as_local() {
11951                            let mut buffers_with_language_server = Vec::new();
11952                            for handle in self.buffer_store.read(cx).buffers() {
11953                                let buffer_id = handle.read(cx).remote_id();
11954                                if local
11955                                    .buffers_opened_in_servers
11956                                    .get(&buffer_id)
11957                                    .filter(|s| s.contains(&server_id))
11958                                    .is_some()
11959                                {
11960                                    buffers_with_language_server.push(handle);
11961                                }
11962                            }
11963                            let triggers = caps
11964                                .trigger_characters
11965                                .unwrap_or_default()
11966                                .into_iter()
11967                                .collect::<BTreeSet<_>>();
11968                            for handle in buffers_with_language_server {
11969                                let triggers = triggers.clone();
11970                                let _ = handle.update(cx, move |buffer, cx| {
11971                                    buffer.set_completion_triggers(server_id, triggers, cx);
11972                                });
11973                            }
11974                        }
11975                        notify_server_capabilities_updated(&server, cx);
11976                    }
11977                }
11978                "textDocument/hover" => {
11979                    let options = parse_register_capabilities(reg)?;
11980                    let provider = match options {
11981                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
11982                        OneOf::Right(caps) => caps,
11983                    };
11984                    server.update_capabilities(|capabilities| {
11985                        capabilities.hover_provider = Some(provider);
11986                    });
11987                    notify_server_capabilities_updated(&server, cx);
11988                }
11989                "textDocument/signatureHelp" => {
11990                    if let Some(caps) = reg
11991                        .register_options
11992                        .map(serde_json::from_value)
11993                        .transpose()?
11994                    {
11995                        server.update_capabilities(|capabilities| {
11996                            capabilities.signature_help_provider = Some(caps);
11997                        });
11998                        notify_server_capabilities_updated(&server, cx);
11999                    }
12000                }
12001                "textDocument/didChange" => {
12002                    if let Some(sync_kind) = reg
12003                        .register_options
12004                        .and_then(|opts| opts.get("syncKind").cloned())
12005                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12006                        .transpose()?
12007                    {
12008                        server.update_capabilities(|capabilities| {
12009                            let mut sync_options =
12010                                Self::take_text_document_sync_options(capabilities);
12011                            sync_options.change = Some(sync_kind);
12012                            capabilities.text_document_sync =
12013                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12014                        });
12015                        notify_server_capabilities_updated(&server, cx);
12016                    }
12017                }
12018                "textDocument/didSave" => {
12019                    if let Some(include_text) = reg
12020                        .register_options
12021                        .map(|opts| {
12022                            let transpose = opts
12023                                .get("includeText")
12024                                .cloned()
12025                                .map(serde_json::from_value::<Option<bool>>)
12026                                .transpose();
12027                            match transpose {
12028                                Ok(value) => Ok(value.flatten()),
12029                                Err(e) => Err(e),
12030                            }
12031                        })
12032                        .transpose()?
12033                    {
12034                        server.update_capabilities(|capabilities| {
12035                            let mut sync_options =
12036                                Self::take_text_document_sync_options(capabilities);
12037                            sync_options.save =
12038                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12039                                    include_text,
12040                                }));
12041                            capabilities.text_document_sync =
12042                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12043                        });
12044                        notify_server_capabilities_updated(&server, cx);
12045                    }
12046                }
12047                "textDocument/codeLens" => {
12048                    if let Some(caps) = reg
12049                        .register_options
12050                        .map(serde_json::from_value)
12051                        .transpose()?
12052                    {
12053                        server.update_capabilities(|capabilities| {
12054                            capabilities.code_lens_provider = Some(caps);
12055                        });
12056                        notify_server_capabilities_updated(&server, cx);
12057                    }
12058                }
12059                "textDocument/diagnostic" => {
12060                    if let Some(caps) = reg
12061                        .register_options
12062                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12063                        .transpose()?
12064                    {
12065                        let local = self
12066                            .as_local_mut()
12067                            .context("Expected LSP Store to be local")?;
12068                        let state = local
12069                            .language_servers
12070                            .get_mut(&server_id)
12071                            .context("Could not obtain Language Servers state")?;
12072                        local
12073                            .language_server_dynamic_registrations
12074                            .entry(server_id)
12075                            .or_default()
12076                            .diagnostics
12077                            .insert(Some(reg.id.clone()), caps.clone());
12078
12079                        if let LanguageServerState::Running {
12080                            workspace_diagnostics_refresh_tasks,
12081                            ..
12082                        } = state
12083                            && let Some(task) = lsp_workspace_diagnostics_refresh(
12084                                Some(reg.id.clone()),
12085                                caps.clone(),
12086                                server.clone(),
12087                                cx,
12088                            )
12089                        {
12090                            workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12091                        }
12092
12093                        let mut did_update_caps = false;
12094                        server.update_capabilities(|capabilities| {
12095                            if capabilities.diagnostic_provider.as_ref().is_none_or(
12096                                |current_caps| {
12097                                    let supports_workspace_diagnostics =
12098                                        |capabilities: &DiagnosticServerCapabilities| {
12099                                            match capabilities {
12100                                            DiagnosticServerCapabilities::Options(
12101                                                diagnostic_options,
12102                                            ) => diagnostic_options.workspace_diagnostics,
12103                                            DiagnosticServerCapabilities::RegistrationOptions(
12104                                                diagnostic_registration_options,
12105                                            ) => {
12106                                                diagnostic_registration_options
12107                                                    .diagnostic_options
12108                                                    .workspace_diagnostics
12109                                            }
12110                                        }
12111                                        };
12112                                    // We don't actually care about capabilities.diagnostic_provider, but it IS relevant for the remote peer
12113                                    // to know that there's at least one provider. Otherwise, it will never ask us to issue documentdiagnostic calls on their behalf,
12114                                    // as it'll think that they're not supported.
12115                                    // If we did not support any workspace diagnostics up to this point but now do, let's update.
12116                                    !supports_workspace_diagnostics(current_caps)
12117                                        & supports_workspace_diagnostics(&caps)
12118                                },
12119                            ) {
12120                                did_update_caps = true;
12121                                capabilities.diagnostic_provider = Some(caps);
12122                            }
12123                        });
12124                        if did_update_caps {
12125                            notify_server_capabilities_updated(&server, cx);
12126                        }
12127                    }
12128                }
12129                "textDocument/documentColor" => {
12130                    let options = parse_register_capabilities(reg)?;
12131                    let provider = match options {
12132                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12133                        OneOf::Right(caps) => caps,
12134                    };
12135                    server.update_capabilities(|capabilities| {
12136                        capabilities.color_provider = Some(provider);
12137                    });
12138                    notify_server_capabilities_updated(&server, cx);
12139                }
12140                _ => log::warn!("unhandled capability registration: {reg:?}"),
12141            }
12142        }
12143
12144        Ok(())
12145    }
12146
12147    fn unregister_server_capabilities(
12148        &mut self,
12149        server_id: LanguageServerId,
12150        params: lsp::UnregistrationParams,
12151        cx: &mut Context<Self>,
12152    ) -> anyhow::Result<()> {
12153        let server = self
12154            .language_server_for_id(server_id)
12155            .with_context(|| format!("no server {server_id} found"))?;
12156        for unreg in params.unregisterations.iter() {
12157            match unreg.method.as_str() {
12158                "workspace/didChangeWatchedFiles" => {
12159                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12160                        local_lsp_store
12161                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12162                        true
12163                    } else {
12164                        false
12165                    };
12166                    if notify {
12167                        notify_server_capabilities_updated(&server, cx);
12168                    }
12169                }
12170                "workspace/didChangeConfiguration" => {
12171                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12172                }
12173                "workspace/didChangeWorkspaceFolders" => {
12174                    server.update_capabilities(|capabilities| {
12175                        capabilities
12176                            .workspace
12177                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12178                                workspace_folders: None,
12179                                file_operations: None,
12180                            })
12181                            .workspace_folders = None;
12182                    });
12183                    notify_server_capabilities_updated(&server, cx);
12184                }
12185                "workspace/symbol" => {
12186                    server.update_capabilities(|capabilities| {
12187                        capabilities.workspace_symbol_provider = None
12188                    });
12189                    notify_server_capabilities_updated(&server, cx);
12190                }
12191                "workspace/fileOperations" => {
12192                    server.update_capabilities(|capabilities| {
12193                        capabilities
12194                            .workspace
12195                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12196                                workspace_folders: None,
12197                                file_operations: None,
12198                            })
12199                            .file_operations = None;
12200                    });
12201                    notify_server_capabilities_updated(&server, cx);
12202                }
12203                "workspace/executeCommand" => {
12204                    server.update_capabilities(|capabilities| {
12205                        capabilities.execute_command_provider = None;
12206                    });
12207                    notify_server_capabilities_updated(&server, cx);
12208                }
12209                "textDocument/rangeFormatting" => {
12210                    server.update_capabilities(|capabilities| {
12211                        capabilities.document_range_formatting_provider = None
12212                    });
12213                    notify_server_capabilities_updated(&server, cx);
12214                }
12215                "textDocument/onTypeFormatting" => {
12216                    server.update_capabilities(|capabilities| {
12217                        capabilities.document_on_type_formatting_provider = None;
12218                    });
12219                    notify_server_capabilities_updated(&server, cx);
12220                }
12221                "textDocument/formatting" => {
12222                    server.update_capabilities(|capabilities| {
12223                        capabilities.document_formatting_provider = None;
12224                    });
12225                    notify_server_capabilities_updated(&server, cx);
12226                }
12227                "textDocument/rename" => {
12228                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12229                    notify_server_capabilities_updated(&server, cx);
12230                }
12231                "textDocument/codeAction" => {
12232                    server.update_capabilities(|capabilities| {
12233                        capabilities.code_action_provider = None;
12234                    });
12235                    notify_server_capabilities_updated(&server, cx);
12236                }
12237                "textDocument/definition" => {
12238                    server.update_capabilities(|capabilities| {
12239                        capabilities.definition_provider = None;
12240                    });
12241                    notify_server_capabilities_updated(&server, cx);
12242                }
12243                "textDocument/completion" => {
12244                    server.update_capabilities(|capabilities| {
12245                        capabilities.completion_provider = None;
12246                    });
12247                    notify_server_capabilities_updated(&server, cx);
12248                }
12249                "textDocument/hover" => {
12250                    server.update_capabilities(|capabilities| {
12251                        capabilities.hover_provider = None;
12252                    });
12253                    notify_server_capabilities_updated(&server, cx);
12254                }
12255                "textDocument/signatureHelp" => {
12256                    server.update_capabilities(|capabilities| {
12257                        capabilities.signature_help_provider = None;
12258                    });
12259                    notify_server_capabilities_updated(&server, cx);
12260                }
12261                "textDocument/didChange" => {
12262                    server.update_capabilities(|capabilities| {
12263                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12264                        sync_options.change = None;
12265                        capabilities.text_document_sync =
12266                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12267                    });
12268                    notify_server_capabilities_updated(&server, cx);
12269                }
12270                "textDocument/didSave" => {
12271                    server.update_capabilities(|capabilities| {
12272                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12273                        sync_options.save = None;
12274                        capabilities.text_document_sync =
12275                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12276                    });
12277                    notify_server_capabilities_updated(&server, cx);
12278                }
12279                "textDocument/codeLens" => {
12280                    server.update_capabilities(|capabilities| {
12281                        capabilities.code_lens_provider = None;
12282                    });
12283                    notify_server_capabilities_updated(&server, cx);
12284                }
12285                "textDocument/diagnostic" => {
12286                    let local = self
12287                        .as_local_mut()
12288                        .context("Expected LSP Store to be local")?;
12289
12290                    let state = local
12291                        .language_servers
12292                        .get_mut(&server_id)
12293                        .context("Could not obtain Language Servers state")?;
12294                    let options = local
12295                        .language_server_dynamic_registrations
12296                        .get_mut(&server_id)
12297                        .with_context(|| {
12298                            format!("Expected dynamic registration to exist for server {server_id}")
12299                        })?.diagnostics
12300                        .remove(&Some(unreg.id.clone()))
12301                        .with_context(|| format!(
12302                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12303                            unreg.id)
12304                        )?;
12305
12306                    let mut has_any_diagnostic_providers_still = true;
12307                    if let Some(identifier) = diagnostic_identifier(&options)
12308                        && let LanguageServerState::Running {
12309                            workspace_diagnostics_refresh_tasks,
12310                            ..
12311                        } = state
12312                    {
12313                        workspace_diagnostics_refresh_tasks.remove(&identifier);
12314                        has_any_diagnostic_providers_still =
12315                            !workspace_diagnostics_refresh_tasks.is_empty();
12316                    }
12317
12318                    if !has_any_diagnostic_providers_still {
12319                        server.update_capabilities(|capabilities| {
12320                            debug_assert!(capabilities.diagnostic_provider.is_some());
12321                            capabilities.diagnostic_provider = None;
12322                        });
12323                    }
12324
12325                    notify_server_capabilities_updated(&server, cx);
12326                }
12327                "textDocument/documentColor" => {
12328                    server.update_capabilities(|capabilities| {
12329                        capabilities.color_provider = None;
12330                    });
12331                    notify_server_capabilities_updated(&server, cx);
12332                }
12333                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12334            }
12335        }
12336
12337        Ok(())
12338    }
12339
12340    async fn deduplicate_range_based_lsp_requests<T>(
12341        lsp_store: &Entity<Self>,
12342        server_id: Option<LanguageServerId>,
12343        lsp_request_id: LspRequestId,
12344        proto_request: &T::ProtoRequest,
12345        range: Range<Anchor>,
12346        cx: &mut AsyncApp,
12347    ) -> Result<()>
12348    where
12349        T: LspCommand,
12350        T::ProtoRequest: proto::LspRequestMessage,
12351    {
12352        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12353        let version = deserialize_version(proto_request.buffer_version());
12354        let buffer = lsp_store.update(cx, |this, cx| {
12355            this.buffer_store.read(cx).get_existing(buffer_id)
12356        })??;
12357        buffer
12358            .update(cx, |buffer, _| buffer.wait_for_version(version))?
12359            .await?;
12360        lsp_store.update(cx, |lsp_store, cx| {
12361            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12362            let chunks_queried_for = lsp_data
12363                .inlay_hints
12364                .applicable_chunks(&[range])
12365                .collect::<Vec<_>>();
12366            match chunks_queried_for.as_slice() {
12367                &[chunk] => {
12368                    let key = LspKey {
12369                        request_type: TypeId::of::<T>(),
12370                        server_queried: server_id,
12371                    };
12372                    let previous_request = lsp_data
12373                        .chunk_lsp_requests
12374                        .entry(key)
12375                        .or_default()
12376                        .insert(chunk, lsp_request_id);
12377                    if let Some((previous_request, running_requests)) =
12378                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12379                    {
12380                        running_requests.remove(&previous_request);
12381                    }
12382                }
12383                _ambiguous_chunks => {
12384                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12385                    // there, a buffer version-based check will be performed and outdated requests discarded.
12386                }
12387            }
12388            anyhow::Ok(())
12389        })??;
12390
12391        Ok(())
12392    }
12393
12394    async fn query_lsp_locally<T>(
12395        lsp_store: Entity<Self>,
12396        for_server_id: Option<LanguageServerId>,
12397        sender_id: proto::PeerId,
12398        lsp_request_id: LspRequestId,
12399        proto_request: T::ProtoRequest,
12400        position: Option<Anchor>,
12401        cx: &mut AsyncApp,
12402    ) -> Result<()>
12403    where
12404        T: LspCommand + Clone,
12405        T::ProtoRequest: proto::LspRequestMessage,
12406        <T::ProtoRequest as proto::RequestMessage>::Response:
12407            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12408    {
12409        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12410        let version = deserialize_version(proto_request.buffer_version());
12411        let buffer = lsp_store.update(cx, |this, cx| {
12412            this.buffer_store.read(cx).get_existing(buffer_id)
12413        })??;
12414        buffer
12415            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))?
12416            .await?;
12417        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version())?;
12418        let request =
12419            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12420        let key = LspKey {
12421            request_type: TypeId::of::<T>(),
12422            server_queried: for_server_id,
12423        };
12424        lsp_store.update(cx, |lsp_store, cx| {
12425            let request_task = match for_server_id {
12426                Some(server_id) => {
12427                    let server_task = lsp_store.request_lsp(
12428                        buffer.clone(),
12429                        LanguageServerToQuery::Other(server_id),
12430                        request.clone(),
12431                        cx,
12432                    );
12433                    cx.background_spawn(async move {
12434                        let mut responses = Vec::new();
12435                        match server_task.await {
12436                            Ok(response) => responses.push((server_id, response)),
12437                            // rust-analyzer likes to error with this when its still loading up
12438                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
12439                            Err(e) => log::error!(
12440                                "Error handling response for request {request:?}: {e:#}"
12441                            ),
12442                        }
12443                        responses
12444                    })
12445                }
12446                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12447            };
12448            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12449            if T::ProtoRequest::stop_previous_requests() {
12450                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12451                    lsp_requests.clear();
12452                }
12453            }
12454            lsp_data.lsp_requests.entry(key).or_default().insert(
12455                lsp_request_id,
12456                cx.spawn(async move |lsp_store, cx| {
12457                    let response = request_task.await;
12458                    lsp_store
12459                        .update(cx, |lsp_store, cx| {
12460                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12461                            {
12462                                let response = response
12463                                    .into_iter()
12464                                    .map(|(server_id, response)| {
12465                                        (
12466                                            server_id.to_proto(),
12467                                            T::response_to_proto(
12468                                                response,
12469                                                lsp_store,
12470                                                sender_id,
12471                                                &buffer_version,
12472                                                cx,
12473                                            )
12474                                            .into(),
12475                                        )
12476                                    })
12477                                    .collect::<HashMap<_, _>>();
12478                                match client.send_lsp_response::<T::ProtoRequest>(
12479                                    project_id,
12480                                    lsp_request_id,
12481                                    response,
12482                                ) {
12483                                    Ok(()) => {}
12484                                    Err(e) => {
12485                                        log::error!("Failed to send LSP response: {e:#}",)
12486                                    }
12487                                }
12488                            }
12489                        })
12490                        .ok();
12491                }),
12492            );
12493        })?;
12494        Ok(())
12495    }
12496
12497    fn take_text_document_sync_options(
12498        capabilities: &mut lsp::ServerCapabilities,
12499    ) -> lsp::TextDocumentSyncOptions {
12500        match capabilities.text_document_sync.take() {
12501            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12502            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12503                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12504                sync_options.change = Some(sync_kind);
12505                sync_options
12506            }
12507            None => lsp::TextDocumentSyncOptions::default(),
12508        }
12509    }
12510
12511    #[cfg(any(test, feature = "test-support"))]
12512    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
12513        Some(
12514            self.lsp_data
12515                .get_mut(&buffer_id)?
12516                .code_lens
12517                .take()?
12518                .update
12519                .take()?
12520                .1,
12521        )
12522    }
12523
12524    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
12525        self.downstream_client.clone()
12526    }
12527
12528    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
12529        self.worktree_store.clone()
12530    }
12531
12532    /// Gets what's stored in the LSP data for the given buffer.
12533    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
12534        self.lsp_data.get_mut(&buffer_id)
12535    }
12536
12537    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
12538    /// new [`BufferLspData`] will be created to replace the previous state.
12539    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
12540        let (buffer_id, buffer_version) =
12541            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
12542        let lsp_data = self
12543            .lsp_data
12544            .entry(buffer_id)
12545            .or_insert_with(|| BufferLspData::new(buffer, cx));
12546        if buffer_version.changed_since(&lsp_data.buffer_version) {
12547            *lsp_data = BufferLspData::new(buffer, cx);
12548        }
12549        lsp_data
12550    }
12551}
12552
12553// Registration with registerOptions as null, should fallback to true.
12554// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
12555fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
12556    reg: lsp::Registration,
12557) -> Result<OneOf<bool, T>> {
12558    Ok(match reg.register_options {
12559        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
12560        None => OneOf::Left(true),
12561    })
12562}
12563
12564fn subscribe_to_binary_statuses(
12565    languages: &Arc<LanguageRegistry>,
12566    cx: &mut Context<'_, LspStore>,
12567) -> Task<()> {
12568    let mut server_statuses = languages.language_server_binary_statuses();
12569    cx.spawn(async move |lsp_store, cx| {
12570        while let Some((server_name, binary_status)) = server_statuses.next().await {
12571            if lsp_store
12572                .update(cx, |_, cx| {
12573                    let mut message = None;
12574                    let binary_status = match binary_status {
12575                        BinaryStatus::None => proto::ServerBinaryStatus::None,
12576                        BinaryStatus::CheckingForUpdate => {
12577                            proto::ServerBinaryStatus::CheckingForUpdate
12578                        }
12579                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
12580                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
12581                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
12582                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
12583                        BinaryStatus::Failed { error } => {
12584                            message = Some(error);
12585                            proto::ServerBinaryStatus::Failed
12586                        }
12587                    };
12588                    cx.emit(LspStoreEvent::LanguageServerUpdate {
12589                        // Binary updates are about the binary that might not have any language server id at that point.
12590                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
12591                        language_server_id: LanguageServerId(0),
12592                        name: Some(server_name),
12593                        message: proto::update_language_server::Variant::StatusUpdate(
12594                            proto::StatusUpdate {
12595                                message,
12596                                status: Some(proto::status_update::Status::Binary(
12597                                    binary_status as i32,
12598                                )),
12599                            },
12600                        ),
12601                    });
12602                })
12603                .is_err()
12604            {
12605                break;
12606            }
12607        }
12608    })
12609}
12610
12611fn lsp_workspace_diagnostics_refresh(
12612    registration_id: Option<String>,
12613    options: DiagnosticServerCapabilities,
12614    server: Arc<LanguageServer>,
12615    cx: &mut Context<'_, LspStore>,
12616) -> Option<WorkspaceRefreshTask> {
12617    let identifier = diagnostic_identifier(&options)?;
12618
12619    let (progress_tx, mut progress_rx) = mpsc::channel(1);
12620    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
12621    refresh_tx.try_send(()).ok();
12622
12623    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
12624        let mut attempts = 0;
12625        let max_attempts = 50;
12626        let mut requests = 0;
12627
12628        loop {
12629            let Some(()) = refresh_rx.recv().await else {
12630                return;
12631            };
12632
12633            'request: loop {
12634                requests += 1;
12635                if attempts > max_attempts {
12636                    log::error!(
12637                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
12638                    );
12639                    return;
12640                }
12641                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
12642                cx.background_executor()
12643                    .timer(Duration::from_millis(backoff_millis))
12644                    .await;
12645                attempts += 1;
12646
12647                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
12648                    lsp_store
12649                        .all_result_ids(server.server_id())
12650                        .into_iter()
12651                        .filter_map(|(abs_path, result_id)| {
12652                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
12653                            Some(lsp::PreviousResultId {
12654                                uri,
12655                                value: result_id,
12656                            })
12657                        })
12658                        .collect()
12659                }) else {
12660                    return;
12661                };
12662
12663                let token = if let Some(identifier) = &registration_id {
12664                    format!(
12665                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{identifier}",
12666                        server.server_id(),
12667                    )
12668                } else {
12669                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
12670                };
12671
12672                progress_rx.try_recv().ok();
12673                let timer =
12674                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
12675                let progress = pin!(progress_rx.recv().fuse());
12676                let response_result = server
12677                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
12678                        lsp::WorkspaceDiagnosticParams {
12679                            previous_result_ids,
12680                            identifier: identifier.clone(),
12681                            work_done_progress_params: Default::default(),
12682                            partial_result_params: lsp::PartialResultParams {
12683                                partial_result_token: Some(lsp::ProgressToken::String(token)),
12684                            },
12685                        },
12686                        select(timer, progress).then(|either| match either {
12687                            Either::Left((message, ..)) => ready(message).left_future(),
12688                            Either::Right(..) => pending::<String>().right_future(),
12689                        }),
12690                    )
12691                    .await;
12692
12693                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
12694                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
12695                match response_result {
12696                    ConnectionResult::Timeout => {
12697                        log::error!("Timeout during workspace diagnostics pull");
12698                        continue 'request;
12699                    }
12700                    ConnectionResult::ConnectionReset => {
12701                        log::error!("Server closed a workspace diagnostics pull request");
12702                        continue 'request;
12703                    }
12704                    ConnectionResult::Result(Err(e)) => {
12705                        log::error!("Error during workspace diagnostics pull: {e:#}");
12706                        break 'request;
12707                    }
12708                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
12709                        attempts = 0;
12710                        if lsp_store
12711                            .update(cx, |lsp_store, cx| {
12712                                lsp_store.apply_workspace_diagnostic_report(
12713                                    server.server_id(),
12714                                    pulled_diagnostics,
12715                                    cx,
12716                                )
12717                            })
12718                            .is_err()
12719                        {
12720                            return;
12721                        }
12722                        break 'request;
12723                    }
12724                }
12725            }
12726        }
12727    });
12728
12729    Some(WorkspaceRefreshTask {
12730        refresh_tx,
12731        progress_tx,
12732        task: workspace_query_language_server,
12733    })
12734}
12735
12736fn diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<Option<String>> {
12737    match &options {
12738        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
12739            if !diagnostic_options.workspace_diagnostics {
12740                return None;
12741            }
12742            Some(diagnostic_options.identifier.clone())
12743        }
12744        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
12745            let diagnostic_options = &registration_options.diagnostic_options;
12746            if !diagnostic_options.workspace_diagnostics {
12747                return None;
12748            }
12749            Some(diagnostic_options.identifier.clone())
12750        }
12751    }
12752}
12753
12754fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
12755    let CompletionSource::BufferWord {
12756        word_range,
12757        resolved,
12758    } = &mut completion.source
12759    else {
12760        return;
12761    };
12762    if *resolved {
12763        return;
12764    }
12765
12766    if completion.new_text
12767        != snapshot
12768            .text_for_range(word_range.clone())
12769            .collect::<String>()
12770    {
12771        return;
12772    }
12773
12774    let mut offset = 0;
12775    for chunk in snapshot.chunks(word_range.clone(), true) {
12776        let end_offset = offset + chunk.text.len();
12777        if let Some(highlight_id) = chunk.syntax_highlight_id {
12778            completion
12779                .label
12780                .runs
12781                .push((offset..end_offset, highlight_id));
12782        }
12783        offset = end_offset;
12784    }
12785    *resolved = true;
12786}
12787
12788impl EventEmitter<LspStoreEvent> for LspStore {}
12789
12790fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
12791    hover
12792        .contents
12793        .retain(|hover_block| !hover_block.text.trim().is_empty());
12794    if hover.contents.is_empty() {
12795        None
12796    } else {
12797        Some(hover)
12798    }
12799}
12800
12801async fn populate_labels_for_completions(
12802    new_completions: Vec<CoreCompletion>,
12803    language: Option<Arc<Language>>,
12804    lsp_adapter: Option<Arc<CachedLspAdapter>>,
12805) -> Vec<Completion> {
12806    let lsp_completions = new_completions
12807        .iter()
12808        .filter_map(|new_completion| {
12809            new_completion
12810                .source
12811                .lsp_completion(true)
12812                .map(|lsp_completion| lsp_completion.into_owned())
12813        })
12814        .collect::<Vec<_>>();
12815
12816    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
12817        lsp_adapter
12818            .labels_for_completions(&lsp_completions, language)
12819            .await
12820            .log_err()
12821            .unwrap_or_default()
12822    } else {
12823        Vec::new()
12824    }
12825    .into_iter()
12826    .fuse();
12827
12828    let mut completions = Vec::new();
12829    for completion in new_completions {
12830        match completion.source.lsp_completion(true) {
12831            Some(lsp_completion) => {
12832                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
12833
12834                let mut label = labels.next().flatten().unwrap_or_else(|| {
12835                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
12836                });
12837                ensure_uniform_list_compatible_label(&mut label);
12838                completions.push(Completion {
12839                    label,
12840                    documentation,
12841                    replace_range: completion.replace_range,
12842                    new_text: completion.new_text,
12843                    insert_text_mode: lsp_completion.insert_text_mode,
12844                    source: completion.source,
12845                    icon_path: None,
12846                    confirm: None,
12847                });
12848            }
12849            None => {
12850                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
12851                ensure_uniform_list_compatible_label(&mut label);
12852                completions.push(Completion {
12853                    label,
12854                    documentation: None,
12855                    replace_range: completion.replace_range,
12856                    new_text: completion.new_text,
12857                    source: completion.source,
12858                    insert_text_mode: None,
12859                    icon_path: None,
12860                    confirm: None,
12861                });
12862            }
12863        }
12864    }
12865    completions
12866}
12867
12868#[derive(Debug)]
12869pub enum LanguageServerToQuery {
12870    /// Query language servers in order of users preference, up until one capable of handling the request is found.
12871    FirstCapable,
12872    /// Query a specific language server.
12873    Other(LanguageServerId),
12874}
12875
12876#[derive(Default)]
12877struct RenamePathsWatchedForServer {
12878    did_rename: Vec<RenameActionPredicate>,
12879    will_rename: Vec<RenameActionPredicate>,
12880}
12881
12882impl RenamePathsWatchedForServer {
12883    fn with_did_rename_patterns(
12884        mut self,
12885        did_rename: Option<&FileOperationRegistrationOptions>,
12886    ) -> Self {
12887        if let Some(did_rename) = did_rename {
12888            self.did_rename = did_rename
12889                .filters
12890                .iter()
12891                .filter_map(|filter| filter.try_into().log_err())
12892                .collect();
12893        }
12894        self
12895    }
12896    fn with_will_rename_patterns(
12897        mut self,
12898        will_rename: Option<&FileOperationRegistrationOptions>,
12899    ) -> Self {
12900        if let Some(will_rename) = will_rename {
12901            self.will_rename = will_rename
12902                .filters
12903                .iter()
12904                .filter_map(|filter| filter.try_into().log_err())
12905                .collect();
12906        }
12907        self
12908    }
12909
12910    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
12911        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
12912    }
12913    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
12914        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
12915    }
12916}
12917
12918impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
12919    type Error = globset::Error;
12920    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
12921        Ok(Self {
12922            kind: ops.pattern.matches.clone(),
12923            glob: GlobBuilder::new(&ops.pattern.glob)
12924                .case_insensitive(
12925                    ops.pattern
12926                        .options
12927                        .as_ref()
12928                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
12929                )
12930                .build()?
12931                .compile_matcher(),
12932        })
12933    }
12934}
12935struct RenameActionPredicate {
12936    glob: GlobMatcher,
12937    kind: Option<FileOperationPatternKind>,
12938}
12939
12940impl RenameActionPredicate {
12941    // Returns true if language server should be notified
12942    fn eval(&self, path: &str, is_dir: bool) -> bool {
12943        self.kind.as_ref().is_none_or(|kind| {
12944            let expected_kind = if is_dir {
12945                FileOperationPatternKind::Folder
12946            } else {
12947                FileOperationPatternKind::File
12948            };
12949            kind == &expected_kind
12950        }) && self.glob.is_match(path)
12951    }
12952}
12953
12954#[derive(Default)]
12955struct LanguageServerWatchedPaths {
12956    worktree_paths: HashMap<WorktreeId, GlobSet>,
12957    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
12958}
12959
12960#[derive(Default)]
12961struct LanguageServerWatchedPathsBuilder {
12962    worktree_paths: HashMap<WorktreeId, GlobSet>,
12963    abs_paths: HashMap<Arc<Path>, GlobSet>,
12964}
12965
12966impl LanguageServerWatchedPathsBuilder {
12967    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
12968        self.worktree_paths.insert(worktree_id, glob_set);
12969    }
12970    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
12971        self.abs_paths.insert(path, glob_set);
12972    }
12973    fn build(
12974        self,
12975        fs: Arc<dyn Fs>,
12976        language_server_id: LanguageServerId,
12977        cx: &mut Context<LspStore>,
12978    ) -> LanguageServerWatchedPaths {
12979        let lsp_store = cx.weak_entity();
12980
12981        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
12982        let abs_paths = self
12983            .abs_paths
12984            .into_iter()
12985            .map(|(abs_path, globset)| {
12986                let task = cx.spawn({
12987                    let abs_path = abs_path.clone();
12988                    let fs = fs.clone();
12989
12990                    let lsp_store = lsp_store.clone();
12991                    async move |_, cx| {
12992                        maybe!(async move {
12993                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
12994                            while let Some(update) = push_updates.0.next().await {
12995                                let action = lsp_store
12996                                    .update(cx, |this, _| {
12997                                        let Some(local) = this.as_local() else {
12998                                            return ControlFlow::Break(());
12999                                        };
13000                                        let Some(watcher) = local
13001                                            .language_server_watched_paths
13002                                            .get(&language_server_id)
13003                                        else {
13004                                            return ControlFlow::Break(());
13005                                        };
13006                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13007                                            "Watched abs path is not registered with a watcher",
13008                                        );
13009                                        let matching_entries = update
13010                                            .into_iter()
13011                                            .filter(|event| globs.is_match(&event.path))
13012                                            .collect::<Vec<_>>();
13013                                        this.lsp_notify_abs_paths_changed(
13014                                            language_server_id,
13015                                            matching_entries,
13016                                        );
13017                                        ControlFlow::Continue(())
13018                                    })
13019                                    .ok()?;
13020
13021                                if action.is_break() {
13022                                    break;
13023                                }
13024                            }
13025                            Some(())
13026                        })
13027                        .await;
13028                    }
13029                });
13030                (abs_path, (globset, task))
13031            })
13032            .collect();
13033        LanguageServerWatchedPaths {
13034            worktree_paths: self.worktree_paths,
13035            abs_paths,
13036        }
13037    }
13038}
13039
13040struct LspBufferSnapshot {
13041    version: i32,
13042    snapshot: TextBufferSnapshot,
13043}
13044
13045/// A prompt requested by LSP server.
13046#[derive(Clone, Debug)]
13047pub struct LanguageServerPromptRequest {
13048    pub level: PromptLevel,
13049    pub message: String,
13050    pub actions: Vec<MessageActionItem>,
13051    pub lsp_name: String,
13052    pub(crate) response_channel: Sender<MessageActionItem>,
13053}
13054
13055impl LanguageServerPromptRequest {
13056    pub async fn respond(self, index: usize) -> Option<()> {
13057        if let Some(response) = self.actions.into_iter().nth(index) {
13058            self.response_channel.send(response).await.ok()
13059        } else {
13060            None
13061        }
13062    }
13063}
13064impl PartialEq for LanguageServerPromptRequest {
13065    fn eq(&self, other: &Self) -> bool {
13066        self.message == other.message && self.actions == other.actions
13067    }
13068}
13069
13070#[derive(Clone, Debug, PartialEq)]
13071pub enum LanguageServerLogType {
13072    Log(MessageType),
13073    Trace { verbose_info: Option<String> },
13074    Rpc { received: bool },
13075}
13076
13077impl LanguageServerLogType {
13078    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13079        match self {
13080            Self::Log(log_type) => {
13081                use proto::log_message::LogLevel;
13082                let level = match *log_type {
13083                    MessageType::ERROR => LogLevel::Error,
13084                    MessageType::WARNING => LogLevel::Warning,
13085                    MessageType::INFO => LogLevel::Info,
13086                    MessageType::LOG => LogLevel::Log,
13087                    other => {
13088                        log::warn!("Unknown lsp log message type: {other:?}");
13089                        LogLevel::Log
13090                    }
13091                };
13092                proto::language_server_log::LogType::Log(proto::LogMessage {
13093                    level: level as i32,
13094                })
13095            }
13096            Self::Trace { verbose_info } => {
13097                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13098                    verbose_info: verbose_info.to_owned(),
13099                })
13100            }
13101            Self::Rpc { received } => {
13102                let kind = if *received {
13103                    proto::rpc_message::Kind::Received
13104                } else {
13105                    proto::rpc_message::Kind::Sent
13106                };
13107                let kind = kind as i32;
13108                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13109            }
13110        }
13111    }
13112
13113    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13114        use proto::log_message::LogLevel;
13115        use proto::rpc_message;
13116        match log_type {
13117            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13118                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13119                    LogLevel::Error => MessageType::ERROR,
13120                    LogLevel::Warning => MessageType::WARNING,
13121                    LogLevel::Info => MessageType::INFO,
13122                    LogLevel::Log => MessageType::LOG,
13123                },
13124            ),
13125            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13126                verbose_info: trace_message.verbose_info,
13127            },
13128            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13129                received: match rpc_message::Kind::from_i32(message.kind)
13130                    .unwrap_or(rpc_message::Kind::Received)
13131                {
13132                    rpc_message::Kind::Received => true,
13133                    rpc_message::Kind::Sent => false,
13134                },
13135            },
13136        }
13137    }
13138}
13139
13140pub struct WorkspaceRefreshTask {
13141    refresh_tx: mpsc::Sender<()>,
13142    progress_tx: mpsc::Sender<()>,
13143    #[allow(dead_code)]
13144    task: Task<()>,
13145}
13146
13147pub enum LanguageServerState {
13148    Starting {
13149        startup: Task<Option<Arc<LanguageServer>>>,
13150        /// List of language servers that will be added to the workspace once it's initialization completes.
13151        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13152    },
13153
13154    Running {
13155        adapter: Arc<CachedLspAdapter>,
13156        server: Arc<LanguageServer>,
13157        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13158        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13159    },
13160}
13161
13162impl LanguageServerState {
13163    fn add_workspace_folder(&self, uri: Uri) {
13164        match self {
13165            LanguageServerState::Starting {
13166                pending_workspace_folders,
13167                ..
13168            } => {
13169                pending_workspace_folders.lock().insert(uri);
13170            }
13171            LanguageServerState::Running { server, .. } => {
13172                server.add_workspace_folder(uri);
13173            }
13174        }
13175    }
13176    fn _remove_workspace_folder(&self, uri: Uri) {
13177        match self {
13178            LanguageServerState::Starting {
13179                pending_workspace_folders,
13180                ..
13181            } => {
13182                pending_workspace_folders.lock().remove(&uri);
13183            }
13184            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13185        }
13186    }
13187}
13188
13189impl std::fmt::Debug for LanguageServerState {
13190    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13191        match self {
13192            LanguageServerState::Starting { .. } => {
13193                f.debug_struct("LanguageServerState::Starting").finish()
13194            }
13195            LanguageServerState::Running { .. } => {
13196                f.debug_struct("LanguageServerState::Running").finish()
13197            }
13198        }
13199    }
13200}
13201
13202#[derive(Clone, Debug, Serialize)]
13203pub struct LanguageServerProgress {
13204    pub is_disk_based_diagnostics_progress: bool,
13205    pub is_cancellable: bool,
13206    pub title: Option<String>,
13207    pub message: Option<String>,
13208    pub percentage: Option<usize>,
13209    #[serde(skip_serializing)]
13210    pub last_update_at: Instant,
13211}
13212
13213#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13214pub struct DiagnosticSummary {
13215    pub error_count: usize,
13216    pub warning_count: usize,
13217}
13218
13219impl DiagnosticSummary {
13220    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13221        let mut this = Self {
13222            error_count: 0,
13223            warning_count: 0,
13224        };
13225
13226        for entry in diagnostics {
13227            if entry.diagnostic.is_primary {
13228                match entry.diagnostic.severity {
13229                    DiagnosticSeverity::ERROR => this.error_count += 1,
13230                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13231                    _ => {}
13232                }
13233            }
13234        }
13235
13236        this
13237    }
13238
13239    pub fn is_empty(&self) -> bool {
13240        self.error_count == 0 && self.warning_count == 0
13241    }
13242
13243    pub fn to_proto(
13244        self,
13245        language_server_id: LanguageServerId,
13246        path: &RelPath,
13247    ) -> proto::DiagnosticSummary {
13248        proto::DiagnosticSummary {
13249            path: path.to_proto(),
13250            language_server_id: language_server_id.0 as u64,
13251            error_count: self.error_count as u32,
13252            warning_count: self.warning_count as u32,
13253        }
13254    }
13255}
13256
13257#[derive(Clone, Debug)]
13258pub enum CompletionDocumentation {
13259    /// There is no documentation for this completion.
13260    Undocumented,
13261    /// A single line of documentation.
13262    SingleLine(SharedString),
13263    /// Multiple lines of plain text documentation.
13264    MultiLinePlainText(SharedString),
13265    /// Markdown documentation.
13266    MultiLineMarkdown(SharedString),
13267    /// Both single line and multiple lines of plain text documentation.
13268    SingleLineAndMultiLinePlainText {
13269        single_line: SharedString,
13270        plain_text: Option<SharedString>,
13271    },
13272}
13273
13274impl CompletionDocumentation {
13275    #[cfg(any(test, feature = "test-support"))]
13276    pub fn text(&self) -> SharedString {
13277        match self {
13278            CompletionDocumentation::Undocumented => "".into(),
13279            CompletionDocumentation::SingleLine(s) => s.clone(),
13280            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13281            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13282            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13283                single_line.clone()
13284            }
13285        }
13286    }
13287}
13288
13289impl From<lsp::Documentation> for CompletionDocumentation {
13290    fn from(docs: lsp::Documentation) -> Self {
13291        match docs {
13292            lsp::Documentation::String(text) => {
13293                if text.lines().count() <= 1 {
13294                    CompletionDocumentation::SingleLine(text.into())
13295                } else {
13296                    CompletionDocumentation::MultiLinePlainText(text.into())
13297                }
13298            }
13299
13300            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13301                lsp::MarkupKind::PlainText => {
13302                    if value.lines().count() <= 1 {
13303                        CompletionDocumentation::SingleLine(value.into())
13304                    } else {
13305                        CompletionDocumentation::MultiLinePlainText(value.into())
13306                    }
13307                }
13308
13309                lsp::MarkupKind::Markdown => {
13310                    CompletionDocumentation::MultiLineMarkdown(value.into())
13311                }
13312            },
13313        }
13314    }
13315}
13316
13317pub enum ResolvedHint {
13318    Resolved(InlayHint),
13319    Resolving(Shared<Task<()>>),
13320}
13321
13322fn glob_literal_prefix(glob: &Path) -> PathBuf {
13323    glob.components()
13324        .take_while(|component| match component {
13325            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13326            _ => true,
13327        })
13328        .collect()
13329}
13330
13331pub struct SshLspAdapter {
13332    name: LanguageServerName,
13333    binary: LanguageServerBinary,
13334    initialization_options: Option<String>,
13335    code_action_kinds: Option<Vec<CodeActionKind>>,
13336}
13337
13338impl SshLspAdapter {
13339    pub fn new(
13340        name: LanguageServerName,
13341        binary: LanguageServerBinary,
13342        initialization_options: Option<String>,
13343        code_action_kinds: Option<String>,
13344    ) -> Self {
13345        Self {
13346            name,
13347            binary,
13348            initialization_options,
13349            code_action_kinds: code_action_kinds
13350                .as_ref()
13351                .and_then(|c| serde_json::from_str(c).ok()),
13352        }
13353    }
13354}
13355
13356impl LspInstaller for SshLspAdapter {
13357    type BinaryVersion = ();
13358    async fn check_if_user_installed(
13359        &self,
13360        _: &dyn LspAdapterDelegate,
13361        _: Option<Toolchain>,
13362        _: &AsyncApp,
13363    ) -> Option<LanguageServerBinary> {
13364        Some(self.binary.clone())
13365    }
13366
13367    async fn cached_server_binary(
13368        &self,
13369        _: PathBuf,
13370        _: &dyn LspAdapterDelegate,
13371    ) -> Option<LanguageServerBinary> {
13372        None
13373    }
13374
13375    async fn fetch_latest_server_version(
13376        &self,
13377        _: &dyn LspAdapterDelegate,
13378        _: bool,
13379        _: &mut AsyncApp,
13380    ) -> Result<()> {
13381        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13382    }
13383
13384    async fn fetch_server_binary(
13385        &self,
13386        _: (),
13387        _: PathBuf,
13388        _: &dyn LspAdapterDelegate,
13389    ) -> Result<LanguageServerBinary> {
13390        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13391    }
13392}
13393
13394#[async_trait(?Send)]
13395impl LspAdapter for SshLspAdapter {
13396    fn name(&self) -> LanguageServerName {
13397        self.name.clone()
13398    }
13399
13400    async fn initialization_options(
13401        self: Arc<Self>,
13402        _: &Arc<dyn LspAdapterDelegate>,
13403    ) -> Result<Option<serde_json::Value>> {
13404        let Some(options) = &self.initialization_options else {
13405            return Ok(None);
13406        };
13407        let result = serde_json::from_str(options)?;
13408        Ok(result)
13409    }
13410
13411    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13412        self.code_action_kinds.clone()
13413    }
13414}
13415
13416pub fn language_server_settings<'a>(
13417    delegate: &'a dyn LspAdapterDelegate,
13418    language: &LanguageServerName,
13419    cx: &'a App,
13420) -> Option<&'a LspSettings> {
13421    language_server_settings_for(
13422        SettingsLocation {
13423            worktree_id: delegate.worktree_id(),
13424            path: RelPath::empty(),
13425        },
13426        language,
13427        cx,
13428    )
13429}
13430
13431pub(crate) fn language_server_settings_for<'a>(
13432    location: SettingsLocation<'a>,
13433    language: &LanguageServerName,
13434    cx: &'a App,
13435) -> Option<&'a LspSettings> {
13436    ProjectSettings::get(Some(location), cx).lsp.get(language)
13437}
13438
13439pub struct LocalLspAdapterDelegate {
13440    lsp_store: WeakEntity<LspStore>,
13441    worktree: worktree::Snapshot,
13442    fs: Arc<dyn Fs>,
13443    http_client: Arc<dyn HttpClient>,
13444    language_registry: Arc<LanguageRegistry>,
13445    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13446}
13447
13448impl LocalLspAdapterDelegate {
13449    pub fn new(
13450        language_registry: Arc<LanguageRegistry>,
13451        environment: &Entity<ProjectEnvironment>,
13452        lsp_store: WeakEntity<LspStore>,
13453        worktree: &Entity<Worktree>,
13454        http_client: Arc<dyn HttpClient>,
13455        fs: Arc<dyn Fs>,
13456        cx: &mut App,
13457    ) -> Arc<Self> {
13458        let load_shell_env_task =
13459            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
13460
13461        Arc::new(Self {
13462            lsp_store,
13463            worktree: worktree.read(cx).snapshot(),
13464            fs,
13465            http_client,
13466            language_registry,
13467            load_shell_env_task,
13468        })
13469    }
13470
13471    fn from_local_lsp(
13472        local: &LocalLspStore,
13473        worktree: &Entity<Worktree>,
13474        cx: &mut App,
13475    ) -> Arc<Self> {
13476        Self::new(
13477            local.languages.clone(),
13478            &local.environment,
13479            local.weak.clone(),
13480            worktree,
13481            local.http_client.clone(),
13482            local.fs.clone(),
13483            cx,
13484        )
13485    }
13486}
13487
13488#[async_trait]
13489impl LspAdapterDelegate for LocalLspAdapterDelegate {
13490    fn show_notification(&self, message: &str, cx: &mut App) {
13491        self.lsp_store
13492            .update(cx, |_, cx| {
13493                cx.emit(LspStoreEvent::Notification(message.to_owned()))
13494            })
13495            .ok();
13496    }
13497
13498    fn http_client(&self) -> Arc<dyn HttpClient> {
13499        self.http_client.clone()
13500    }
13501
13502    fn worktree_id(&self) -> WorktreeId {
13503        self.worktree.id()
13504    }
13505
13506    fn worktree_root_path(&self) -> &Path {
13507        self.worktree.abs_path().as_ref()
13508    }
13509
13510    async fn shell_env(&self) -> HashMap<String, String> {
13511        let task = self.load_shell_env_task.clone();
13512        task.await.unwrap_or_default()
13513    }
13514
13515    async fn npm_package_installed_version(
13516        &self,
13517        package_name: &str,
13518    ) -> Result<Option<(PathBuf, String)>> {
13519        let local_package_directory = self.worktree_root_path();
13520        let node_modules_directory = local_package_directory.join("node_modules");
13521
13522        if let Some(version) =
13523            read_package_installed_version(node_modules_directory.clone(), package_name).await?
13524        {
13525            return Ok(Some((node_modules_directory, version)));
13526        }
13527        let Some(npm) = self.which("npm".as_ref()).await else {
13528            log::warn!(
13529                "Failed to find npm executable for {:?}",
13530                local_package_directory
13531            );
13532            return Ok(None);
13533        };
13534
13535        let env = self.shell_env().await;
13536        let output = util::command::new_smol_command(&npm)
13537            .args(["root", "-g"])
13538            .envs(env)
13539            .current_dir(local_package_directory)
13540            .output()
13541            .await?;
13542        let global_node_modules =
13543            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
13544
13545        if let Some(version) =
13546            read_package_installed_version(global_node_modules.clone(), package_name).await?
13547        {
13548            return Ok(Some((global_node_modules, version)));
13549        }
13550        return Ok(None);
13551    }
13552
13553    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
13554        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
13555        if self.fs.is_file(&worktree_abs_path).await {
13556            worktree_abs_path.pop();
13557        }
13558
13559        let env = self.shell_env().await;
13560
13561        let shell_path = env.get("PATH").cloned();
13562
13563        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
13564    }
13565
13566    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
13567        let mut working_dir = self.worktree_root_path().to_path_buf();
13568        if self.fs.is_file(&working_dir).await {
13569            working_dir.pop();
13570        }
13571        let output = util::command::new_smol_command(&command.path)
13572            .args(command.arguments)
13573            .envs(command.env.clone().unwrap_or_default())
13574            .current_dir(working_dir)
13575            .output()
13576            .await?;
13577
13578        anyhow::ensure!(
13579            output.status.success(),
13580            "{}, stdout: {:?}, stderr: {:?}",
13581            output.status,
13582            String::from_utf8_lossy(&output.stdout),
13583            String::from_utf8_lossy(&output.stderr)
13584        );
13585        Ok(())
13586    }
13587
13588    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
13589        self.language_registry
13590            .update_lsp_binary_status(server_name, status);
13591    }
13592
13593    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
13594        self.language_registry
13595            .all_lsp_adapters()
13596            .into_iter()
13597            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
13598            .collect()
13599    }
13600
13601    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
13602        let dir = self.language_registry.language_server_download_dir(name)?;
13603
13604        if !dir.exists() {
13605            smol::fs::create_dir_all(&dir)
13606                .await
13607                .context("failed to create container directory")
13608                .log_err()?;
13609        }
13610
13611        Some(dir)
13612    }
13613
13614    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
13615        let entry = self
13616            .worktree
13617            .entry_for_path(path)
13618            .with_context(|| format!("no worktree entry for path {path:?}"))?;
13619        let abs_path = self.worktree.absolutize(&entry.path);
13620        self.fs.load(&abs_path).await
13621    }
13622}
13623
13624async fn populate_labels_for_symbols(
13625    symbols: Vec<CoreSymbol>,
13626    language_registry: &Arc<LanguageRegistry>,
13627    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13628    output: &mut Vec<Symbol>,
13629) {
13630    #[allow(clippy::mutable_key_type)]
13631    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
13632
13633    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
13634    for symbol in symbols {
13635        let Some(file_name) = symbol.path.file_name() else {
13636            continue;
13637        };
13638        let language = language_registry
13639            .load_language_for_file_path(Path::new(file_name))
13640            .await
13641            .ok()
13642            .or_else(|| {
13643                unknown_paths.insert(file_name.into());
13644                None
13645            });
13646        symbols_by_language
13647            .entry(language)
13648            .or_default()
13649            .push(symbol);
13650    }
13651
13652    for unknown_path in unknown_paths {
13653        log::info!("no language found for symbol in file {unknown_path:?}");
13654    }
13655
13656    let mut label_params = Vec::new();
13657    for (language, mut symbols) in symbols_by_language {
13658        label_params.clear();
13659        label_params.extend(
13660            symbols
13661                .iter_mut()
13662                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
13663        );
13664
13665        let mut labels = Vec::new();
13666        if let Some(language) = language {
13667            let lsp_adapter = lsp_adapter.clone().or_else(|| {
13668                language_registry
13669                    .lsp_adapters(&language.name())
13670                    .first()
13671                    .cloned()
13672            });
13673            if let Some(lsp_adapter) = lsp_adapter {
13674                labels = lsp_adapter
13675                    .labels_for_symbols(&label_params, &language)
13676                    .await
13677                    .log_err()
13678                    .unwrap_or_default();
13679            }
13680        }
13681
13682        for ((symbol, (name, _)), label) in symbols
13683            .into_iter()
13684            .zip(label_params.drain(..))
13685            .zip(labels.into_iter().chain(iter::repeat(None)))
13686        {
13687            output.push(Symbol {
13688                language_server_name: symbol.language_server_name,
13689                source_worktree_id: symbol.source_worktree_id,
13690                source_language_server_id: symbol.source_language_server_id,
13691                path: symbol.path,
13692                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
13693                name,
13694                kind: symbol.kind,
13695                range: symbol.range,
13696            });
13697        }
13698    }
13699}
13700
13701fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
13702    match server.capabilities().text_document_sync.as_ref()? {
13703        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
13704            // Server wants didSave but didn't specify includeText.
13705            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
13706            // Server doesn't want didSave at all.
13707            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
13708            // Server provided SaveOptions.
13709            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
13710                Some(save_options.include_text.unwrap_or(false))
13711            }
13712        },
13713        // We do not have any save info. Kind affects didChange only.
13714        lsp::TextDocumentSyncCapability::Kind(_) => None,
13715    }
13716}
13717
13718/// Completion items are displayed in a `UniformList`.
13719/// Usually, those items are single-line strings, but in LSP responses,
13720/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
13721/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
13722/// 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,
13723/// breaking the completions menu presentation.
13724///
13725/// 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.
13726fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
13727    let mut new_text = String::with_capacity(label.text.len());
13728    let mut offset_map = vec![0; label.text.len() + 1];
13729    let mut last_char_was_space = false;
13730    let mut new_idx = 0;
13731    let chars = label.text.char_indices().fuse();
13732    let mut newlines_removed = false;
13733
13734    for (idx, c) in chars {
13735        offset_map[idx] = new_idx;
13736
13737        match c {
13738            '\n' if last_char_was_space => {
13739                newlines_removed = true;
13740            }
13741            '\t' | ' ' if last_char_was_space => {}
13742            '\n' if !last_char_was_space => {
13743                new_text.push(' ');
13744                new_idx += 1;
13745                last_char_was_space = true;
13746                newlines_removed = true;
13747            }
13748            ' ' | '\t' => {
13749                new_text.push(' ');
13750                new_idx += 1;
13751                last_char_was_space = true;
13752            }
13753            _ => {
13754                new_text.push(c);
13755                new_idx += c.len_utf8();
13756                last_char_was_space = false;
13757            }
13758        }
13759    }
13760    offset_map[label.text.len()] = new_idx;
13761
13762    // Only modify the label if newlines were removed.
13763    if !newlines_removed {
13764        return;
13765    }
13766
13767    let last_index = new_idx;
13768    let mut run_ranges_errors = Vec::new();
13769    label.runs.retain_mut(|(range, _)| {
13770        match offset_map.get(range.start) {
13771            Some(&start) => range.start = start,
13772            None => {
13773                run_ranges_errors.push(range.clone());
13774                return false;
13775            }
13776        }
13777
13778        match offset_map.get(range.end) {
13779            Some(&end) => range.end = end,
13780            None => {
13781                run_ranges_errors.push(range.clone());
13782                range.end = last_index;
13783            }
13784        }
13785        true
13786    });
13787    if !run_ranges_errors.is_empty() {
13788        log::error!(
13789            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
13790            label.text
13791        );
13792    }
13793
13794    let mut wrong_filter_range = None;
13795    if label.filter_range == (0..label.text.len()) {
13796        label.filter_range = 0..new_text.len();
13797    } else {
13798        let mut original_filter_range = Some(label.filter_range.clone());
13799        match offset_map.get(label.filter_range.start) {
13800            Some(&start) => label.filter_range.start = start,
13801            None => {
13802                wrong_filter_range = original_filter_range.take();
13803                label.filter_range.start = last_index;
13804            }
13805        }
13806
13807        match offset_map.get(label.filter_range.end) {
13808            Some(&end) => label.filter_range.end = end,
13809            None => {
13810                wrong_filter_range = original_filter_range.take();
13811                label.filter_range.end = last_index;
13812            }
13813        }
13814    }
13815    if let Some(wrong_filter_range) = wrong_filter_range {
13816        log::error!(
13817            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
13818            label.text
13819        );
13820    }
13821
13822    label.text = new_text;
13823}
13824
13825#[cfg(test)]
13826mod tests {
13827    use language::HighlightId;
13828
13829    use super::*;
13830
13831    #[test]
13832    fn test_glob_literal_prefix() {
13833        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
13834        assert_eq!(
13835            glob_literal_prefix(Path::new("node_modules/**/*.js")),
13836            Path::new("node_modules")
13837        );
13838        assert_eq!(
13839            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13840            Path::new("foo")
13841        );
13842        assert_eq!(
13843            glob_literal_prefix(Path::new("foo/bar/baz.js")),
13844            Path::new("foo/bar/baz.js")
13845        );
13846
13847        #[cfg(target_os = "windows")]
13848        {
13849            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
13850            assert_eq!(
13851                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
13852                Path::new("node_modules")
13853            );
13854            assert_eq!(
13855                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13856                Path::new("foo")
13857            );
13858            assert_eq!(
13859                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
13860                Path::new("foo/bar/baz.js")
13861            );
13862        }
13863    }
13864
13865    #[test]
13866    fn test_multi_len_chars_normalization() {
13867        let mut label = CodeLabel::new(
13868            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
13869            0..6,
13870            vec![(0..6, HighlightId(1))],
13871        );
13872        ensure_uniform_list_compatible_label(&mut label);
13873        assert_eq!(
13874            label,
13875            CodeLabel::new(
13876                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
13877                0..6,
13878                vec![(0..6, HighlightId(1))],
13879            )
13880        );
13881    }
13882}