lsp_store.rs

    1//! LSP store provides unified access to the language server protocol.
    2//! The consumers of LSP store can interact with language servers without knowing exactly which language server they're interacting with.
    3//!
    4//! # Local/Remote LSP Stores
    5//! This module is split up into three distinct parts:
    6//! - [`LocalLspStore`], which is ran on the host machine (either project host or SSH host), that manages the lifecycle of language servers.
    7//! - [`RemoteLspStore`], which is ran on the remote machine (project guests) which is mostly about passing through the requests via RPC.
    8//!   The remote stores don't really care about which language server they're running against - they don't usually get to decide which language server is going to responsible for handling their request.
    9//! - [`LspStore`], which unifies the two under one consistent interface for interacting with language servers.
   10//!
   11//! Most of the interesting work happens at the local layer, as bulk of the complexity is with managing the lifecycle of language servers. The actual implementation of the LSP protocol is handled by [`lsp`] crate.
   12pub mod clangd_ext;
   13pub mod json_language_server_ext;
   14pub mod log_store;
   15pub mod lsp_ext_command;
   16pub mod rust_analyzer_ext;
   17pub mod vue_language_server_ext;
   18
   19mod inlay_hint_cache;
   20
   21use self::inlay_hint_cache::BufferInlayHints;
   22use crate::{
   23    CodeAction, ColorPresentation, Completion, CompletionDisplayOptions, CompletionResponse,
   24    CompletionSource, CoreCompletion, DocumentColor, Hover, InlayHint, InlayId, LocationLink,
   25    LspAction, LspPullDiagnostics, ManifestProvidersStore, Project, ProjectItem, ProjectPath,
   26    ProjectTransaction, PulledDiagnostics, ResolveState, Symbol,
   27    buffer_store::{BufferStore, BufferStoreEvent},
   28    environment::ProjectEnvironment,
   29    lsp_command::{self, *},
   30    lsp_store::{
   31        self,
   32        inlay_hint_cache::BufferChunk,
   33        log_store::{GlobalLogStore, LanguageServerKind},
   34    },
   35    manifest_tree::{
   36        LanguageServerTree, LanguageServerTreeNode, LaunchDisposition, ManifestQueryDelegate,
   37        ManifestTree,
   38    },
   39    prettier_store::{self, PrettierStore, PrettierStoreEvent},
   40    project_settings::{LspSettings, ProjectSettings},
   41    toolchain_store::{LocalToolchainStore, ToolchainStoreEvent},
   42    worktree_store::{WorktreeStore, WorktreeStoreEvent},
   43    yarn::YarnPathStore,
   44};
   45use anyhow::{Context as _, Result, anyhow};
   46use async_trait::async_trait;
   47use client::{TypedEnvelope, proto};
   48use clock::Global;
   49use collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map};
   50use futures::{
   51    AsyncWriteExt, Future, FutureExt, StreamExt,
   52    future::{Either, Shared, join_all, pending, select},
   53    select, select_biased,
   54    stream::FuturesUnordered,
   55};
   56use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
   57use gpui::{
   58    App, AppContext, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString, Task,
   59    WeakEntity,
   60};
   61use http_client::HttpClient;
   62use itertools::Itertools as _;
   63use language::{
   64    Bias, BinaryStatus, Buffer, BufferRow, BufferSnapshot, CachedLspAdapter, CodeLabel, Diagnostic,
   65    DiagnosticEntry, DiagnosticSet, DiagnosticSourceKind, Diff, File as _, Language, LanguageName,
   66    LanguageRegistry, LocalFile, LspAdapter, LspAdapterDelegate, LspInstaller, ManifestDelegate,
   67    ManifestName, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Toolchain,
   68    Transaction, Unclipped,
   69    language_settings::{FormatOnSave, Formatter, LanguageSettings, language_settings},
   70    point_to_lsp,
   71    proto::{
   72        deserialize_anchor, deserialize_lsp_edit, deserialize_version, serialize_anchor,
   73        serialize_lsp_edit, serialize_version,
   74    },
   75    range_from_lsp, range_to_lsp,
   76};
   77use lsp::{
   78    AdapterServerCapabilities, CodeActionKind, CompletionContext, CompletionOptions,
   79    DiagnosticServerCapabilities, DiagnosticSeverity, DiagnosticTag,
   80    DidChangeWatchedFilesRegistrationOptions, Edit, FileOperationFilter, FileOperationPatternKind,
   81    FileOperationRegistrationOptions, FileRename, FileSystemWatcher, LSP_REQUEST_TIMEOUT,
   82    LanguageServer, LanguageServerBinary, LanguageServerBinaryOptions, LanguageServerId,
   83    LanguageServerName, LanguageServerSelector, LspRequestFuture, MessageActionItem, MessageType,
   84    OneOf, RenameFilesParams, SymbolKind, TextDocumentSyncSaveOptions, TextEdit, Uri,
   85    WillRenameFiles, WorkDoneProgressCancelParams, WorkspaceFolder, notification::DidRenameFiles,
   86};
   87use node_runtime::read_package_installed_version;
   88use parking_lot::Mutex;
   89use postage::{mpsc, sink::Sink, stream::Stream, watch};
   90use rand::prelude::*;
   91use rpc::{
   92    AnyProtoClient, ErrorCode, ErrorExt as _,
   93    proto::{LspRequestId, LspRequestMessage as _},
   94};
   95use serde::Serialize;
   96use settings::{Settings, SettingsLocation, SettingsStore};
   97use sha2::{Digest, Sha256};
   98use smol::channel::Sender;
   99use snippet::Snippet;
  100use std::{
  101    any::TypeId,
  102    borrow::Cow,
  103    cell::RefCell,
  104    cmp::{Ordering, Reverse},
  105    convert::TryInto,
  106    ffi::OsStr,
  107    future::ready,
  108    iter, mem,
  109    ops::{ControlFlow, Range},
  110    path::{self, Path, PathBuf},
  111    pin::pin,
  112    rc::Rc,
  113    sync::{
  114        Arc,
  115        atomic::{self, AtomicUsize},
  116    },
  117    time::{Duration, Instant},
  118};
  119use sum_tree::Dimensions;
  120use text::{Anchor, BufferId, LineEnding, OffsetRangeExt, Point, ToPoint as _};
  121
  122use util::{
  123    ConnectionResult, ResultExt as _, debug_panic, defer, maybe, merge_json_value_into,
  124    paths::{PathStyle, SanitizedPath},
  125    post_inc,
  126    rel_path::RelPath,
  127};
  128
  129pub use fs::*;
  130pub use language::Location;
  131pub use lsp_store::inlay_hint_cache::{CacheInlayHints, InvalidationStrategy};
  132#[cfg(any(test, feature = "test-support"))]
  133pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;
  134pub use worktree::{
  135    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,
  136    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,
  137};
  138
  139const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);
  140pub const SERVER_PROGRESS_THROTTLE_TIMEOUT: Duration = Duration::from_millis(100);
  141const WORKSPACE_DIAGNOSTICS_TOKEN_START: &str = "id:";
  142
  143#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
  144pub enum ProgressToken {
  145    Number(i32),
  146    String(SharedString),
  147}
  148
  149impl std::fmt::Display for ProgressToken {
  150    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  151        match self {
  152            Self::Number(number) => write!(f, "{number}"),
  153            Self::String(string) => write!(f, "{string}"),
  154        }
  155    }
  156}
  157
  158impl ProgressToken {
  159    fn from_lsp(value: lsp::NumberOrString) -> Self {
  160        match value {
  161            lsp::NumberOrString::Number(number) => Self::Number(number),
  162            lsp::NumberOrString::String(string) => Self::String(SharedString::new(string)),
  163        }
  164    }
  165
  166    fn to_lsp(&self) -> lsp::NumberOrString {
  167        match self {
  168            Self::Number(number) => lsp::NumberOrString::Number(*number),
  169            Self::String(string) => lsp::NumberOrString::String(string.to_string()),
  170        }
  171    }
  172
  173    fn from_proto(value: proto::ProgressToken) -> Option<Self> {
  174        Some(match value.value? {
  175            proto::progress_token::Value::Number(number) => Self::Number(number),
  176            proto::progress_token::Value::String(string) => Self::String(SharedString::new(string)),
  177        })
  178    }
  179
  180    fn to_proto(&self) -> proto::ProgressToken {
  181        proto::ProgressToken {
  182            value: Some(match self {
  183                Self::Number(number) => proto::progress_token::Value::Number(*number),
  184                Self::String(string) => proto::progress_token::Value::String(string.to_string()),
  185            }),
  186        }
  187    }
  188}
  189
  190#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  191pub enum FormatTrigger {
  192    Save,
  193    Manual,
  194}
  195
  196pub enum LspFormatTarget {
  197    Buffers,
  198    Ranges(BTreeMap<BufferId, Vec<Range<Anchor>>>),
  199}
  200
  201pub type OpenLspBufferHandle = Entity<Entity<Buffer>>;
  202
  203impl FormatTrigger {
  204    fn from_proto(value: i32) -> FormatTrigger {
  205        match value {
  206            0 => FormatTrigger::Save,
  207            1 => FormatTrigger::Manual,
  208            _ => FormatTrigger::Save,
  209        }
  210    }
  211}
  212
  213#[derive(Clone)]
  214struct UnifiedLanguageServer {
  215    id: LanguageServerId,
  216    project_roots: HashSet<Arc<RelPath>>,
  217}
  218
  219#[derive(Clone, Hash, PartialEq, Eq)]
  220struct LanguageServerSeed {
  221    worktree_id: WorktreeId,
  222    name: LanguageServerName,
  223    toolchain: Option<Toolchain>,
  224    settings: Arc<LspSettings>,
  225}
  226
  227#[derive(Debug)]
  228pub struct DocumentDiagnosticsUpdate<'a, D> {
  229    pub diagnostics: D,
  230    pub result_id: Option<String>,
  231    pub server_id: LanguageServerId,
  232    pub disk_based_sources: Cow<'a, [String]>,
  233}
  234
  235pub struct DocumentDiagnostics {
  236    diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  237    document_abs_path: PathBuf,
  238    version: Option<i32>,
  239}
  240
  241#[derive(Default, Debug)]
  242struct DynamicRegistrations {
  243    did_change_watched_files: HashMap<String, Vec<FileSystemWatcher>>,
  244    diagnostics: HashMap<Option<String>, DiagnosticServerCapabilities>,
  245}
  246
  247pub struct LocalLspStore {
  248    weak: WeakEntity<LspStore>,
  249    worktree_store: Entity<WorktreeStore>,
  250    toolchain_store: Entity<LocalToolchainStore>,
  251    http_client: Arc<dyn HttpClient>,
  252    environment: Entity<ProjectEnvironment>,
  253    fs: Arc<dyn Fs>,
  254    languages: Arc<LanguageRegistry>,
  255    language_server_ids: HashMap<LanguageServerSeed, UnifiedLanguageServer>,
  256    yarn: Entity<YarnPathStore>,
  257    pub language_servers: HashMap<LanguageServerId, LanguageServerState>,
  258    buffers_being_formatted: HashSet<BufferId>,
  259    last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>,
  260    language_server_watched_paths: HashMap<LanguageServerId, LanguageServerWatchedPaths>,
  261    watched_manifest_filenames: HashSet<ManifestName>,
  262    language_server_paths_watched_for_rename:
  263        HashMap<LanguageServerId, RenamePathsWatchedForServer>,
  264    language_server_dynamic_registrations: HashMap<LanguageServerId, DynamicRegistrations>,
  265    supplementary_language_servers:
  266        HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>,
  267    prettier_store: Entity<PrettierStore>,
  268    next_diagnostic_group_id: usize,
  269    diagnostics: HashMap<
  270        WorktreeId,
  271        HashMap<
  272            Arc<RelPath>,
  273            Vec<(
  274                LanguageServerId,
  275                Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
  276            )>,
  277        >,
  278    >,
  279    buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots
  280    _subscription: gpui::Subscription,
  281    lsp_tree: LanguageServerTree,
  282    registered_buffers: HashMap<BufferId, usize>,
  283    buffers_opened_in_servers: HashMap<BufferId, HashSet<LanguageServerId>>,
  284    buffer_pull_diagnostics_result_ids: HashMap<LanguageServerId, HashMap<PathBuf, Option<String>>>,
  285}
  286
  287impl LocalLspStore {
  288    /// Returns the running language server for the given ID. Note if the language server is starting, it will not be returned.
  289    pub fn running_language_server_for_id(
  290        &self,
  291        id: LanguageServerId,
  292    ) -> Option<&Arc<LanguageServer>> {
  293        let language_server_state = self.language_servers.get(&id)?;
  294
  295        match language_server_state {
  296            LanguageServerState::Running { server, .. } => Some(server),
  297            LanguageServerState::Starting { .. } => None,
  298        }
  299    }
  300
  301    fn get_or_insert_language_server(
  302        &mut self,
  303        worktree_handle: &Entity<Worktree>,
  304        delegate: Arc<LocalLspAdapterDelegate>,
  305        disposition: &Arc<LaunchDisposition>,
  306        language_name: &LanguageName,
  307        cx: &mut App,
  308    ) -> LanguageServerId {
  309        let key = LanguageServerSeed {
  310            worktree_id: worktree_handle.read(cx).id(),
  311            name: disposition.server_name.clone(),
  312            settings: disposition.settings.clone(),
  313            toolchain: disposition.toolchain.clone(),
  314        };
  315        if let Some(state) = self.language_server_ids.get_mut(&key) {
  316            state.project_roots.insert(disposition.path.path.clone());
  317            state.id
  318        } else {
  319            let adapter = self
  320                .languages
  321                .lsp_adapters(language_name)
  322                .into_iter()
  323                .find(|adapter| adapter.name() == disposition.server_name)
  324                .expect("To find LSP adapter");
  325            let new_language_server_id = self.start_language_server(
  326                worktree_handle,
  327                delegate,
  328                adapter,
  329                disposition.settings.clone(),
  330                key.clone(),
  331                cx,
  332            );
  333            if let Some(state) = self.language_server_ids.get_mut(&key) {
  334                state.project_roots.insert(disposition.path.path.clone());
  335            } else {
  336                debug_assert!(
  337                    false,
  338                    "Expected `start_language_server` to ensure that `key` exists in a map"
  339                );
  340            }
  341            new_language_server_id
  342        }
  343    }
  344
  345    fn start_language_server(
  346        &mut self,
  347        worktree_handle: &Entity<Worktree>,
  348        delegate: Arc<LocalLspAdapterDelegate>,
  349        adapter: Arc<CachedLspAdapter>,
  350        settings: Arc<LspSettings>,
  351        key: LanguageServerSeed,
  352        cx: &mut App,
  353    ) -> LanguageServerId {
  354        let worktree = worktree_handle.read(cx);
  355
  356        let root_path = worktree.abs_path();
  357        let toolchain = key.toolchain.clone();
  358        let override_options = settings.initialization_options.clone();
  359
  360        let stderr_capture = Arc::new(Mutex::new(Some(String::new())));
  361
  362        let server_id = self.languages.next_language_server_id();
  363        log::trace!(
  364            "attempting to start language server {:?}, path: {root_path:?}, id: {server_id}",
  365            adapter.name.0
  366        );
  367
  368        let binary = self.get_language_server_binary(
  369            adapter.clone(),
  370            settings,
  371            toolchain.clone(),
  372            delegate.clone(),
  373            true,
  374            cx,
  375        );
  376        let pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>> = Default::default();
  377
  378        let pending_server = cx.spawn({
  379            let adapter = adapter.clone();
  380            let server_name = adapter.name.clone();
  381            let stderr_capture = stderr_capture.clone();
  382            #[cfg(any(test, feature = "test-support"))]
  383            let lsp_store = self.weak.clone();
  384            let pending_workspace_folders = pending_workspace_folders.clone();
  385            async move |cx| {
  386                let binary = binary.await?;
  387                #[cfg(any(test, feature = "test-support"))]
  388                if let Some(server) = lsp_store
  389                    .update(&mut cx.clone(), |this, cx| {
  390                        this.languages.create_fake_language_server(
  391                            server_id,
  392                            &server_name,
  393                            binary.clone(),
  394                            &mut cx.to_async(),
  395                        )
  396                    })
  397                    .ok()
  398                    .flatten()
  399                {
  400                    return Ok(server);
  401                }
  402
  403                let code_action_kinds = adapter.code_action_kinds();
  404                lsp::LanguageServer::new(
  405                    stderr_capture,
  406                    server_id,
  407                    server_name,
  408                    binary,
  409                    &root_path,
  410                    code_action_kinds,
  411                    Some(pending_workspace_folders),
  412                    cx,
  413                )
  414            }
  415        });
  416
  417        let startup = {
  418            let server_name = adapter.name.0.clone();
  419            let delegate = delegate as Arc<dyn LspAdapterDelegate>;
  420            let key = key.clone();
  421            let adapter = adapter.clone();
  422            let lsp_store = self.weak.clone();
  423            let pending_workspace_folders = pending_workspace_folders.clone();
  424
  425            let pull_diagnostics = ProjectSettings::get_global(cx)
  426                .diagnostics
  427                .lsp_pull_diagnostics
  428                .enabled;
  429            cx.spawn(async move |cx| {
  430                let result = async {
  431                    let language_server = pending_server.await?;
  432
  433                    let workspace_config = Self::workspace_configuration_for_adapter(
  434                        adapter.adapter.clone(),
  435                        &delegate,
  436                        toolchain,
  437                        cx,
  438                    )
  439                    .await?;
  440
  441                    let mut initialization_options = Self::initialization_options_for_adapter(
  442                        adapter.adapter.clone(),
  443                        &delegate,
  444                    )
  445                    .await?;
  446
  447                    match (&mut initialization_options, override_options) {
  448                        (Some(initialization_options), Some(override_options)) => {
  449                            merge_json_value_into(override_options, initialization_options);
  450                        }
  451                        (None, override_options) => initialization_options = override_options,
  452                        _ => {}
  453                    }
  454
  455                    let initialization_params = cx.update(|cx| {
  456                        let mut params =
  457                            language_server.default_initialize_params(pull_diagnostics, cx);
  458                        params.initialization_options = initialization_options;
  459                        adapter.adapter.prepare_initialize_params(params, cx)
  460                    })??;
  461
  462                    Self::setup_lsp_messages(
  463                        lsp_store.clone(),
  464                        &language_server,
  465                        delegate.clone(),
  466                        adapter.clone(),
  467                    );
  468
  469                    let did_change_configuration_params = lsp::DidChangeConfigurationParams {
  470                        settings: workspace_config,
  471                    };
  472                    let language_server = cx
  473                        .update(|cx| {
  474                            language_server.initialize(
  475                                initialization_params,
  476                                Arc::new(did_change_configuration_params.clone()),
  477                                cx,
  478                            )
  479                        })?
  480                        .await
  481                        .inspect_err(|_| {
  482                            if let Some(lsp_store) = lsp_store.upgrade() {
  483                                lsp_store
  484                                    .update(cx, |lsp_store, cx| {
  485                                        lsp_store.cleanup_lsp_data(server_id);
  486                                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id))
  487                                    })
  488                                    .ok();
  489                            }
  490                        })?;
  491
  492                    language_server.notify::<lsp::notification::DidChangeConfiguration>(
  493                        did_change_configuration_params,
  494                    )?;
  495
  496                    anyhow::Ok(language_server)
  497                }
  498                .await;
  499
  500                match result {
  501                    Ok(server) => {
  502                        lsp_store
  503                            .update(cx, |lsp_store, cx| {
  504                                lsp_store.insert_newly_running_language_server(
  505                                    adapter,
  506                                    server.clone(),
  507                                    server_id,
  508                                    key,
  509                                    pending_workspace_folders,
  510                                    cx,
  511                                );
  512                            })
  513                            .ok();
  514                        stderr_capture.lock().take();
  515                        Some(server)
  516                    }
  517
  518                    Err(err) => {
  519                        let log = stderr_capture.lock().take().unwrap_or_default();
  520                        delegate.update_status(
  521                            adapter.name(),
  522                            BinaryStatus::Failed {
  523                                error: if log.is_empty() {
  524                                    format!("{err:#}")
  525                                } else {
  526                                    format!("{err:#}\n-- stderr --\n{log}")
  527                                },
  528                            },
  529                        );
  530                        log::error!("Failed to start language server {server_name:?}: {err:?}");
  531                        if !log.is_empty() {
  532                            log::error!("server stderr: {log}");
  533                        }
  534                        None
  535                    }
  536                }
  537            })
  538        };
  539        let state = LanguageServerState::Starting {
  540            startup,
  541            pending_workspace_folders,
  542        };
  543
  544        self.languages
  545            .update_lsp_binary_status(adapter.name(), BinaryStatus::Starting);
  546
  547        self.language_servers.insert(server_id, state);
  548        self.language_server_ids
  549            .entry(key)
  550            .or_insert(UnifiedLanguageServer {
  551                id: server_id,
  552                project_roots: Default::default(),
  553            });
  554        server_id
  555    }
  556
  557    fn get_language_server_binary(
  558        &self,
  559        adapter: Arc<CachedLspAdapter>,
  560        settings: Arc<LspSettings>,
  561        toolchain: Option<Toolchain>,
  562        delegate: Arc<dyn LspAdapterDelegate>,
  563        allow_binary_download: bool,
  564        cx: &mut App,
  565    ) -> Task<Result<LanguageServerBinary>> {
  566        if let Some(settings) = &settings.binary
  567            && let Some(path) = settings.path.as_ref().map(PathBuf::from)
  568        {
  569            let settings = settings.clone();
  570
  571            return cx.background_spawn(async move {
  572                let mut env = delegate.shell_env().await;
  573                env.extend(settings.env.unwrap_or_default());
  574
  575                Ok(LanguageServerBinary {
  576                    // if `path` is absolute, `.join()` will keep it unmodified
  577                    path: delegate.worktree_root_path().join(path),
  578                    env: Some(env),
  579                    arguments: settings
  580                        .arguments
  581                        .unwrap_or_default()
  582                        .iter()
  583                        .map(Into::into)
  584                        .collect(),
  585                })
  586            });
  587        }
  588        let lsp_binary_options = LanguageServerBinaryOptions {
  589            allow_path_lookup: !settings
  590                .binary
  591                .as_ref()
  592                .and_then(|b| b.ignore_system_version)
  593                .unwrap_or_default(),
  594            allow_binary_download,
  595            pre_release: settings
  596                .fetch
  597                .as_ref()
  598                .and_then(|f| f.pre_release)
  599                .unwrap_or(false),
  600        };
  601
  602        cx.spawn(async move |cx| {
  603            let binary_result = adapter
  604                .clone()
  605                .get_language_server_command(delegate.clone(), toolchain, lsp_binary_options, cx)
  606                .await;
  607
  608            delegate.update_status(adapter.name.clone(), BinaryStatus::None);
  609
  610            let mut binary = binary_result?;
  611            let mut shell_env = delegate.shell_env().await;
  612
  613            shell_env.extend(binary.env.unwrap_or_default());
  614
  615            if let Some(settings) = settings.binary.as_ref() {
  616                if let Some(arguments) = &settings.arguments {
  617                    binary.arguments = arguments.iter().map(Into::into).collect();
  618                }
  619                if let Some(env) = &settings.env {
  620                    shell_env.extend(env.iter().map(|(k, v)| (k.clone(), v.clone())));
  621                }
  622            }
  623
  624            binary.env = Some(shell_env);
  625            Ok(binary)
  626        })
  627    }
  628
  629    fn setup_lsp_messages(
  630        lsp_store: WeakEntity<LspStore>,
  631        language_server: &LanguageServer,
  632        delegate: Arc<dyn LspAdapterDelegate>,
  633        adapter: Arc<CachedLspAdapter>,
  634    ) {
  635        let name = language_server.name();
  636        let server_id = language_server.server_id();
  637        language_server
  638            .on_notification::<lsp::notification::PublishDiagnostics, _>({
  639                let adapter = adapter.clone();
  640                let this = lsp_store.clone();
  641                move |mut params, cx| {
  642                    let adapter = adapter.clone();
  643                    if let Some(this) = this.upgrade() {
  644                        this.update(cx, |this, cx| {
  645                            {
  646                                let buffer = params
  647                                    .uri
  648                                    .to_file_path()
  649                                    .map(|file_path| this.get_buffer(&file_path, cx))
  650                                    .ok()
  651                                    .flatten();
  652                                adapter.process_diagnostics(&mut params, server_id, buffer);
  653                            }
  654
  655                            this.merge_lsp_diagnostics(
  656                                DiagnosticSourceKind::Pushed,
  657                                vec![DocumentDiagnosticsUpdate {
  658                                    server_id,
  659                                    diagnostics: params,
  660                                    result_id: None,
  661                                    disk_based_sources: Cow::Borrowed(
  662                                        &adapter.disk_based_diagnostic_sources,
  663                                    ),
  664                                }],
  665                                |_, diagnostic, cx| match diagnostic.source_kind {
  666                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
  667                                        adapter.retain_old_diagnostic(diagnostic, cx)
  668                                    }
  669                                    DiagnosticSourceKind::Pulled => true,
  670                                },
  671                                cx,
  672                            )
  673                            .log_err();
  674                        })
  675                        .ok();
  676                    }
  677                }
  678            })
  679            .detach();
  680        language_server
  681            .on_request::<lsp::request::WorkspaceConfiguration, _, _>({
  682                let adapter = adapter.adapter.clone();
  683                let delegate = delegate.clone();
  684                let this = lsp_store.clone();
  685                move |params, cx| {
  686                    let adapter = adapter.clone();
  687                    let delegate = delegate.clone();
  688                    let this = this.clone();
  689                    let mut cx = cx.clone();
  690                    async move {
  691                        let toolchain_for_id = this
  692                            .update(&mut cx, |this, _| {
  693                                this.as_local()?.language_server_ids.iter().find_map(
  694                                    |(seed, value)| {
  695                                        (value.id == server_id).then(|| seed.toolchain.clone())
  696                                    },
  697                                )
  698                            })?
  699                            .context("Expected the LSP store to be in a local mode")?;
  700                        let workspace_config = Self::workspace_configuration_for_adapter(
  701                            adapter.clone(),
  702                            &delegate,
  703                            toolchain_for_id,
  704                            &mut cx,
  705                        )
  706                        .await?;
  707
  708                        Ok(params
  709                            .items
  710                            .into_iter()
  711                            .map(|item| {
  712                                if let Some(section) = &item.section {
  713                                    workspace_config
  714                                        .get(section)
  715                                        .cloned()
  716                                        .unwrap_or(serde_json::Value::Null)
  717                                } else {
  718                                    workspace_config.clone()
  719                                }
  720                            })
  721                            .collect())
  722                    }
  723                }
  724            })
  725            .detach();
  726
  727        language_server
  728            .on_request::<lsp::request::WorkspaceFoldersRequest, _, _>({
  729                let this = lsp_store.clone();
  730                move |_, cx| {
  731                    let this = this.clone();
  732                    let cx = cx.clone();
  733                    async move {
  734                        let Some(server) =
  735                            this.read_with(&cx, |this, _| this.language_server_for_id(server_id))?
  736                        else {
  737                            return Ok(None);
  738                        };
  739                        let root = server.workspace_folders();
  740                        Ok(Some(
  741                            root.into_iter()
  742                                .map(|uri| WorkspaceFolder {
  743                                    uri,
  744                                    name: Default::default(),
  745                                })
  746                                .collect(),
  747                        ))
  748                    }
  749                }
  750            })
  751            .detach();
  752        // Even though we don't have handling for these requests, respond to them to
  753        // avoid stalling any language server like `gopls` which waits for a response
  754        // to these requests when initializing.
  755        language_server
  756            .on_request::<lsp::request::WorkDoneProgressCreate, _, _>({
  757                let this = lsp_store.clone();
  758                move |params, cx| {
  759                    let this = this.clone();
  760                    let mut cx = cx.clone();
  761                    async move {
  762                        this.update(&mut cx, |this, _| {
  763                            if let Some(status) = this.language_server_statuses.get_mut(&server_id)
  764                            {
  765                                status
  766                                    .progress_tokens
  767                                    .insert(ProgressToken::from_lsp(params.token));
  768                            }
  769                        })?;
  770
  771                        Ok(())
  772                    }
  773                }
  774            })
  775            .detach();
  776
  777        language_server
  778            .on_request::<lsp::request::RegisterCapability, _, _>({
  779                let lsp_store = lsp_store.clone();
  780                move |params, cx| {
  781                    let lsp_store = lsp_store.clone();
  782                    let mut cx = cx.clone();
  783                    async move {
  784                        lsp_store
  785                            .update(&mut cx, |lsp_store, cx| {
  786                                if lsp_store.as_local().is_some() {
  787                                    match lsp_store
  788                                        .register_server_capabilities(server_id, params, cx)
  789                                    {
  790                                        Ok(()) => {}
  791                                        Err(e) => {
  792                                            log::error!(
  793                                                "Failed to register server capabilities: {e:#}"
  794                                            );
  795                                        }
  796                                    };
  797                                }
  798                            })
  799                            .ok();
  800                        Ok(())
  801                    }
  802                }
  803            })
  804            .detach();
  805
  806        language_server
  807            .on_request::<lsp::request::UnregisterCapability, _, _>({
  808                let lsp_store = lsp_store.clone();
  809                move |params, cx| {
  810                    let lsp_store = lsp_store.clone();
  811                    let mut cx = cx.clone();
  812                    async move {
  813                        lsp_store
  814                            .update(&mut cx, |lsp_store, cx| {
  815                                if lsp_store.as_local().is_some() {
  816                                    match lsp_store
  817                                        .unregister_server_capabilities(server_id, params, cx)
  818                                    {
  819                                        Ok(()) => {}
  820                                        Err(e) => {
  821                                            log::error!(
  822                                                "Failed to unregister server capabilities: {e:#}"
  823                                            );
  824                                        }
  825                                    }
  826                                }
  827                            })
  828                            .ok();
  829                        Ok(())
  830                    }
  831                }
  832            })
  833            .detach();
  834
  835        language_server
  836            .on_request::<lsp::request::ApplyWorkspaceEdit, _, _>({
  837                let this = lsp_store.clone();
  838                move |params, cx| {
  839                    let mut cx = cx.clone();
  840                    let this = this.clone();
  841                    async move {
  842                        LocalLspStore::on_lsp_workspace_edit(
  843                            this.clone(),
  844                            params,
  845                            server_id,
  846                            &mut cx,
  847                        )
  848                        .await
  849                    }
  850                }
  851            })
  852            .detach();
  853
  854        language_server
  855            .on_request::<lsp::request::InlayHintRefreshRequest, _, _>({
  856                let lsp_store = lsp_store.clone();
  857                let request_id = Arc::new(AtomicUsize::new(0));
  858                move |(), cx| {
  859                    let lsp_store = lsp_store.clone();
  860                    let request_id = request_id.clone();
  861                    let mut cx = cx.clone();
  862                    async move {
  863                        lsp_store
  864                            .update(&mut cx, |lsp_store, cx| {
  865                                let request_id =
  866                                    Some(request_id.fetch_add(1, atomic::Ordering::AcqRel));
  867                                cx.emit(LspStoreEvent::RefreshInlayHints {
  868                                    server_id,
  869                                    request_id,
  870                                });
  871                                lsp_store
  872                                    .downstream_client
  873                                    .as_ref()
  874                                    .map(|(client, project_id)| {
  875                                        client.send(proto::RefreshInlayHints {
  876                                            project_id: *project_id,
  877                                            server_id: server_id.to_proto(),
  878                                            request_id: request_id.map(|id| id as u64),
  879                                        })
  880                                    })
  881                            })?
  882                            .transpose()?;
  883                        Ok(())
  884                    }
  885                }
  886            })
  887            .detach();
  888
  889        language_server
  890            .on_request::<lsp::request::CodeLensRefresh, _, _>({
  891                let this = lsp_store.clone();
  892                move |(), cx| {
  893                    let this = this.clone();
  894                    let mut cx = cx.clone();
  895                    async move {
  896                        this.update(&mut cx, |this, cx| {
  897                            cx.emit(LspStoreEvent::RefreshCodeLens);
  898                            this.downstream_client.as_ref().map(|(client, project_id)| {
  899                                client.send(proto::RefreshCodeLens {
  900                                    project_id: *project_id,
  901                                })
  902                            })
  903                        })?
  904                        .transpose()?;
  905                        Ok(())
  906                    }
  907                }
  908            })
  909            .detach();
  910
  911        language_server
  912            .on_request::<lsp::request::WorkspaceDiagnosticRefresh, _, _>({
  913                let this = lsp_store.clone();
  914                move |(), cx| {
  915                    let this = this.clone();
  916                    let mut cx = cx.clone();
  917                    async move {
  918                        this.update(&mut cx, |lsp_store, _| {
  919                            lsp_store.pull_workspace_diagnostics(server_id);
  920                            lsp_store
  921                                .downstream_client
  922                                .as_ref()
  923                                .map(|(client, project_id)| {
  924                                    client.send(proto::PullWorkspaceDiagnostics {
  925                                        project_id: *project_id,
  926                                        server_id: server_id.to_proto(),
  927                                    })
  928                                })
  929                        })?
  930                        .transpose()?;
  931                        Ok(())
  932                    }
  933                }
  934            })
  935            .detach();
  936
  937        language_server
  938            .on_request::<lsp::request::ShowMessageRequest, _, _>({
  939                let this = lsp_store.clone();
  940                let name = name.to_string();
  941                move |params, cx| {
  942                    let this = this.clone();
  943                    let name = name.to_string();
  944                    let mut cx = cx.clone();
  945                    async move {
  946                        let actions = params.actions.unwrap_or_default();
  947                        let (tx, rx) = smol::channel::bounded(1);
  948                        let request = LanguageServerPromptRequest {
  949                            level: match params.typ {
  950                                lsp::MessageType::ERROR => PromptLevel::Critical,
  951                                lsp::MessageType::WARNING => PromptLevel::Warning,
  952                                _ => PromptLevel::Info,
  953                            },
  954                            message: params.message,
  955                            actions,
  956                            response_channel: tx,
  957                            lsp_name: name.clone(),
  958                        };
  959
  960                        let did_update = this
  961                            .update(&mut cx, |_, cx| {
  962                                cx.emit(LspStoreEvent::LanguageServerPrompt(request));
  963                            })
  964                            .is_ok();
  965                        if did_update {
  966                            let response = rx.recv().await.ok();
  967                            Ok(response)
  968                        } else {
  969                            Ok(None)
  970                        }
  971                    }
  972                }
  973            })
  974            .detach();
  975        language_server
  976            .on_notification::<lsp::notification::ShowMessage, _>({
  977                let this = lsp_store.clone();
  978                let name = name.to_string();
  979                move |params, cx| {
  980                    let this = this.clone();
  981                    let name = name.to_string();
  982                    let mut cx = cx.clone();
  983
  984                    let (tx, _) = smol::channel::bounded(1);
  985                    let request = LanguageServerPromptRequest {
  986                        level: match params.typ {
  987                            lsp::MessageType::ERROR => PromptLevel::Critical,
  988                            lsp::MessageType::WARNING => PromptLevel::Warning,
  989                            _ => PromptLevel::Info,
  990                        },
  991                        message: params.message,
  992                        actions: vec![],
  993                        response_channel: tx,
  994                        lsp_name: name,
  995                    };
  996
  997                    let _ = this.update(&mut cx, |_, cx| {
  998                        cx.emit(LspStoreEvent::LanguageServerPrompt(request));
  999                    });
 1000                }
 1001            })
 1002            .detach();
 1003
 1004        let disk_based_diagnostics_progress_token =
 1005            adapter.disk_based_diagnostics_progress_token.clone();
 1006
 1007        language_server
 1008            .on_notification::<lsp::notification::Progress, _>({
 1009                let this = lsp_store.clone();
 1010                move |params, cx| {
 1011                    if let Some(this) = this.upgrade() {
 1012                        this.update(cx, |this, cx| {
 1013                            this.on_lsp_progress(
 1014                                params,
 1015                                server_id,
 1016                                disk_based_diagnostics_progress_token.clone(),
 1017                                cx,
 1018                            );
 1019                        })
 1020                        .ok();
 1021                    }
 1022                }
 1023            })
 1024            .detach();
 1025
 1026        language_server
 1027            .on_notification::<lsp::notification::LogMessage, _>({
 1028                let this = lsp_store.clone();
 1029                move |params, cx| {
 1030                    if let Some(this) = this.upgrade() {
 1031                        this.update(cx, |_, cx| {
 1032                            cx.emit(LspStoreEvent::LanguageServerLog(
 1033                                server_id,
 1034                                LanguageServerLogType::Log(params.typ),
 1035                                params.message,
 1036                            ));
 1037                        })
 1038                        .ok();
 1039                    }
 1040                }
 1041            })
 1042            .detach();
 1043
 1044        language_server
 1045            .on_notification::<lsp::notification::LogTrace, _>({
 1046                let this = lsp_store.clone();
 1047                move |params, cx| {
 1048                    let mut cx = cx.clone();
 1049                    if let Some(this) = this.upgrade() {
 1050                        this.update(&mut cx, |_, cx| {
 1051                            cx.emit(LspStoreEvent::LanguageServerLog(
 1052                                server_id,
 1053                                LanguageServerLogType::Trace {
 1054                                    verbose_info: params.verbose,
 1055                                },
 1056                                params.message,
 1057                            ));
 1058                        })
 1059                        .ok();
 1060                    }
 1061                }
 1062            })
 1063            .detach();
 1064
 1065        vue_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1066        json_language_server_ext::register_requests(lsp_store.clone(), language_server);
 1067        rust_analyzer_ext::register_notifications(lsp_store.clone(), language_server);
 1068        clangd_ext::register_notifications(lsp_store, language_server, adapter);
 1069    }
 1070
 1071    fn shutdown_language_servers_on_quit(
 1072        &mut self,
 1073        _: &mut Context<LspStore>,
 1074    ) -> impl Future<Output = ()> + use<> {
 1075        let shutdown_futures = self
 1076            .language_servers
 1077            .drain()
 1078            .map(|(_, server_state)| Self::shutdown_server(server_state))
 1079            .collect::<Vec<_>>();
 1080
 1081        async move {
 1082            join_all(shutdown_futures).await;
 1083        }
 1084    }
 1085
 1086    async fn shutdown_server(server_state: LanguageServerState) -> anyhow::Result<()> {
 1087        match server_state {
 1088            LanguageServerState::Running { server, .. } => {
 1089                if let Some(shutdown) = server.shutdown() {
 1090                    shutdown.await;
 1091                }
 1092            }
 1093            LanguageServerState::Starting { startup, .. } => {
 1094                if let Some(server) = startup.await
 1095                    && let Some(shutdown) = server.shutdown()
 1096                {
 1097                    shutdown.await;
 1098                }
 1099            }
 1100        }
 1101        Ok(())
 1102    }
 1103
 1104    fn language_servers_for_worktree(
 1105        &self,
 1106        worktree_id: WorktreeId,
 1107    ) -> impl Iterator<Item = &Arc<LanguageServer>> {
 1108        self.language_server_ids
 1109            .iter()
 1110            .filter_map(move |(seed, state)| {
 1111                if seed.worktree_id != worktree_id {
 1112                    return None;
 1113                }
 1114
 1115                if let Some(LanguageServerState::Running { server, .. }) =
 1116                    self.language_servers.get(&state.id)
 1117                {
 1118                    Some(server)
 1119                } else {
 1120                    None
 1121                }
 1122            })
 1123    }
 1124
 1125    fn language_server_ids_for_project_path(
 1126        &self,
 1127        project_path: ProjectPath,
 1128        language: &Language,
 1129        cx: &mut App,
 1130    ) -> Vec<LanguageServerId> {
 1131        let Some(worktree) = self
 1132            .worktree_store
 1133            .read(cx)
 1134            .worktree_for_id(project_path.worktree_id, cx)
 1135        else {
 1136            return Vec::new();
 1137        };
 1138        let delegate: Arc<dyn ManifestDelegate> =
 1139            Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 1140
 1141        self.lsp_tree
 1142            .get(
 1143                project_path,
 1144                language.name(),
 1145                language.manifest(),
 1146                &delegate,
 1147                cx,
 1148            )
 1149            .collect::<Vec<_>>()
 1150    }
 1151
 1152    fn language_server_ids_for_buffer(
 1153        &self,
 1154        buffer: &Buffer,
 1155        cx: &mut App,
 1156    ) -> Vec<LanguageServerId> {
 1157        if let Some((file, language)) = File::from_dyn(buffer.file()).zip(buffer.language()) {
 1158            let worktree_id = file.worktree_id(cx);
 1159
 1160            let path: Arc<RelPath> = file
 1161                .path()
 1162                .parent()
 1163                .map(Arc::from)
 1164                .unwrap_or_else(|| file.path().clone());
 1165            let worktree_path = ProjectPath { worktree_id, path };
 1166            self.language_server_ids_for_project_path(worktree_path, language, cx)
 1167        } else {
 1168            Vec::new()
 1169        }
 1170    }
 1171
 1172    fn language_servers_for_buffer<'a>(
 1173        &'a self,
 1174        buffer: &'a Buffer,
 1175        cx: &'a mut App,
 1176    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 1177        self.language_server_ids_for_buffer(buffer, cx)
 1178            .into_iter()
 1179            .filter_map(|server_id| match self.language_servers.get(&server_id)? {
 1180                LanguageServerState::Running {
 1181                    adapter, server, ..
 1182                } => Some((adapter, server)),
 1183                _ => None,
 1184            })
 1185    }
 1186
 1187    async fn execute_code_action_kind_locally(
 1188        lsp_store: WeakEntity<LspStore>,
 1189        mut buffers: Vec<Entity<Buffer>>,
 1190        kind: CodeActionKind,
 1191        push_to_history: bool,
 1192        cx: &mut AsyncApp,
 1193    ) -> anyhow::Result<ProjectTransaction> {
 1194        // Do not allow multiple concurrent code actions requests for the
 1195        // same buffer.
 1196        lsp_store.update(cx, |this, cx| {
 1197            let this = this.as_local_mut().unwrap();
 1198            buffers.retain(|buffer| {
 1199                this.buffers_being_formatted
 1200                    .insert(buffer.read(cx).remote_id())
 1201            });
 1202        })?;
 1203        let _cleanup = defer({
 1204            let this = lsp_store.clone();
 1205            let mut cx = cx.clone();
 1206            let buffers = &buffers;
 1207            move || {
 1208                this.update(&mut cx, |this, cx| {
 1209                    let this = this.as_local_mut().unwrap();
 1210                    for buffer in buffers {
 1211                        this.buffers_being_formatted
 1212                            .remove(&buffer.read(cx).remote_id());
 1213                    }
 1214                })
 1215                .ok();
 1216            }
 1217        });
 1218        let mut project_transaction = ProjectTransaction::default();
 1219
 1220        for buffer in &buffers {
 1221            let adapters_and_servers = lsp_store.update(cx, |lsp_store, cx| {
 1222                buffer.update(cx, |buffer, cx| {
 1223                    lsp_store
 1224                        .as_local()
 1225                        .unwrap()
 1226                        .language_servers_for_buffer(buffer, cx)
 1227                        .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1228                        .collect::<Vec<_>>()
 1229                })
 1230            })?;
 1231            for (_, language_server) in adapters_and_servers.iter() {
 1232                let actions = Self::get_server_code_actions_from_action_kinds(
 1233                    &lsp_store,
 1234                    language_server.server_id(),
 1235                    vec![kind.clone()],
 1236                    buffer,
 1237                    cx,
 1238                )
 1239                .await?;
 1240                Self::execute_code_actions_on_server(
 1241                    &lsp_store,
 1242                    language_server,
 1243                    actions,
 1244                    push_to_history,
 1245                    &mut project_transaction,
 1246                    cx,
 1247                )
 1248                .await?;
 1249            }
 1250        }
 1251        Ok(project_transaction)
 1252    }
 1253
 1254    async fn format_locally(
 1255        lsp_store: WeakEntity<LspStore>,
 1256        mut buffers: Vec<FormattableBuffer>,
 1257        push_to_history: bool,
 1258        trigger: FormatTrigger,
 1259        logger: zlog::Logger,
 1260        cx: &mut AsyncApp,
 1261    ) -> anyhow::Result<ProjectTransaction> {
 1262        // Do not allow multiple concurrent formatting requests for the
 1263        // same buffer.
 1264        lsp_store.update(cx, |this, cx| {
 1265            let this = this.as_local_mut().unwrap();
 1266            buffers.retain(|buffer| {
 1267                this.buffers_being_formatted
 1268                    .insert(buffer.handle.read(cx).remote_id())
 1269            });
 1270        })?;
 1271
 1272        let _cleanup = defer({
 1273            let this = lsp_store.clone();
 1274            let mut cx = cx.clone();
 1275            let buffers = &buffers;
 1276            move || {
 1277                this.update(&mut cx, |this, cx| {
 1278                    let this = this.as_local_mut().unwrap();
 1279                    for buffer in buffers {
 1280                        this.buffers_being_formatted
 1281                            .remove(&buffer.handle.read(cx).remote_id());
 1282                    }
 1283                })
 1284                .ok();
 1285            }
 1286        });
 1287
 1288        let mut project_transaction = ProjectTransaction::default();
 1289
 1290        for buffer in &buffers {
 1291            zlog::debug!(
 1292                logger =>
 1293                "formatting buffer '{:?}'",
 1294                buffer.abs_path.as_ref().unwrap_or(&PathBuf::from("unknown")).display()
 1295            );
 1296            // Create an empty transaction to hold all of the formatting edits.
 1297            let formatting_transaction_id = buffer.handle.update(cx, |buffer, cx| {
 1298                // ensure no transactions created while formatting are
 1299                // grouped with the previous transaction in the history
 1300                // based on the transaction group interval
 1301                buffer.finalize_last_transaction();
 1302                buffer
 1303                    .start_transaction()
 1304                    .context("transaction already open")?;
 1305                buffer.end_transaction(cx);
 1306                let transaction_id = buffer.push_empty_transaction(cx.background_executor().now());
 1307                buffer.finalize_last_transaction();
 1308                anyhow::Ok(transaction_id)
 1309            })??;
 1310
 1311            let result = Self::format_buffer_locally(
 1312                lsp_store.clone(),
 1313                buffer,
 1314                formatting_transaction_id,
 1315                trigger,
 1316                logger,
 1317                cx,
 1318            )
 1319            .await;
 1320
 1321            buffer.handle.update(cx, |buffer, cx| {
 1322                let Some(formatting_transaction) =
 1323                    buffer.get_transaction(formatting_transaction_id).cloned()
 1324                else {
 1325                    zlog::warn!(logger => "no formatting transaction");
 1326                    return;
 1327                };
 1328                if formatting_transaction.edit_ids.is_empty() {
 1329                    zlog::debug!(logger => "no changes made while formatting");
 1330                    buffer.forget_transaction(formatting_transaction_id);
 1331                    return;
 1332                }
 1333                if !push_to_history {
 1334                    zlog::trace!(logger => "forgetting format transaction");
 1335                    buffer.forget_transaction(formatting_transaction.id);
 1336                }
 1337                project_transaction
 1338                    .0
 1339                    .insert(cx.entity(), formatting_transaction);
 1340            })?;
 1341
 1342            result?;
 1343        }
 1344
 1345        Ok(project_transaction)
 1346    }
 1347
 1348    async fn format_buffer_locally(
 1349        lsp_store: WeakEntity<LspStore>,
 1350        buffer: &FormattableBuffer,
 1351        formatting_transaction_id: clock::Lamport,
 1352        trigger: FormatTrigger,
 1353        logger: zlog::Logger,
 1354        cx: &mut AsyncApp,
 1355    ) -> Result<()> {
 1356        let (adapters_and_servers, settings) = lsp_store.update(cx, |lsp_store, cx| {
 1357            buffer.handle.update(cx, |buffer, cx| {
 1358                let adapters_and_servers = lsp_store
 1359                    .as_local()
 1360                    .unwrap()
 1361                    .language_servers_for_buffer(buffer, cx)
 1362                    .map(|(adapter, lsp)| (adapter.clone(), lsp.clone()))
 1363                    .collect::<Vec<_>>();
 1364                let settings =
 1365                    language_settings(buffer.language().map(|l| l.name()), buffer.file(), cx)
 1366                        .into_owned();
 1367                (adapters_and_servers, settings)
 1368            })
 1369        })?;
 1370
 1371        /// Apply edits to the buffer that will become part of the formatting transaction.
 1372        /// Fails if the buffer has been edited since the start of that transaction.
 1373        fn extend_formatting_transaction(
 1374            buffer: &FormattableBuffer,
 1375            formatting_transaction_id: text::TransactionId,
 1376            cx: &mut AsyncApp,
 1377            operation: impl FnOnce(&mut Buffer, &mut Context<Buffer>),
 1378        ) -> anyhow::Result<()> {
 1379            buffer.handle.update(cx, |buffer, cx| {
 1380                let last_transaction_id = buffer.peek_undo_stack().map(|t| t.transaction_id());
 1381                if last_transaction_id != Some(formatting_transaction_id) {
 1382                    anyhow::bail!("Buffer edited while formatting. Aborting")
 1383                }
 1384                buffer.start_transaction();
 1385                operation(buffer, cx);
 1386                if let Some(transaction_id) = buffer.end_transaction(cx) {
 1387                    buffer.merge_transactions(transaction_id, formatting_transaction_id);
 1388                }
 1389                Ok(())
 1390            })?
 1391        }
 1392
 1393        // handle whitespace formatting
 1394        if settings.remove_trailing_whitespace_on_save {
 1395            zlog::trace!(logger => "removing trailing whitespace");
 1396            let diff = buffer
 1397                .handle
 1398                .read_with(cx, |buffer, cx| buffer.remove_trailing_whitespace(cx))?
 1399                .await;
 1400            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1401                buffer.apply_diff(diff, cx);
 1402            })?;
 1403        }
 1404
 1405        if settings.ensure_final_newline_on_save {
 1406            zlog::trace!(logger => "ensuring final newline");
 1407            extend_formatting_transaction(buffer, formatting_transaction_id, cx, |buffer, cx| {
 1408                buffer.ensure_final_newline(cx);
 1409            })?;
 1410        }
 1411
 1412        // Formatter for `code_actions_on_format` that runs before
 1413        // the rest of the formatters
 1414        let mut code_actions_on_format_formatters = None;
 1415        let should_run_code_actions_on_format = !matches!(
 1416            (trigger, &settings.format_on_save),
 1417            (FormatTrigger::Save, &FormatOnSave::Off)
 1418        );
 1419        if should_run_code_actions_on_format {
 1420            let have_code_actions_to_run_on_format = settings
 1421                .code_actions_on_format
 1422                .values()
 1423                .any(|enabled| *enabled);
 1424            if have_code_actions_to_run_on_format {
 1425                zlog::trace!(logger => "going to run code actions on format");
 1426                code_actions_on_format_formatters = Some(
 1427                    settings
 1428                        .code_actions_on_format
 1429                        .iter()
 1430                        .filter_map(|(action, enabled)| enabled.then_some(action))
 1431                        .cloned()
 1432                        .map(Formatter::CodeAction)
 1433                        .collect::<Vec<_>>(),
 1434                );
 1435            }
 1436        }
 1437
 1438        let formatters = match (trigger, &settings.format_on_save) {
 1439            (FormatTrigger::Save, FormatOnSave::Off) => &[],
 1440            (FormatTrigger::Manual, _) | (FormatTrigger::Save, FormatOnSave::On) => {
 1441                settings.formatter.as_ref()
 1442            }
 1443        };
 1444
 1445        let formatters = code_actions_on_format_formatters
 1446            .iter()
 1447            .flatten()
 1448            .chain(formatters);
 1449
 1450        for formatter in formatters {
 1451            let formatter = if formatter == &Formatter::Auto {
 1452                if settings.prettier.allowed {
 1453                    zlog::trace!(logger => "Formatter set to auto: defaulting to prettier");
 1454                    &Formatter::Prettier
 1455                } else {
 1456                    zlog::trace!(logger => "Formatter set to auto: defaulting to primary language server");
 1457                    &Formatter::LanguageServer(settings::LanguageServerFormatterSpecifier::Current)
 1458                }
 1459            } else {
 1460                formatter
 1461            };
 1462            match formatter {
 1463                Formatter::Auto => unreachable!("Auto resolved above"),
 1464                Formatter::Prettier => {
 1465                    let logger = zlog::scoped!(logger => "prettier");
 1466                    zlog::trace!(logger => "formatting");
 1467                    let _timer = zlog::time!(logger => "Formatting buffer via prettier");
 1468
 1469                    let prettier = lsp_store.read_with(cx, |lsp_store, _cx| {
 1470                        lsp_store.prettier_store().unwrap().downgrade()
 1471                    })?;
 1472                    let diff = prettier_store::format_with_prettier(&prettier, &buffer.handle, cx)
 1473                        .await
 1474                        .transpose()?;
 1475                    let Some(diff) = diff else {
 1476                        zlog::trace!(logger => "No changes");
 1477                        continue;
 1478                    };
 1479
 1480                    extend_formatting_transaction(
 1481                        buffer,
 1482                        formatting_transaction_id,
 1483                        cx,
 1484                        |buffer, cx| {
 1485                            buffer.apply_diff(diff, cx);
 1486                        },
 1487                    )?;
 1488                }
 1489                Formatter::External { command, arguments } => {
 1490                    let logger = zlog::scoped!(logger => "command");
 1491                    zlog::trace!(logger => "formatting");
 1492                    let _timer = zlog::time!(logger => "Formatting buffer via external command");
 1493
 1494                    let diff = Self::format_via_external_command(
 1495                        buffer,
 1496                        command.as_ref(),
 1497                        arguments.as_deref(),
 1498                        cx,
 1499                    )
 1500                    .await
 1501                    .with_context(|| {
 1502                        format!("Failed to format buffer via external command: {}", command)
 1503                    })?;
 1504                    let Some(diff) = diff else {
 1505                        zlog::trace!(logger => "No changes");
 1506                        continue;
 1507                    };
 1508
 1509                    extend_formatting_transaction(
 1510                        buffer,
 1511                        formatting_transaction_id,
 1512                        cx,
 1513                        |buffer, cx| {
 1514                            buffer.apply_diff(diff, cx);
 1515                        },
 1516                    )?;
 1517                }
 1518                Formatter::LanguageServer(specifier) => {
 1519                    let logger = zlog::scoped!(logger => "language-server");
 1520                    zlog::trace!(logger => "formatting");
 1521                    let _timer = zlog::time!(logger => "Formatting buffer using language server");
 1522
 1523                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1524                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using language servers. Skipping");
 1525                        continue;
 1526                    };
 1527
 1528                    let language_server = match specifier {
 1529                        settings::LanguageServerFormatterSpecifier::Specific { name } => {
 1530                            adapters_and_servers.iter().find_map(|(adapter, server)| {
 1531                                if adapter.name.0.as_ref() == name {
 1532                                    Some(server.clone())
 1533                                } else {
 1534                                    None
 1535                                }
 1536                            })
 1537                        }
 1538                        settings::LanguageServerFormatterSpecifier::Current => {
 1539                            adapters_and_servers.first().map(|e| e.1.clone())
 1540                        }
 1541                    };
 1542
 1543                    let Some(language_server) = language_server else {
 1544                        log::debug!(
 1545                            "No language server found to format buffer '{:?}'. Skipping",
 1546                            buffer_path_abs.as_path().to_string_lossy()
 1547                        );
 1548                        continue;
 1549                    };
 1550
 1551                    zlog::trace!(
 1552                        logger =>
 1553                        "Formatting buffer '{:?}' using language server '{:?}'",
 1554                        buffer_path_abs.as_path().to_string_lossy(),
 1555                        language_server.name()
 1556                    );
 1557
 1558                    let edits = if let Some(ranges) = buffer.ranges.as_ref() {
 1559                        zlog::trace!(logger => "formatting ranges");
 1560                        Self::format_ranges_via_lsp(
 1561                            &lsp_store,
 1562                            &buffer.handle,
 1563                            ranges,
 1564                            buffer_path_abs,
 1565                            &language_server,
 1566                            &settings,
 1567                            cx,
 1568                        )
 1569                        .await
 1570                        .context("Failed to format ranges via language server")?
 1571                    } else {
 1572                        zlog::trace!(logger => "formatting full");
 1573                        Self::format_via_lsp(
 1574                            &lsp_store,
 1575                            &buffer.handle,
 1576                            buffer_path_abs,
 1577                            &language_server,
 1578                            &settings,
 1579                            cx,
 1580                        )
 1581                        .await
 1582                        .context("failed to format via language server")?
 1583                    };
 1584
 1585                    if edits.is_empty() {
 1586                        zlog::trace!(logger => "No changes");
 1587                        continue;
 1588                    }
 1589                    extend_formatting_transaction(
 1590                        buffer,
 1591                        formatting_transaction_id,
 1592                        cx,
 1593                        |buffer, cx| {
 1594                            buffer.edit(edits, None, cx);
 1595                        },
 1596                    )?;
 1597                }
 1598                Formatter::CodeAction(code_action_name) => {
 1599                    let logger = zlog::scoped!(logger => "code-actions");
 1600                    zlog::trace!(logger => "formatting");
 1601                    let _timer = zlog::time!(logger => "Formatting buffer using code actions");
 1602
 1603                    let Some(buffer_path_abs) = buffer.abs_path.as_ref() else {
 1604                        zlog::warn!(logger => "Cannot format buffer that is not backed by a file on disk using code actions. Skipping");
 1605                        continue;
 1606                    };
 1607
 1608                    let code_action_kind: CodeActionKind = code_action_name.clone().into();
 1609                    zlog::trace!(logger => "Attempting to resolve code actions {:?}", &code_action_kind);
 1610
 1611                    let mut actions_and_servers = Vec::new();
 1612
 1613                    for (index, (_, language_server)) in adapters_and_servers.iter().enumerate() {
 1614                        let actions_result = Self::get_server_code_actions_from_action_kinds(
 1615                            &lsp_store,
 1616                            language_server.server_id(),
 1617                            vec![code_action_kind.clone()],
 1618                            &buffer.handle,
 1619                            cx,
 1620                        )
 1621                        .await
 1622                        .with_context(|| {
 1623                            format!(
 1624                                "Failed to resolve code action {:?} with language server {}",
 1625                                code_action_kind,
 1626                                language_server.name()
 1627                            )
 1628                        });
 1629                        let Ok(actions) = actions_result else {
 1630                            // note: it may be better to set result to the error and break formatters here
 1631                            // but for now we try to execute the actions that we can resolve and skip the rest
 1632                            zlog::error!(
 1633                                logger =>
 1634                                "Failed to resolve code action {:?} with language server {}",
 1635                                code_action_kind,
 1636                                language_server.name()
 1637                            );
 1638                            continue;
 1639                        };
 1640                        for action in actions {
 1641                            actions_and_servers.push((action, index));
 1642                        }
 1643                    }
 1644
 1645                    if actions_and_servers.is_empty() {
 1646                        zlog::warn!(logger => "No code actions were resolved, continuing");
 1647                        continue;
 1648                    }
 1649
 1650                    'actions: for (mut action, server_index) in actions_and_servers {
 1651                        let server = &adapters_and_servers[server_index].1;
 1652
 1653                        let describe_code_action = |action: &CodeAction| {
 1654                            format!(
 1655                                "code action '{}' with title \"{}\" on server {}",
 1656                                action
 1657                                    .lsp_action
 1658                                    .action_kind()
 1659                                    .unwrap_or("unknown".into())
 1660                                    .as_str(),
 1661                                action.lsp_action.title(),
 1662                                server.name(),
 1663                            )
 1664                        };
 1665
 1666                        zlog::trace!(logger => "Executing {}", describe_code_action(&action));
 1667
 1668                        if let Err(err) = Self::try_resolve_code_action(server, &mut action).await {
 1669                            zlog::error!(
 1670                                logger =>
 1671                                "Failed to resolve {}. Error: {}",
 1672                                describe_code_action(&action),
 1673                                err
 1674                            );
 1675                            continue;
 1676                        }
 1677
 1678                        if let Some(edit) = action.lsp_action.edit().cloned() {
 1679                            // NOTE: code below duplicated from `Self::deserialize_workspace_edit`
 1680                            // but filters out and logs warnings for code actions that require unreasonably
 1681                            // difficult handling on our part, such as:
 1682                            // - applying edits that call commands
 1683                            //   which can result in arbitrary workspace edits being sent from the server that
 1684                            //   have no way of being tied back to the command that initiated them (i.e. we
 1685                            //   can't know which edits are part of the format request, or if the server is done sending
 1686                            //   actions in response to the command)
 1687                            // - actions that create/delete/modify/rename files other than the one we are formatting
 1688                            //   as we then would need to handle such changes correctly in the local history as well
 1689                            //   as the remote history through the ProjectTransaction
 1690                            // - actions with snippet edits, as these simply don't make sense in the context of a format request
 1691                            // Supporting these actions is not impossible, but not supported as of yet.
 1692                            if edit.changes.is_none() && edit.document_changes.is_none() {
 1693                                zlog::trace!(
 1694                                    logger =>
 1695                                    "No changes for code action. Skipping {}",
 1696                                    describe_code_action(&action),
 1697                                );
 1698                                continue;
 1699                            }
 1700
 1701                            let mut operations = Vec::new();
 1702                            if let Some(document_changes) = edit.document_changes {
 1703                                match document_changes {
 1704                                    lsp::DocumentChanges::Edits(edits) => operations.extend(
 1705                                        edits.into_iter().map(lsp::DocumentChangeOperation::Edit),
 1706                                    ),
 1707                                    lsp::DocumentChanges::Operations(ops) => operations = ops,
 1708                                }
 1709                            } else if let Some(changes) = edit.changes {
 1710                                operations.extend(changes.into_iter().map(|(uri, edits)| {
 1711                                    lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 1712                                        text_document:
 1713                                            lsp::OptionalVersionedTextDocumentIdentifier {
 1714                                                uri,
 1715                                                version: None,
 1716                                            },
 1717                                        edits: edits.into_iter().map(Edit::Plain).collect(),
 1718                                    })
 1719                                }));
 1720                            }
 1721
 1722                            let mut edits = Vec::with_capacity(operations.len());
 1723
 1724                            if operations.is_empty() {
 1725                                zlog::trace!(
 1726                                    logger =>
 1727                                    "No changes for code action. Skipping {}",
 1728                                    describe_code_action(&action),
 1729                                );
 1730                                continue;
 1731                            }
 1732                            for operation in operations {
 1733                                let op = match operation {
 1734                                    lsp::DocumentChangeOperation::Edit(op) => op,
 1735                                    lsp::DocumentChangeOperation::Op(_) => {
 1736                                        zlog::warn!(
 1737                                            logger =>
 1738                                            "Code actions which create, delete, or rename files are not supported on format. Skipping {}",
 1739                                            describe_code_action(&action),
 1740                                        );
 1741                                        continue 'actions;
 1742                                    }
 1743                                };
 1744                                let Ok(file_path) = op.text_document.uri.to_file_path() else {
 1745                                    zlog::warn!(
 1746                                        logger =>
 1747                                        "Failed to convert URI '{:?}' to file path. Skipping {}",
 1748                                        &op.text_document.uri,
 1749                                        describe_code_action(&action),
 1750                                    );
 1751                                    continue 'actions;
 1752                                };
 1753                                if &file_path != buffer_path_abs {
 1754                                    zlog::warn!(
 1755                                        logger =>
 1756                                        "File path '{:?}' does not match buffer path '{:?}'. Skipping {}",
 1757                                        file_path,
 1758                                        buffer_path_abs,
 1759                                        describe_code_action(&action),
 1760                                    );
 1761                                    continue 'actions;
 1762                                }
 1763
 1764                                let mut lsp_edits = Vec::new();
 1765                                for edit in op.edits {
 1766                                    match edit {
 1767                                        Edit::Plain(edit) => {
 1768                                            if !lsp_edits.contains(&edit) {
 1769                                                lsp_edits.push(edit);
 1770                                            }
 1771                                        }
 1772                                        Edit::Annotated(edit) => {
 1773                                            if !lsp_edits.contains(&edit.text_edit) {
 1774                                                lsp_edits.push(edit.text_edit);
 1775                                            }
 1776                                        }
 1777                                        Edit::Snippet(_) => {
 1778                                            zlog::warn!(
 1779                                                logger =>
 1780                                                "Code actions which produce snippet edits are not supported during formatting. Skipping {}",
 1781                                                describe_code_action(&action),
 1782                                            );
 1783                                            continue 'actions;
 1784                                        }
 1785                                    }
 1786                                }
 1787                                let edits_result = lsp_store
 1788                                    .update(cx, |lsp_store, cx| {
 1789                                        lsp_store.as_local_mut().unwrap().edits_from_lsp(
 1790                                            &buffer.handle,
 1791                                            lsp_edits,
 1792                                            server.server_id(),
 1793                                            op.text_document.version,
 1794                                            cx,
 1795                                        )
 1796                                    })?
 1797                                    .await;
 1798                                let Ok(resolved_edits) = edits_result else {
 1799                                    zlog::warn!(
 1800                                        logger =>
 1801                                        "Failed to resolve edits from LSP for buffer {:?} while handling {}",
 1802                                        buffer_path_abs.as_path(),
 1803                                        describe_code_action(&action),
 1804                                    );
 1805                                    continue 'actions;
 1806                                };
 1807                                edits.extend(resolved_edits);
 1808                            }
 1809
 1810                            if edits.is_empty() {
 1811                                zlog::warn!(logger => "No edits resolved from LSP");
 1812                                continue;
 1813                            }
 1814
 1815                            extend_formatting_transaction(
 1816                                buffer,
 1817                                formatting_transaction_id,
 1818                                cx,
 1819                                |buffer, cx| {
 1820                                    zlog::info!(
 1821                                        "Applying edits {edits:?}. Content: {:?}",
 1822                                        buffer.text()
 1823                                    );
 1824                                    buffer.edit(edits, None, cx);
 1825                                    zlog::info!("Applied edits. New Content: {:?}", buffer.text());
 1826                                },
 1827                            )?;
 1828                        }
 1829
 1830                        if let Some(command) = action.lsp_action.command() {
 1831                            zlog::warn!(
 1832                                logger =>
 1833                                "Executing code action command '{}'. This may cause formatting to abort unnecessarily as well as splitting formatting into two entries in the undo history",
 1834                                &command.command,
 1835                            );
 1836
 1837                            // bail early if command is invalid
 1838                            let server_capabilities = server.capabilities();
 1839                            let available_commands = server_capabilities
 1840                                .execute_command_provider
 1841                                .as_ref()
 1842                                .map(|options| options.commands.as_slice())
 1843                                .unwrap_or_default();
 1844                            if !available_commands.contains(&command.command) {
 1845                                zlog::warn!(
 1846                                    logger =>
 1847                                    "Cannot execute a command {} not listed in the language server capabilities of server {}",
 1848                                    command.command,
 1849                                    server.name(),
 1850                                );
 1851                                continue;
 1852                            }
 1853
 1854                            // noop so we just ensure buffer hasn't been edited since resolving code actions
 1855                            extend_formatting_transaction(
 1856                                buffer,
 1857                                formatting_transaction_id,
 1858                                cx,
 1859                                |_, _| {},
 1860                            )?;
 1861                            zlog::info!(logger => "Executing command {}", &command.command);
 1862
 1863                            lsp_store.update(cx, |this, _| {
 1864                                this.as_local_mut()
 1865                                    .unwrap()
 1866                                    .last_workspace_edits_by_language_server
 1867                                    .remove(&server.server_id());
 1868                            })?;
 1869
 1870                            let execute_command_result = server
 1871                                .request::<lsp::request::ExecuteCommand>(
 1872                                    lsp::ExecuteCommandParams {
 1873                                        command: command.command.clone(),
 1874                                        arguments: command.arguments.clone().unwrap_or_default(),
 1875                                        ..Default::default()
 1876                                    },
 1877                                )
 1878                                .await
 1879                                .into_response();
 1880
 1881                            if execute_command_result.is_err() {
 1882                                zlog::error!(
 1883                                    logger =>
 1884                                    "Failed to execute command '{}' as part of {}",
 1885                                    &command.command,
 1886                                    describe_code_action(&action),
 1887                                );
 1888                                continue 'actions;
 1889                            }
 1890
 1891                            let mut project_transaction_command =
 1892                                lsp_store.update(cx, |this, _| {
 1893                                    this.as_local_mut()
 1894                                        .unwrap()
 1895                                        .last_workspace_edits_by_language_server
 1896                                        .remove(&server.server_id())
 1897                                        .unwrap_or_default()
 1898                                })?;
 1899
 1900                            if let Some(transaction) =
 1901                                project_transaction_command.0.remove(&buffer.handle)
 1902                            {
 1903                                zlog::trace!(
 1904                                    logger =>
 1905                                    "Successfully captured {} edits that resulted from command {}",
 1906                                    transaction.edit_ids.len(),
 1907                                    &command.command,
 1908                                );
 1909                                let transaction_id_project_transaction = transaction.id;
 1910                                buffer.handle.update(cx, |buffer, _| {
 1911                                    // it may have been removed from history if push_to_history was
 1912                                    // false in deserialize_workspace_edit. If so push it so we
 1913                                    // can merge it with the format transaction
 1914                                    // and pop the combined transaction off the history stack
 1915                                    // later if push_to_history is false
 1916                                    if buffer.get_transaction(transaction.id).is_none() {
 1917                                        buffer.push_transaction(transaction, Instant::now());
 1918                                    }
 1919                                    buffer.merge_transactions(
 1920                                        transaction_id_project_transaction,
 1921                                        formatting_transaction_id,
 1922                                    );
 1923                                })?;
 1924                            }
 1925
 1926                            if !project_transaction_command.0.is_empty() {
 1927                                let mut extra_buffers = String::new();
 1928                                for buffer in project_transaction_command.0.keys() {
 1929                                    buffer
 1930                                        .read_with(cx, |b, cx| {
 1931                                            if let Some(path) = b.project_path(cx) {
 1932                                                if !extra_buffers.is_empty() {
 1933                                                    extra_buffers.push_str(", ");
 1934                                                }
 1935                                                extra_buffers.push_str(path.path.as_unix_str());
 1936                                            }
 1937                                        })
 1938                                        .ok();
 1939                                }
 1940                                zlog::warn!(
 1941                                    logger =>
 1942                                    "Unexpected edits to buffers other than the buffer actively being formatted due to command {}. Impacted buffers: [{}].",
 1943                                    &command.command,
 1944                                    extra_buffers,
 1945                                );
 1946                                // NOTE: if this case is hit, the proper thing to do is to for each buffer, merge the extra transaction
 1947                                // into the existing transaction in project_transaction if there is one, and if there isn't one in project_transaction,
 1948                                // add it so it's included, and merge it into the format transaction when its created later
 1949                            }
 1950                        }
 1951                    }
 1952                }
 1953            }
 1954        }
 1955
 1956        Ok(())
 1957    }
 1958
 1959    pub async fn format_ranges_via_lsp(
 1960        this: &WeakEntity<LspStore>,
 1961        buffer_handle: &Entity<Buffer>,
 1962        ranges: &[Range<Anchor>],
 1963        abs_path: &Path,
 1964        language_server: &Arc<LanguageServer>,
 1965        settings: &LanguageSettings,
 1966        cx: &mut AsyncApp,
 1967    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 1968        let capabilities = &language_server.capabilities();
 1969        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 1970        if range_formatting_provider == Some(&OneOf::Left(false)) {
 1971            anyhow::bail!(
 1972                "{} language server does not support range formatting",
 1973                language_server.name()
 1974            );
 1975        }
 1976
 1977        let uri = file_path_to_lsp_url(abs_path)?;
 1978        let text_document = lsp::TextDocumentIdentifier::new(uri);
 1979
 1980        let lsp_edits = {
 1981            let mut lsp_ranges = Vec::new();
 1982            this.update(cx, |_this, cx| {
 1983                // TODO(#22930): In the case of formatting multibuffer selections, this buffer may
 1984                // not have been sent to the language server. This seems like a fairly systemic
 1985                // issue, though, the resolution probably is not specific to formatting.
 1986                //
 1987                // TODO: Instead of using current snapshot, should use the latest snapshot sent to
 1988                // LSP.
 1989                let snapshot = buffer_handle.read(cx).snapshot();
 1990                for range in ranges {
 1991                    lsp_ranges.push(range_to_lsp(range.to_point_utf16(&snapshot))?);
 1992                }
 1993                anyhow::Ok(())
 1994            })??;
 1995
 1996            let mut edits = None;
 1997            for range in lsp_ranges {
 1998                if let Some(mut edit) = language_server
 1999                    .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2000                        text_document: text_document.clone(),
 2001                        range,
 2002                        options: lsp_command::lsp_formatting_options(settings),
 2003                        work_done_progress_params: Default::default(),
 2004                    })
 2005                    .await
 2006                    .into_response()?
 2007                {
 2008                    edits.get_or_insert_with(Vec::new).append(&mut edit);
 2009                }
 2010            }
 2011            edits
 2012        };
 2013
 2014        if let Some(lsp_edits) = lsp_edits {
 2015            this.update(cx, |this, cx| {
 2016                this.as_local_mut().unwrap().edits_from_lsp(
 2017                    buffer_handle,
 2018                    lsp_edits,
 2019                    language_server.server_id(),
 2020                    None,
 2021                    cx,
 2022                )
 2023            })?
 2024            .await
 2025        } else {
 2026            Ok(Vec::with_capacity(0))
 2027        }
 2028    }
 2029
 2030    async fn format_via_lsp(
 2031        this: &WeakEntity<LspStore>,
 2032        buffer: &Entity<Buffer>,
 2033        abs_path: &Path,
 2034        language_server: &Arc<LanguageServer>,
 2035        settings: &LanguageSettings,
 2036        cx: &mut AsyncApp,
 2037    ) -> Result<Vec<(Range<Anchor>, Arc<str>)>> {
 2038        let logger = zlog::scoped!("lsp_format");
 2039        zlog::debug!(logger => "Formatting via LSP");
 2040
 2041        let uri = file_path_to_lsp_url(abs_path)?;
 2042        let text_document = lsp::TextDocumentIdentifier::new(uri);
 2043        let capabilities = &language_server.capabilities();
 2044
 2045        let formatting_provider = capabilities.document_formatting_provider.as_ref();
 2046        let range_formatting_provider = capabilities.document_range_formatting_provider.as_ref();
 2047
 2048        let lsp_edits = if matches!(formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2049            let _timer = zlog::time!(logger => "format-full");
 2050            language_server
 2051                .request::<lsp::request::Formatting>(lsp::DocumentFormattingParams {
 2052                    text_document,
 2053                    options: lsp_command::lsp_formatting_options(settings),
 2054                    work_done_progress_params: Default::default(),
 2055                })
 2056                .await
 2057                .into_response()?
 2058        } else if matches!(range_formatting_provider, Some(p) if *p != OneOf::Left(false)) {
 2059            let _timer = zlog::time!(logger => "format-range");
 2060            let buffer_start = lsp::Position::new(0, 0);
 2061            let buffer_end = buffer.read_with(cx, |b, _| point_to_lsp(b.max_point_utf16()))?;
 2062            language_server
 2063                .request::<lsp::request::RangeFormatting>(lsp::DocumentRangeFormattingParams {
 2064                    text_document: text_document.clone(),
 2065                    range: lsp::Range::new(buffer_start, buffer_end),
 2066                    options: lsp_command::lsp_formatting_options(settings),
 2067                    work_done_progress_params: Default::default(),
 2068                })
 2069                .await
 2070                .into_response()?
 2071        } else {
 2072            None
 2073        };
 2074
 2075        if let Some(lsp_edits) = lsp_edits {
 2076            this.update(cx, |this, cx| {
 2077                this.as_local_mut().unwrap().edits_from_lsp(
 2078                    buffer,
 2079                    lsp_edits,
 2080                    language_server.server_id(),
 2081                    None,
 2082                    cx,
 2083                )
 2084            })?
 2085            .await
 2086        } else {
 2087            Ok(Vec::with_capacity(0))
 2088        }
 2089    }
 2090
 2091    async fn format_via_external_command(
 2092        buffer: &FormattableBuffer,
 2093        command: &str,
 2094        arguments: Option<&[String]>,
 2095        cx: &mut AsyncApp,
 2096    ) -> Result<Option<Diff>> {
 2097        let working_dir_path = buffer.handle.update(cx, |buffer, cx| {
 2098            let file = File::from_dyn(buffer.file())?;
 2099            let worktree = file.worktree.read(cx);
 2100            let mut worktree_path = worktree.abs_path().to_path_buf();
 2101            if worktree.root_entry()?.is_file() {
 2102                worktree_path.pop();
 2103            }
 2104            Some(worktree_path)
 2105        })?;
 2106
 2107        let mut child = util::command::new_smol_command(command);
 2108
 2109        if let Some(buffer_env) = buffer.env.as_ref() {
 2110            child.envs(buffer_env);
 2111        }
 2112
 2113        if let Some(working_dir_path) = working_dir_path {
 2114            child.current_dir(working_dir_path);
 2115        }
 2116
 2117        if let Some(arguments) = arguments {
 2118            child.args(arguments.iter().map(|arg| {
 2119                if let Some(buffer_abs_path) = buffer.abs_path.as_ref() {
 2120                    arg.replace("{buffer_path}", &buffer_abs_path.to_string_lossy())
 2121                } else {
 2122                    arg.replace("{buffer_path}", "Untitled")
 2123                }
 2124            }));
 2125        }
 2126
 2127        let mut child = child
 2128            .stdin(smol::process::Stdio::piped())
 2129            .stdout(smol::process::Stdio::piped())
 2130            .stderr(smol::process::Stdio::piped())
 2131            .spawn()?;
 2132
 2133        let stdin = child.stdin.as_mut().context("failed to acquire stdin")?;
 2134        let text = buffer
 2135            .handle
 2136            .read_with(cx, |buffer, _| buffer.as_rope().clone())?;
 2137        for chunk in text.chunks() {
 2138            stdin.write_all(chunk.as_bytes()).await?;
 2139        }
 2140        stdin.flush().await?;
 2141
 2142        let output = child.output().await?;
 2143        anyhow::ensure!(
 2144            output.status.success(),
 2145            "command failed with exit code {:?}:\nstdout: {}\nstderr: {}",
 2146            output.status.code(),
 2147            String::from_utf8_lossy(&output.stdout),
 2148            String::from_utf8_lossy(&output.stderr),
 2149        );
 2150
 2151        let stdout = String::from_utf8(output.stdout)?;
 2152        Ok(Some(
 2153            buffer
 2154                .handle
 2155                .update(cx, |buffer, cx| buffer.diff(stdout, cx))?
 2156                .await,
 2157        ))
 2158    }
 2159
 2160    async fn try_resolve_code_action(
 2161        lang_server: &LanguageServer,
 2162        action: &mut CodeAction,
 2163    ) -> anyhow::Result<()> {
 2164        match &mut action.lsp_action {
 2165            LspAction::Action(lsp_action) => {
 2166                if !action.resolved
 2167                    && GetCodeActions::can_resolve_actions(&lang_server.capabilities())
 2168                    && lsp_action.data.is_some()
 2169                    && (lsp_action.command.is_none() || lsp_action.edit.is_none())
 2170                {
 2171                    *lsp_action = Box::new(
 2172                        lang_server
 2173                            .request::<lsp::request::CodeActionResolveRequest>(*lsp_action.clone())
 2174                            .await
 2175                            .into_response()?,
 2176                    );
 2177                }
 2178            }
 2179            LspAction::CodeLens(lens) => {
 2180                if !action.resolved && GetCodeLens::can_resolve_lens(&lang_server.capabilities()) {
 2181                    *lens = lang_server
 2182                        .request::<lsp::request::CodeLensResolve>(lens.clone())
 2183                        .await
 2184                        .into_response()?;
 2185                }
 2186            }
 2187            LspAction::Command(_) => {}
 2188        }
 2189
 2190        action.resolved = true;
 2191        anyhow::Ok(())
 2192    }
 2193
 2194    fn initialize_buffer(&mut self, buffer_handle: &Entity<Buffer>, cx: &mut Context<LspStore>) {
 2195        let buffer = buffer_handle.read(cx);
 2196
 2197        let file = buffer.file().cloned();
 2198
 2199        let Some(file) = File::from_dyn(file.as_ref()) else {
 2200            return;
 2201        };
 2202        if !file.is_local() {
 2203            return;
 2204        }
 2205        let path = ProjectPath::from_file(file, cx);
 2206        let worktree_id = file.worktree_id(cx);
 2207        let language = buffer.language().cloned();
 2208
 2209        if let Some(diagnostics) = self.diagnostics.get(&worktree_id) {
 2210            for (server_id, diagnostics) in
 2211                diagnostics.get(file.path()).cloned().unwrap_or_default()
 2212            {
 2213                self.update_buffer_diagnostics(
 2214                    buffer_handle,
 2215                    server_id,
 2216                    None,
 2217                    None,
 2218                    diagnostics,
 2219                    Vec::new(),
 2220                    cx,
 2221                )
 2222                .log_err();
 2223            }
 2224        }
 2225        let Some(language) = language else {
 2226            return;
 2227        };
 2228        let Some(snapshot) = self
 2229            .worktree_store
 2230            .read(cx)
 2231            .worktree_for_id(worktree_id, cx)
 2232            .map(|worktree| worktree.read(cx).snapshot())
 2233        else {
 2234            return;
 2235        };
 2236        let delegate: Arc<dyn ManifestDelegate> = Arc::new(ManifestQueryDelegate::new(snapshot));
 2237
 2238        for server_id in
 2239            self.lsp_tree
 2240                .get(path, language.name(), language.manifest(), &delegate, cx)
 2241        {
 2242            let server = self
 2243                .language_servers
 2244                .get(&server_id)
 2245                .and_then(|server_state| {
 2246                    if let LanguageServerState::Running { server, .. } = server_state {
 2247                        Some(server.clone())
 2248                    } else {
 2249                        None
 2250                    }
 2251                });
 2252            let server = match server {
 2253                Some(server) => server,
 2254                None => continue,
 2255            };
 2256
 2257            buffer_handle.update(cx, |buffer, cx| {
 2258                buffer.set_completion_triggers(
 2259                    server.server_id(),
 2260                    server
 2261                        .capabilities()
 2262                        .completion_provider
 2263                        .as_ref()
 2264                        .and_then(|provider| {
 2265                            provider
 2266                                .trigger_characters
 2267                                .as_ref()
 2268                                .map(|characters| characters.iter().cloned().collect())
 2269                        })
 2270                        .unwrap_or_default(),
 2271                    cx,
 2272                );
 2273            });
 2274        }
 2275    }
 2276
 2277    pub(crate) fn reset_buffer(&mut self, buffer: &Entity<Buffer>, old_file: &File, cx: &mut App) {
 2278        buffer.update(cx, |buffer, cx| {
 2279            let Some(language) = buffer.language() else {
 2280                return;
 2281            };
 2282            let path = ProjectPath {
 2283                worktree_id: old_file.worktree_id(cx),
 2284                path: old_file.path.clone(),
 2285            };
 2286            for server_id in self.language_server_ids_for_project_path(path, language, cx) {
 2287                buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
 2288                buffer.set_completion_triggers(server_id, Default::default(), cx);
 2289            }
 2290        });
 2291    }
 2292
 2293    fn update_buffer_diagnostics(
 2294        &mut self,
 2295        buffer: &Entity<Buffer>,
 2296        server_id: LanguageServerId,
 2297        result_id: Option<String>,
 2298        version: Option<i32>,
 2299        new_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2300        reused_diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 2301        cx: &mut Context<LspStore>,
 2302    ) -> Result<()> {
 2303        fn compare_diagnostics(a: &Diagnostic, b: &Diagnostic) -> Ordering {
 2304            Ordering::Equal
 2305                .then_with(|| b.is_primary.cmp(&a.is_primary))
 2306                .then_with(|| a.is_disk_based.cmp(&b.is_disk_based))
 2307                .then_with(|| a.severity.cmp(&b.severity))
 2308                .then_with(|| a.message.cmp(&b.message))
 2309        }
 2310
 2311        let mut diagnostics = Vec::with_capacity(new_diagnostics.len() + reused_diagnostics.len());
 2312        diagnostics.extend(new_diagnostics.into_iter().map(|d| (true, d)));
 2313        diagnostics.extend(reused_diagnostics.into_iter().map(|d| (false, d)));
 2314
 2315        diagnostics.sort_unstable_by(|(_, a), (_, b)| {
 2316            Ordering::Equal
 2317                .then_with(|| a.range.start.cmp(&b.range.start))
 2318                .then_with(|| b.range.end.cmp(&a.range.end))
 2319                .then_with(|| compare_diagnostics(&a.diagnostic, &b.diagnostic))
 2320        });
 2321
 2322        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx)?;
 2323
 2324        let edits_since_save = std::cell::LazyCell::new(|| {
 2325            let saved_version = buffer.read(cx).saved_version();
 2326            Patch::new(snapshot.edits_since::<PointUtf16>(saved_version).collect())
 2327        });
 2328
 2329        let mut sanitized_diagnostics = Vec::with_capacity(diagnostics.len());
 2330
 2331        for (new_diagnostic, entry) in diagnostics {
 2332            let start;
 2333            let end;
 2334            if new_diagnostic && entry.diagnostic.is_disk_based {
 2335                // Some diagnostics are based on files on disk instead of buffers'
 2336                // current contents. Adjust these diagnostics' ranges to reflect
 2337                // any unsaved edits.
 2338                // Do not alter the reused ones though, as their coordinates were stored as anchors
 2339                // and were properly adjusted on reuse.
 2340                start = Unclipped((*edits_since_save).old_to_new(entry.range.start.0));
 2341                end = Unclipped((*edits_since_save).old_to_new(entry.range.end.0));
 2342            } else {
 2343                start = entry.range.start;
 2344                end = entry.range.end;
 2345            }
 2346
 2347            let mut range = snapshot.clip_point_utf16(start, Bias::Left)
 2348                ..snapshot.clip_point_utf16(end, Bias::Right);
 2349
 2350            // Expand empty ranges by one codepoint
 2351            if range.start == range.end {
 2352                // This will be go to the next boundary when being clipped
 2353                range.end.column += 1;
 2354                range.end = snapshot.clip_point_utf16(Unclipped(range.end), Bias::Right);
 2355                if range.start == range.end && range.end.column > 0 {
 2356                    range.start.column -= 1;
 2357                    range.start = snapshot.clip_point_utf16(Unclipped(range.start), Bias::Left);
 2358                }
 2359            }
 2360
 2361            sanitized_diagnostics.push(DiagnosticEntry {
 2362                range,
 2363                diagnostic: entry.diagnostic,
 2364            });
 2365        }
 2366        drop(edits_since_save);
 2367
 2368        let set = DiagnosticSet::new(sanitized_diagnostics, &snapshot);
 2369        buffer.update(cx, |buffer, cx| {
 2370            if let Some(abs_path) = File::from_dyn(buffer.file()).map(|f| f.abs_path(cx)) {
 2371                self.buffer_pull_diagnostics_result_ids
 2372                    .entry(server_id)
 2373                    .or_default()
 2374                    .insert(abs_path, result_id);
 2375            }
 2376
 2377            buffer.update_diagnostics(server_id, set, cx)
 2378        });
 2379
 2380        Ok(())
 2381    }
 2382
 2383    fn register_language_server_for_invisible_worktree(
 2384        &mut self,
 2385        worktree: &Entity<Worktree>,
 2386        language_server_id: LanguageServerId,
 2387        cx: &mut App,
 2388    ) {
 2389        let worktree = worktree.read(cx);
 2390        let worktree_id = worktree.id();
 2391        debug_assert!(!worktree.is_visible());
 2392        let Some(mut origin_seed) = self
 2393            .language_server_ids
 2394            .iter()
 2395            .find_map(|(seed, state)| (state.id == language_server_id).then(|| seed.clone()))
 2396        else {
 2397            return;
 2398        };
 2399        origin_seed.worktree_id = worktree_id;
 2400        self.language_server_ids
 2401            .entry(origin_seed)
 2402            .or_insert_with(|| UnifiedLanguageServer {
 2403                id: language_server_id,
 2404                project_roots: Default::default(),
 2405            });
 2406    }
 2407
 2408    fn register_buffer_with_language_servers(
 2409        &mut self,
 2410        buffer_handle: &Entity<Buffer>,
 2411        only_register_servers: HashSet<LanguageServerSelector>,
 2412        cx: &mut Context<LspStore>,
 2413    ) {
 2414        let buffer = buffer_handle.read(cx);
 2415        let buffer_id = buffer.remote_id();
 2416
 2417        let Some(file) = File::from_dyn(buffer.file()) else {
 2418            return;
 2419        };
 2420        if !file.is_local() {
 2421            return;
 2422        }
 2423
 2424        let abs_path = file.abs_path(cx);
 2425        let Some(uri) = file_path_to_lsp_url(&abs_path).log_err() else {
 2426            return;
 2427        };
 2428        let initial_snapshot = buffer.text_snapshot();
 2429        let worktree_id = file.worktree_id(cx);
 2430
 2431        let Some(language) = buffer.language().cloned() else {
 2432            return;
 2433        };
 2434        let path: Arc<RelPath> = file
 2435            .path()
 2436            .parent()
 2437            .map(Arc::from)
 2438            .unwrap_or_else(|| file.path().clone());
 2439        let Some(worktree) = self
 2440            .worktree_store
 2441            .read(cx)
 2442            .worktree_for_id(worktree_id, cx)
 2443        else {
 2444            return;
 2445        };
 2446        let language_name = language.name();
 2447        let (reused, delegate, servers) = self
 2448            .reuse_existing_language_server(&self.lsp_tree, &worktree, &language_name, cx)
 2449            .map(|(delegate, apply)| (true, delegate, apply(&mut self.lsp_tree)))
 2450            .unwrap_or_else(|| {
 2451                let lsp_delegate = LocalLspAdapterDelegate::from_local_lsp(self, &worktree, cx);
 2452                let delegate: Arc<dyn ManifestDelegate> =
 2453                    Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 2454
 2455                let servers = self
 2456                    .lsp_tree
 2457                    .walk(
 2458                        ProjectPath { worktree_id, path },
 2459                        language.name(),
 2460                        language.manifest(),
 2461                        &delegate,
 2462                        cx,
 2463                    )
 2464                    .collect::<Vec<_>>();
 2465                (false, lsp_delegate, servers)
 2466            });
 2467        let servers_and_adapters = servers
 2468            .into_iter()
 2469            .filter_map(|server_node| {
 2470                if reused && server_node.server_id().is_none() {
 2471                    return None;
 2472                }
 2473                if !only_register_servers.is_empty() {
 2474                    if let Some(server_id) = server_node.server_id()
 2475                        && !only_register_servers.contains(&LanguageServerSelector::Id(server_id))
 2476                    {
 2477                        return None;
 2478                    }
 2479                    if let Some(name) = server_node.name()
 2480                        && !only_register_servers.contains(&LanguageServerSelector::Name(name))
 2481                    {
 2482                        return None;
 2483                    }
 2484                }
 2485
 2486                let server_id = server_node.server_id_or_init(|disposition| {
 2487                    let path = &disposition.path;
 2488
 2489                    {
 2490                        let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 2491
 2492                        let server_id = self.get_or_insert_language_server(
 2493                            &worktree,
 2494                            delegate.clone(),
 2495                            disposition,
 2496                            &language_name,
 2497                            cx,
 2498                        );
 2499
 2500                        if let Some(state) = self.language_servers.get(&server_id)
 2501                            && let Ok(uri) = uri
 2502                        {
 2503                            state.add_workspace_folder(uri);
 2504                        };
 2505                        server_id
 2506                    }
 2507                })?;
 2508                let server_state = self.language_servers.get(&server_id)?;
 2509                if let LanguageServerState::Running {
 2510                    server, adapter, ..
 2511                } = server_state
 2512                {
 2513                    Some((server.clone(), adapter.clone()))
 2514                } else {
 2515                    None
 2516                }
 2517            })
 2518            .collect::<Vec<_>>();
 2519        for (server, adapter) in servers_and_adapters {
 2520            buffer_handle.update(cx, |buffer, cx| {
 2521                buffer.set_completion_triggers(
 2522                    server.server_id(),
 2523                    server
 2524                        .capabilities()
 2525                        .completion_provider
 2526                        .as_ref()
 2527                        .and_then(|provider| {
 2528                            provider
 2529                                .trigger_characters
 2530                                .as_ref()
 2531                                .map(|characters| characters.iter().cloned().collect())
 2532                        })
 2533                        .unwrap_or_default(),
 2534                    cx,
 2535                );
 2536            });
 2537
 2538            let snapshot = LspBufferSnapshot {
 2539                version: 0,
 2540                snapshot: initial_snapshot.clone(),
 2541            };
 2542
 2543            let mut registered = false;
 2544            self.buffer_snapshots
 2545                .entry(buffer_id)
 2546                .or_default()
 2547                .entry(server.server_id())
 2548                .or_insert_with(|| {
 2549                    registered = true;
 2550                    server.register_buffer(
 2551                        uri.clone(),
 2552                        adapter.language_id(&language.name()),
 2553                        0,
 2554                        initial_snapshot.text(),
 2555                    );
 2556
 2557                    vec![snapshot]
 2558                });
 2559
 2560            self.buffers_opened_in_servers
 2561                .entry(buffer_id)
 2562                .or_default()
 2563                .insert(server.server_id());
 2564            if registered {
 2565                cx.emit(LspStoreEvent::LanguageServerUpdate {
 2566                    language_server_id: server.server_id(),
 2567                    name: None,
 2568                    message: proto::update_language_server::Variant::RegisteredForBuffer(
 2569                        proto::RegisteredForBuffer {
 2570                            buffer_abs_path: abs_path.to_string_lossy().into_owned(),
 2571                            buffer_id: buffer_id.to_proto(),
 2572                        },
 2573                    ),
 2574                });
 2575            }
 2576        }
 2577    }
 2578
 2579    fn reuse_existing_language_server<'lang_name>(
 2580        &self,
 2581        server_tree: &LanguageServerTree,
 2582        worktree: &Entity<Worktree>,
 2583        language_name: &'lang_name LanguageName,
 2584        cx: &mut App,
 2585    ) -> Option<(
 2586        Arc<LocalLspAdapterDelegate>,
 2587        impl FnOnce(&mut LanguageServerTree) -> Vec<LanguageServerTreeNode> + use<'lang_name>,
 2588    )> {
 2589        if worktree.read(cx).is_visible() {
 2590            return None;
 2591        }
 2592
 2593        let worktree_store = self.worktree_store.read(cx);
 2594        let servers = server_tree
 2595            .instances
 2596            .iter()
 2597            .filter(|(worktree_id, _)| {
 2598                worktree_store
 2599                    .worktree_for_id(**worktree_id, cx)
 2600                    .is_some_and(|worktree| worktree.read(cx).is_visible())
 2601            })
 2602            .flat_map(|(worktree_id, servers)| {
 2603                servers
 2604                    .roots
 2605                    .iter()
 2606                    .flat_map(|(_, language_servers)| language_servers)
 2607                    .map(move |(_, (server_node, server_languages))| {
 2608                        (worktree_id, server_node, server_languages)
 2609                    })
 2610                    .filter(|(_, _, server_languages)| server_languages.contains(language_name))
 2611                    .map(|(worktree_id, server_node, _)| {
 2612                        (
 2613                            *worktree_id,
 2614                            LanguageServerTreeNode::from(Arc::downgrade(server_node)),
 2615                        )
 2616                    })
 2617            })
 2618            .fold(HashMap::default(), |mut acc, (worktree_id, server_node)| {
 2619                acc.entry(worktree_id)
 2620                    .or_insert_with(Vec::new)
 2621                    .push(server_node);
 2622                acc
 2623            })
 2624            .into_values()
 2625            .max_by_key(|servers| servers.len())?;
 2626
 2627        let worktree_id = worktree.read(cx).id();
 2628        let apply = move |tree: &mut LanguageServerTree| {
 2629            for server_node in &servers {
 2630                tree.register_reused(worktree_id, language_name.clone(), server_node.clone());
 2631            }
 2632            servers
 2633        };
 2634
 2635        let delegate = LocalLspAdapterDelegate::from_local_lsp(self, worktree, cx);
 2636        Some((delegate, apply))
 2637    }
 2638
 2639    pub(crate) fn unregister_old_buffer_from_language_servers(
 2640        &mut self,
 2641        buffer: &Entity<Buffer>,
 2642        old_file: &File,
 2643        cx: &mut App,
 2644    ) {
 2645        let old_path = match old_file.as_local() {
 2646            Some(local) => local.abs_path(cx),
 2647            None => return,
 2648        };
 2649
 2650        let Ok(file_url) = lsp::Uri::from_file_path(old_path.as_path()) else {
 2651            debug_panic!("{old_path:?} is not parseable as an URI");
 2652            return;
 2653        };
 2654        self.unregister_buffer_from_language_servers(buffer, &file_url, cx);
 2655    }
 2656
 2657    pub(crate) fn unregister_buffer_from_language_servers(
 2658        &mut self,
 2659        buffer: &Entity<Buffer>,
 2660        file_url: &lsp::Uri,
 2661        cx: &mut App,
 2662    ) {
 2663        buffer.update(cx, |buffer, cx| {
 2664            let _ = self.buffer_snapshots.remove(&buffer.remote_id());
 2665
 2666            for (_, language_server) in self.language_servers_for_buffer(buffer, cx) {
 2667                language_server.unregister_buffer(file_url.clone());
 2668            }
 2669        });
 2670    }
 2671
 2672    fn buffer_snapshot_for_lsp_version(
 2673        &mut self,
 2674        buffer: &Entity<Buffer>,
 2675        server_id: LanguageServerId,
 2676        version: Option<i32>,
 2677        cx: &App,
 2678    ) -> Result<TextBufferSnapshot> {
 2679        const OLD_VERSIONS_TO_RETAIN: i32 = 10;
 2680
 2681        if let Some(version) = version {
 2682            let buffer_id = buffer.read(cx).remote_id();
 2683            let snapshots = if let Some(snapshots) = self
 2684                .buffer_snapshots
 2685                .get_mut(&buffer_id)
 2686                .and_then(|m| m.get_mut(&server_id))
 2687            {
 2688                snapshots
 2689            } else if version == 0 {
 2690                // Some language servers report version 0 even if the buffer hasn't been opened yet.
 2691                // We detect this case and treat it as if the version was `None`.
 2692                return Ok(buffer.read(cx).text_snapshot());
 2693            } else {
 2694                anyhow::bail!("no snapshots found for buffer {buffer_id} and server {server_id}");
 2695            };
 2696
 2697            let found_snapshot = snapshots
 2698                    .binary_search_by_key(&version, |e| e.version)
 2699                    .map(|ix| snapshots[ix].snapshot.clone())
 2700                    .map_err(|_| {
 2701                        anyhow!("snapshot not found for buffer {buffer_id} server {server_id} at version {version}")
 2702                    })?;
 2703
 2704            snapshots.retain(|snapshot| snapshot.version + OLD_VERSIONS_TO_RETAIN >= version);
 2705            Ok(found_snapshot)
 2706        } else {
 2707            Ok((buffer.read(cx)).text_snapshot())
 2708        }
 2709    }
 2710
 2711    async fn get_server_code_actions_from_action_kinds(
 2712        lsp_store: &WeakEntity<LspStore>,
 2713        language_server_id: LanguageServerId,
 2714        code_action_kinds: Vec<lsp::CodeActionKind>,
 2715        buffer: &Entity<Buffer>,
 2716        cx: &mut AsyncApp,
 2717    ) -> Result<Vec<CodeAction>> {
 2718        let actions = lsp_store
 2719            .update(cx, move |this, cx| {
 2720                let request = GetCodeActions {
 2721                    range: text::Anchor::MIN..text::Anchor::MAX,
 2722                    kinds: Some(code_action_kinds),
 2723                };
 2724                let server = LanguageServerToQuery::Other(language_server_id);
 2725                this.request_lsp(buffer.clone(), server, request, cx)
 2726            })?
 2727            .await?;
 2728        Ok(actions)
 2729    }
 2730
 2731    pub async fn execute_code_actions_on_server(
 2732        lsp_store: &WeakEntity<LspStore>,
 2733        language_server: &Arc<LanguageServer>,
 2734
 2735        actions: Vec<CodeAction>,
 2736        push_to_history: bool,
 2737        project_transaction: &mut ProjectTransaction,
 2738        cx: &mut AsyncApp,
 2739    ) -> anyhow::Result<()> {
 2740        for mut action in actions {
 2741            Self::try_resolve_code_action(language_server, &mut action)
 2742                .await
 2743                .context("resolving a formatting code action")?;
 2744
 2745            if let Some(edit) = action.lsp_action.edit() {
 2746                if edit.changes.is_none() && edit.document_changes.is_none() {
 2747                    continue;
 2748                }
 2749
 2750                let new = Self::deserialize_workspace_edit(
 2751                    lsp_store.upgrade().context("project dropped")?,
 2752                    edit.clone(),
 2753                    push_to_history,
 2754                    language_server.clone(),
 2755                    cx,
 2756                )
 2757                .await?;
 2758                project_transaction.0.extend(new.0);
 2759            }
 2760
 2761            if let Some(command) = action.lsp_action.command() {
 2762                let server_capabilities = language_server.capabilities();
 2763                let available_commands = server_capabilities
 2764                    .execute_command_provider
 2765                    .as_ref()
 2766                    .map(|options| options.commands.as_slice())
 2767                    .unwrap_or_default();
 2768                if available_commands.contains(&command.command) {
 2769                    lsp_store.update(cx, |lsp_store, _| {
 2770                        if let LspStoreMode::Local(mode) = &mut lsp_store.mode {
 2771                            mode.last_workspace_edits_by_language_server
 2772                                .remove(&language_server.server_id());
 2773                        }
 2774                    })?;
 2775
 2776                    language_server
 2777                        .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 2778                            command: command.command.clone(),
 2779                            arguments: command.arguments.clone().unwrap_or_default(),
 2780                            ..Default::default()
 2781                        })
 2782                        .await
 2783                        .into_response()
 2784                        .context("execute command")?;
 2785
 2786                    lsp_store.update(cx, |this, _| {
 2787                        if let LspStoreMode::Local(mode) = &mut this.mode {
 2788                            project_transaction.0.extend(
 2789                                mode.last_workspace_edits_by_language_server
 2790                                    .remove(&language_server.server_id())
 2791                                    .unwrap_or_default()
 2792                                    .0,
 2793                            )
 2794                        }
 2795                    })?;
 2796                } else {
 2797                    log::warn!(
 2798                        "Cannot execute a command {} not listed in the language server capabilities",
 2799                        command.command
 2800                    )
 2801                }
 2802            }
 2803        }
 2804        Ok(())
 2805    }
 2806
 2807    pub async fn deserialize_text_edits(
 2808        this: Entity<LspStore>,
 2809        buffer_to_edit: Entity<Buffer>,
 2810        edits: Vec<lsp::TextEdit>,
 2811        push_to_history: bool,
 2812        _: Arc<CachedLspAdapter>,
 2813        language_server: Arc<LanguageServer>,
 2814        cx: &mut AsyncApp,
 2815    ) -> Result<Option<Transaction>> {
 2816        let edits = this
 2817            .update(cx, |this, cx| {
 2818                this.as_local_mut().unwrap().edits_from_lsp(
 2819                    &buffer_to_edit,
 2820                    edits,
 2821                    language_server.server_id(),
 2822                    None,
 2823                    cx,
 2824                )
 2825            })?
 2826            .await?;
 2827
 2828        let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 2829            buffer.finalize_last_transaction();
 2830            buffer.start_transaction();
 2831            for (range, text) in edits {
 2832                buffer.edit([(range, text)], None, cx);
 2833            }
 2834
 2835            if buffer.end_transaction(cx).is_some() {
 2836                let transaction = buffer.finalize_last_transaction().unwrap().clone();
 2837                if !push_to_history {
 2838                    buffer.forget_transaction(transaction.id);
 2839                }
 2840                Some(transaction)
 2841            } else {
 2842                None
 2843            }
 2844        })?;
 2845
 2846        Ok(transaction)
 2847    }
 2848
 2849    #[allow(clippy::type_complexity)]
 2850    pub(crate) fn edits_from_lsp(
 2851        &mut self,
 2852        buffer: &Entity<Buffer>,
 2853        lsp_edits: impl 'static + Send + IntoIterator<Item = lsp::TextEdit>,
 2854        server_id: LanguageServerId,
 2855        version: Option<i32>,
 2856        cx: &mut Context<LspStore>,
 2857    ) -> Task<Result<Vec<(Range<Anchor>, Arc<str>)>>> {
 2858        let snapshot = self.buffer_snapshot_for_lsp_version(buffer, server_id, version, cx);
 2859        cx.background_spawn(async move {
 2860            let snapshot = snapshot?;
 2861            let mut lsp_edits = lsp_edits
 2862                .into_iter()
 2863                .map(|edit| (range_from_lsp(edit.range), edit.new_text))
 2864                .collect::<Vec<_>>();
 2865
 2866            lsp_edits.sort_by_key(|(range, _)| (range.start, range.end));
 2867
 2868            let mut lsp_edits = lsp_edits.into_iter().peekable();
 2869            let mut edits = Vec::new();
 2870            while let Some((range, mut new_text)) = lsp_edits.next() {
 2871                // Clip invalid ranges provided by the language server.
 2872                let mut range = snapshot.clip_point_utf16(range.start, Bias::Left)
 2873                    ..snapshot.clip_point_utf16(range.end, Bias::Left);
 2874
 2875                // Combine any LSP edits that are adjacent.
 2876                //
 2877                // Also, combine LSP edits that are separated from each other by only
 2878                // a newline. This is important because for some code actions,
 2879                // Rust-analyzer rewrites the entire buffer via a series of edits that
 2880                // are separated by unchanged newline characters.
 2881                //
 2882                // In order for the diffing logic below to work properly, any edits that
 2883                // cancel each other out must be combined into one.
 2884                while let Some((next_range, next_text)) = lsp_edits.peek() {
 2885                    if next_range.start.0 > range.end {
 2886                        if next_range.start.0.row > range.end.row + 1
 2887                            || next_range.start.0.column > 0
 2888                            || snapshot.clip_point_utf16(
 2889                                Unclipped(PointUtf16::new(range.end.row, u32::MAX)),
 2890                                Bias::Left,
 2891                            ) > range.end
 2892                        {
 2893                            break;
 2894                        }
 2895                        new_text.push('\n');
 2896                    }
 2897                    range.end = snapshot.clip_point_utf16(next_range.end, Bias::Left);
 2898                    new_text.push_str(next_text);
 2899                    lsp_edits.next();
 2900                }
 2901
 2902                // For multiline edits, perform a diff of the old and new text so that
 2903                // we can identify the changes more precisely, preserving the locations
 2904                // of any anchors positioned in the unchanged regions.
 2905                if range.end.row > range.start.row {
 2906                    let offset = range.start.to_offset(&snapshot);
 2907                    let old_text = snapshot.text_for_range(range).collect::<String>();
 2908                    let range_edits = language::text_diff(old_text.as_str(), &new_text);
 2909                    edits.extend(range_edits.into_iter().map(|(range, replacement)| {
 2910                        (
 2911                            snapshot.anchor_after(offset + range.start)
 2912                                ..snapshot.anchor_before(offset + range.end),
 2913                            replacement,
 2914                        )
 2915                    }));
 2916                } else if range.end == range.start {
 2917                    let anchor = snapshot.anchor_after(range.start);
 2918                    edits.push((anchor..anchor, new_text.into()));
 2919                } else {
 2920                    let edit_start = snapshot.anchor_after(range.start);
 2921                    let edit_end = snapshot.anchor_before(range.end);
 2922                    edits.push((edit_start..edit_end, new_text.into()));
 2923                }
 2924            }
 2925
 2926            Ok(edits)
 2927        })
 2928    }
 2929
 2930    pub(crate) async fn deserialize_workspace_edit(
 2931        this: Entity<LspStore>,
 2932        edit: lsp::WorkspaceEdit,
 2933        push_to_history: bool,
 2934        language_server: Arc<LanguageServer>,
 2935        cx: &mut AsyncApp,
 2936    ) -> Result<ProjectTransaction> {
 2937        let fs = this.read_with(cx, |this, _| this.as_local().unwrap().fs.clone())?;
 2938
 2939        let mut operations = Vec::new();
 2940        if let Some(document_changes) = edit.document_changes {
 2941            match document_changes {
 2942                lsp::DocumentChanges::Edits(edits) => {
 2943                    operations.extend(edits.into_iter().map(lsp::DocumentChangeOperation::Edit))
 2944                }
 2945                lsp::DocumentChanges::Operations(ops) => operations = ops,
 2946            }
 2947        } else if let Some(changes) = edit.changes {
 2948            operations.extend(changes.into_iter().map(|(uri, edits)| {
 2949                lsp::DocumentChangeOperation::Edit(lsp::TextDocumentEdit {
 2950                    text_document: lsp::OptionalVersionedTextDocumentIdentifier {
 2951                        uri,
 2952                        version: None,
 2953                    },
 2954                    edits: edits.into_iter().map(Edit::Plain).collect(),
 2955                })
 2956            }));
 2957        }
 2958
 2959        let mut project_transaction = ProjectTransaction::default();
 2960        for operation in operations {
 2961            match operation {
 2962                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Create(op)) => {
 2963                    let abs_path = op
 2964                        .uri
 2965                        .to_file_path()
 2966                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2967
 2968                    if let Some(parent_path) = abs_path.parent() {
 2969                        fs.create_dir(parent_path).await?;
 2970                    }
 2971                    if abs_path.ends_with("/") {
 2972                        fs.create_dir(&abs_path).await?;
 2973                    } else {
 2974                        fs.create_file(
 2975                            &abs_path,
 2976                            op.options
 2977                                .map(|options| fs::CreateOptions {
 2978                                    overwrite: options.overwrite.unwrap_or(false),
 2979                                    ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 2980                                })
 2981                                .unwrap_or_default(),
 2982                        )
 2983                        .await?;
 2984                    }
 2985                }
 2986
 2987                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Rename(op)) => {
 2988                    let source_abs_path = op
 2989                        .old_uri
 2990                        .to_file_path()
 2991                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2992                    let target_abs_path = op
 2993                        .new_uri
 2994                        .to_file_path()
 2995                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 2996                    fs.rename(
 2997                        &source_abs_path,
 2998                        &target_abs_path,
 2999                        op.options
 3000                            .map(|options| fs::RenameOptions {
 3001                                overwrite: options.overwrite.unwrap_or(false),
 3002                                ignore_if_exists: options.ignore_if_exists.unwrap_or(false),
 3003                            })
 3004                            .unwrap_or_default(),
 3005                    )
 3006                    .await?;
 3007                }
 3008
 3009                lsp::DocumentChangeOperation::Op(lsp::ResourceOp::Delete(op)) => {
 3010                    let abs_path = op
 3011                        .uri
 3012                        .to_file_path()
 3013                        .map_err(|()| anyhow!("can't convert URI to path"))?;
 3014                    let options = op
 3015                        .options
 3016                        .map(|options| fs::RemoveOptions {
 3017                            recursive: options.recursive.unwrap_or(false),
 3018                            ignore_if_not_exists: options.ignore_if_not_exists.unwrap_or(false),
 3019                        })
 3020                        .unwrap_or_default();
 3021                    if abs_path.ends_with("/") {
 3022                        fs.remove_dir(&abs_path, options).await?;
 3023                    } else {
 3024                        fs.remove_file(&abs_path, options).await?;
 3025                    }
 3026                }
 3027
 3028                lsp::DocumentChangeOperation::Edit(op) => {
 3029                    let buffer_to_edit = this
 3030                        .update(cx, |this, cx| {
 3031                            this.open_local_buffer_via_lsp(
 3032                                op.text_document.uri.clone(),
 3033                                language_server.server_id(),
 3034                                cx,
 3035                            )
 3036                        })?
 3037                        .await?;
 3038
 3039                    let edits = this
 3040                        .update(cx, |this, cx| {
 3041                            let path = buffer_to_edit.read(cx).project_path(cx);
 3042                            let active_entry = this.active_entry;
 3043                            let is_active_entry = path.is_some_and(|project_path| {
 3044                                this.worktree_store
 3045                                    .read(cx)
 3046                                    .entry_for_path(&project_path, cx)
 3047                                    .is_some_and(|entry| Some(entry.id) == active_entry)
 3048                            });
 3049                            let local = this.as_local_mut().unwrap();
 3050
 3051                            let (mut edits, mut snippet_edits) = (vec![], vec![]);
 3052                            for edit in op.edits {
 3053                                match edit {
 3054                                    Edit::Plain(edit) => {
 3055                                        if !edits.contains(&edit) {
 3056                                            edits.push(edit)
 3057                                        }
 3058                                    }
 3059                                    Edit::Annotated(edit) => {
 3060                                        if !edits.contains(&edit.text_edit) {
 3061                                            edits.push(edit.text_edit)
 3062                                        }
 3063                                    }
 3064                                    Edit::Snippet(edit) => {
 3065                                        let Ok(snippet) = Snippet::parse(&edit.snippet.value)
 3066                                        else {
 3067                                            continue;
 3068                                        };
 3069
 3070                                        if is_active_entry {
 3071                                            snippet_edits.push((edit.range, snippet));
 3072                                        } else {
 3073                                            // Since this buffer is not focused, apply a normal edit.
 3074                                            let new_edit = TextEdit {
 3075                                                range: edit.range,
 3076                                                new_text: snippet.text,
 3077                                            };
 3078                                            if !edits.contains(&new_edit) {
 3079                                                edits.push(new_edit);
 3080                                            }
 3081                                        }
 3082                                    }
 3083                                }
 3084                            }
 3085                            if !snippet_edits.is_empty() {
 3086                                let buffer_id = buffer_to_edit.read(cx).remote_id();
 3087                                let version = if let Some(buffer_version) = op.text_document.version
 3088                                {
 3089                                    local
 3090                                        .buffer_snapshot_for_lsp_version(
 3091                                            &buffer_to_edit,
 3092                                            language_server.server_id(),
 3093                                            Some(buffer_version),
 3094                                            cx,
 3095                                        )
 3096                                        .ok()
 3097                                        .map(|snapshot| snapshot.version)
 3098                                } else {
 3099                                    Some(buffer_to_edit.read(cx).saved_version().clone())
 3100                                };
 3101
 3102                                let most_recent_edit =
 3103                                    version.and_then(|version| version.most_recent());
 3104                                // Check if the edit that triggered that edit has been made by this participant.
 3105
 3106                                if let Some(most_recent_edit) = most_recent_edit {
 3107                                    cx.emit(LspStoreEvent::SnippetEdit {
 3108                                        buffer_id,
 3109                                        edits: snippet_edits,
 3110                                        most_recent_edit,
 3111                                    });
 3112                                }
 3113                            }
 3114
 3115                            local.edits_from_lsp(
 3116                                &buffer_to_edit,
 3117                                edits,
 3118                                language_server.server_id(),
 3119                                op.text_document.version,
 3120                                cx,
 3121                            )
 3122                        })?
 3123                        .await?;
 3124
 3125                    let transaction = buffer_to_edit.update(cx, |buffer, cx| {
 3126                        buffer.finalize_last_transaction();
 3127                        buffer.start_transaction();
 3128                        for (range, text) in edits {
 3129                            buffer.edit([(range, text)], None, cx);
 3130                        }
 3131
 3132                        buffer.end_transaction(cx).and_then(|transaction_id| {
 3133                            if push_to_history {
 3134                                buffer.finalize_last_transaction();
 3135                                buffer.get_transaction(transaction_id).cloned()
 3136                            } else {
 3137                                buffer.forget_transaction(transaction_id)
 3138                            }
 3139                        })
 3140                    })?;
 3141                    if let Some(transaction) = transaction {
 3142                        project_transaction.0.insert(buffer_to_edit, transaction);
 3143                    }
 3144                }
 3145            }
 3146        }
 3147
 3148        Ok(project_transaction)
 3149    }
 3150
 3151    async fn on_lsp_workspace_edit(
 3152        this: WeakEntity<LspStore>,
 3153        params: lsp::ApplyWorkspaceEditParams,
 3154        server_id: LanguageServerId,
 3155        cx: &mut AsyncApp,
 3156    ) -> Result<lsp::ApplyWorkspaceEditResponse> {
 3157        let this = this.upgrade().context("project project closed")?;
 3158        let language_server = this
 3159            .read_with(cx, |this, _| this.language_server_for_id(server_id))?
 3160            .context("language server not found")?;
 3161        let transaction = Self::deserialize_workspace_edit(
 3162            this.clone(),
 3163            params.edit,
 3164            true,
 3165            language_server.clone(),
 3166            cx,
 3167        )
 3168        .await
 3169        .log_err();
 3170        this.update(cx, |this, _| {
 3171            if let Some(transaction) = transaction {
 3172                this.as_local_mut()
 3173                    .unwrap()
 3174                    .last_workspace_edits_by_language_server
 3175                    .insert(server_id, transaction);
 3176            }
 3177        })?;
 3178        Ok(lsp::ApplyWorkspaceEditResponse {
 3179            applied: true,
 3180            failed_change: None,
 3181            failure_reason: None,
 3182        })
 3183    }
 3184
 3185    fn remove_worktree(
 3186        &mut self,
 3187        id_to_remove: WorktreeId,
 3188        cx: &mut Context<LspStore>,
 3189    ) -> Vec<LanguageServerId> {
 3190        self.diagnostics.remove(&id_to_remove);
 3191        self.prettier_store.update(cx, |prettier_store, cx| {
 3192            prettier_store.remove_worktree(id_to_remove, cx);
 3193        });
 3194
 3195        let mut servers_to_remove = BTreeSet::default();
 3196        let mut servers_to_preserve = HashSet::default();
 3197        for (seed, state) in &self.language_server_ids {
 3198            if seed.worktree_id == id_to_remove {
 3199                servers_to_remove.insert(state.id);
 3200            } else {
 3201                servers_to_preserve.insert(state.id);
 3202            }
 3203        }
 3204        servers_to_remove.retain(|server_id| !servers_to_preserve.contains(server_id));
 3205        self.language_server_ids
 3206            .retain(|_, state| !servers_to_remove.contains(&state.id));
 3207        for server_id_to_remove in &servers_to_remove {
 3208            self.language_server_watched_paths
 3209                .remove(server_id_to_remove);
 3210            self.language_server_paths_watched_for_rename
 3211                .remove(server_id_to_remove);
 3212            self.last_workspace_edits_by_language_server
 3213                .remove(server_id_to_remove);
 3214            self.language_servers.remove(server_id_to_remove);
 3215            self.buffer_pull_diagnostics_result_ids
 3216                .remove(server_id_to_remove);
 3217            for buffer_servers in self.buffers_opened_in_servers.values_mut() {
 3218                buffer_servers.remove(server_id_to_remove);
 3219            }
 3220            cx.emit(LspStoreEvent::LanguageServerRemoved(*server_id_to_remove));
 3221        }
 3222        servers_to_remove.into_iter().collect()
 3223    }
 3224
 3225    fn rebuild_watched_paths_inner<'a>(
 3226        &'a self,
 3227        language_server_id: LanguageServerId,
 3228        watchers: impl Iterator<Item = &'a FileSystemWatcher>,
 3229        cx: &mut Context<LspStore>,
 3230    ) -> LanguageServerWatchedPathsBuilder {
 3231        let worktrees = self
 3232            .worktree_store
 3233            .read(cx)
 3234            .worktrees()
 3235            .filter_map(|worktree| {
 3236                self.language_servers_for_worktree(worktree.read(cx).id())
 3237                    .find(|server| server.server_id() == language_server_id)
 3238                    .map(|_| worktree)
 3239            })
 3240            .collect::<Vec<_>>();
 3241
 3242        let mut worktree_globs = HashMap::default();
 3243        let mut abs_globs = HashMap::default();
 3244        log::trace!(
 3245            "Processing new watcher paths for language server with id {}",
 3246            language_server_id
 3247        );
 3248
 3249        for watcher in watchers {
 3250            if let Some((worktree, literal_prefix, pattern)) =
 3251                Self::worktree_and_path_for_file_watcher(&worktrees, watcher, cx)
 3252            {
 3253                worktree.update(cx, |worktree, _| {
 3254                    if let Some((tree, glob)) =
 3255                        worktree.as_local_mut().zip(Glob::new(&pattern).log_err())
 3256                    {
 3257                        tree.add_path_prefix_to_scan(literal_prefix);
 3258                        worktree_globs
 3259                            .entry(tree.id())
 3260                            .or_insert_with(GlobSetBuilder::new)
 3261                            .add(glob);
 3262                    }
 3263                });
 3264            } else {
 3265                let (path, pattern) = match &watcher.glob_pattern {
 3266                    lsp::GlobPattern::String(s) => {
 3267                        let watcher_path = SanitizedPath::new(s);
 3268                        let path = glob_literal_prefix(watcher_path.as_path());
 3269                        let pattern = watcher_path
 3270                            .as_path()
 3271                            .strip_prefix(&path)
 3272                            .map(|p| p.to_string_lossy().into_owned())
 3273                            .unwrap_or_else(|e| {
 3274                                debug_panic!(
 3275                                    "Failed to strip prefix for string pattern: {}, with prefix: {}, with error: {}",
 3276                                    s,
 3277                                    path.display(),
 3278                                    e
 3279                                );
 3280                                watcher_path.as_path().to_string_lossy().into_owned()
 3281                            });
 3282                        (path, pattern)
 3283                    }
 3284                    lsp::GlobPattern::Relative(rp) => {
 3285                        let Ok(mut base_uri) = match &rp.base_uri {
 3286                            lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3287                            lsp::OneOf::Right(base_uri) => base_uri,
 3288                        }
 3289                        .to_file_path() else {
 3290                            continue;
 3291                        };
 3292
 3293                        let path = glob_literal_prefix(Path::new(&rp.pattern));
 3294                        let pattern = Path::new(&rp.pattern)
 3295                            .strip_prefix(&path)
 3296                            .map(|p| p.to_string_lossy().into_owned())
 3297                            .unwrap_or_else(|e| {
 3298                                debug_panic!(
 3299                                    "Failed to strip prefix for relative pattern: {}, with prefix: {}, with error: {}",
 3300                                    rp.pattern,
 3301                                    path.display(),
 3302                                    e
 3303                                );
 3304                                rp.pattern.clone()
 3305                            });
 3306                        base_uri.push(path);
 3307                        (base_uri, pattern)
 3308                    }
 3309                };
 3310
 3311                if let Some(glob) = Glob::new(&pattern).log_err() {
 3312                    if !path
 3313                        .components()
 3314                        .any(|c| matches!(c, path::Component::Normal(_)))
 3315                    {
 3316                        // For an unrooted glob like `**/Cargo.toml`, watch it within each worktree,
 3317                        // rather than adding a new watcher for `/`.
 3318                        for worktree in &worktrees {
 3319                            worktree_globs
 3320                                .entry(worktree.read(cx).id())
 3321                                .or_insert_with(GlobSetBuilder::new)
 3322                                .add(glob.clone());
 3323                        }
 3324                    } else {
 3325                        abs_globs
 3326                            .entry(path.into())
 3327                            .or_insert_with(GlobSetBuilder::new)
 3328                            .add(glob);
 3329                    }
 3330                }
 3331            }
 3332        }
 3333
 3334        let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
 3335        for (worktree_id, builder) in worktree_globs {
 3336            if let Ok(globset) = builder.build() {
 3337                watch_builder.watch_worktree(worktree_id, globset);
 3338            }
 3339        }
 3340        for (abs_path, builder) in abs_globs {
 3341            if let Ok(globset) = builder.build() {
 3342                watch_builder.watch_abs_path(abs_path, globset);
 3343            }
 3344        }
 3345        watch_builder
 3346    }
 3347
 3348    fn worktree_and_path_for_file_watcher(
 3349        worktrees: &[Entity<Worktree>],
 3350        watcher: &FileSystemWatcher,
 3351        cx: &App,
 3352    ) -> Option<(Entity<Worktree>, Arc<RelPath>, String)> {
 3353        worktrees.iter().find_map(|worktree| {
 3354            let tree = worktree.read(cx);
 3355            let worktree_root_path = tree.abs_path();
 3356            let path_style = tree.path_style();
 3357            match &watcher.glob_pattern {
 3358                lsp::GlobPattern::String(s) => {
 3359                    let watcher_path = SanitizedPath::new(s);
 3360                    let relative = watcher_path
 3361                        .as_path()
 3362                        .strip_prefix(&worktree_root_path)
 3363                        .ok()?;
 3364                    let literal_prefix = glob_literal_prefix(relative);
 3365                    Some((
 3366                        worktree.clone(),
 3367                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3368                        relative.to_string_lossy().into_owned(),
 3369                    ))
 3370                }
 3371                lsp::GlobPattern::Relative(rp) => {
 3372                    let base_uri = match &rp.base_uri {
 3373                        lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
 3374                        lsp::OneOf::Right(base_uri) => base_uri,
 3375                    }
 3376                    .to_file_path()
 3377                    .ok()?;
 3378                    let relative = base_uri.strip_prefix(&worktree_root_path).ok()?;
 3379                    let mut literal_prefix = relative.to_owned();
 3380                    literal_prefix.push(glob_literal_prefix(Path::new(&rp.pattern)));
 3381                    Some((
 3382                        worktree.clone(),
 3383                        RelPath::new(&literal_prefix, path_style).ok()?.into_arc(),
 3384                        rp.pattern.clone(),
 3385                    ))
 3386                }
 3387            }
 3388        })
 3389    }
 3390
 3391    fn rebuild_watched_paths(
 3392        &mut self,
 3393        language_server_id: LanguageServerId,
 3394        cx: &mut Context<LspStore>,
 3395    ) {
 3396        let Some(registrations) = self
 3397            .language_server_dynamic_registrations
 3398            .get(&language_server_id)
 3399        else {
 3400            return;
 3401        };
 3402
 3403        let watch_builder = self.rebuild_watched_paths_inner(
 3404            language_server_id,
 3405            registrations.did_change_watched_files.values().flatten(),
 3406            cx,
 3407        );
 3408        let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
 3409        self.language_server_watched_paths
 3410            .insert(language_server_id, watcher);
 3411
 3412        cx.notify();
 3413    }
 3414
 3415    fn on_lsp_did_change_watched_files(
 3416        &mut self,
 3417        language_server_id: LanguageServerId,
 3418        registration_id: &str,
 3419        params: DidChangeWatchedFilesRegistrationOptions,
 3420        cx: &mut Context<LspStore>,
 3421    ) {
 3422        let registrations = self
 3423            .language_server_dynamic_registrations
 3424            .entry(language_server_id)
 3425            .or_default();
 3426
 3427        registrations
 3428            .did_change_watched_files
 3429            .insert(registration_id.to_string(), params.watchers);
 3430
 3431        self.rebuild_watched_paths(language_server_id, cx);
 3432    }
 3433
 3434    fn on_lsp_unregister_did_change_watched_files(
 3435        &mut self,
 3436        language_server_id: LanguageServerId,
 3437        registration_id: &str,
 3438        cx: &mut Context<LspStore>,
 3439    ) {
 3440        let registrations = self
 3441            .language_server_dynamic_registrations
 3442            .entry(language_server_id)
 3443            .or_default();
 3444
 3445        if registrations
 3446            .did_change_watched_files
 3447            .remove(registration_id)
 3448            .is_some()
 3449        {
 3450            log::info!(
 3451                "language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
 3452                language_server_id,
 3453                registration_id
 3454            );
 3455        } else {
 3456            log::warn!(
 3457                "language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
 3458                language_server_id,
 3459                registration_id
 3460            );
 3461        }
 3462
 3463        self.rebuild_watched_paths(language_server_id, cx);
 3464    }
 3465
 3466    async fn initialization_options_for_adapter(
 3467        adapter: Arc<dyn LspAdapter>,
 3468        delegate: &Arc<dyn LspAdapterDelegate>,
 3469    ) -> Result<Option<serde_json::Value>> {
 3470        let Some(mut initialization_config) =
 3471            adapter.clone().initialization_options(delegate).await?
 3472        else {
 3473            return Ok(None);
 3474        };
 3475
 3476        for other_adapter in delegate.registered_lsp_adapters() {
 3477            if other_adapter.name() == adapter.name() {
 3478                continue;
 3479            }
 3480            if let Ok(Some(target_config)) = other_adapter
 3481                .clone()
 3482                .additional_initialization_options(adapter.name(), delegate)
 3483                .await
 3484            {
 3485                merge_json_value_into(target_config.clone(), &mut initialization_config);
 3486            }
 3487        }
 3488
 3489        Ok(Some(initialization_config))
 3490    }
 3491
 3492    async fn workspace_configuration_for_adapter(
 3493        adapter: Arc<dyn LspAdapter>,
 3494        delegate: &Arc<dyn LspAdapterDelegate>,
 3495        toolchain: Option<Toolchain>,
 3496        cx: &mut AsyncApp,
 3497    ) -> Result<serde_json::Value> {
 3498        let mut workspace_config = adapter
 3499            .clone()
 3500            .workspace_configuration(delegate, toolchain, cx)
 3501            .await?;
 3502
 3503        for other_adapter in delegate.registered_lsp_adapters() {
 3504            if other_adapter.name() == adapter.name() {
 3505                continue;
 3506            }
 3507            if let Ok(Some(target_config)) = other_adapter
 3508                .clone()
 3509                .additional_workspace_configuration(adapter.name(), delegate, cx)
 3510                .await
 3511            {
 3512                merge_json_value_into(target_config.clone(), &mut workspace_config);
 3513            }
 3514        }
 3515
 3516        Ok(workspace_config)
 3517    }
 3518
 3519    fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 3520        if let Some(LanguageServerState::Running { server, .. }) = self.language_servers.get(&id) {
 3521            Some(server.clone())
 3522        } else if let Some((_, server)) = self.supplementary_language_servers.get(&id) {
 3523            Some(Arc::clone(server))
 3524        } else {
 3525            None
 3526        }
 3527    }
 3528}
 3529
 3530fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<LspStore>) {
 3531    if let Some(capabilities) = serde_json::to_string(&server.capabilities()).ok() {
 3532        cx.emit(LspStoreEvent::LanguageServerUpdate {
 3533            language_server_id: server.server_id(),
 3534            name: Some(server.name()),
 3535            message: proto::update_language_server::Variant::MetadataUpdated(
 3536                proto::ServerMetadataUpdated {
 3537                    capabilities: Some(capabilities),
 3538                },
 3539            ),
 3540        });
 3541    }
 3542}
 3543
 3544#[derive(Debug)]
 3545pub struct FormattableBuffer {
 3546    handle: Entity<Buffer>,
 3547    abs_path: Option<PathBuf>,
 3548    env: Option<HashMap<String, String>>,
 3549    ranges: Option<Vec<Range<Anchor>>>,
 3550}
 3551
 3552pub struct RemoteLspStore {
 3553    upstream_client: Option<AnyProtoClient>,
 3554    upstream_project_id: u64,
 3555}
 3556
 3557pub(crate) enum LspStoreMode {
 3558    Local(LocalLspStore),   // ssh host and collab host
 3559    Remote(RemoteLspStore), // collab guest
 3560}
 3561
 3562impl LspStoreMode {
 3563    fn is_local(&self) -> bool {
 3564        matches!(self, LspStoreMode::Local(_))
 3565    }
 3566}
 3567
 3568pub struct LspStore {
 3569    mode: LspStoreMode,
 3570    last_formatting_failure: Option<String>,
 3571    downstream_client: Option<(AnyProtoClient, u64)>,
 3572    nonce: u128,
 3573    buffer_store: Entity<BufferStore>,
 3574    worktree_store: Entity<WorktreeStore>,
 3575    pub languages: Arc<LanguageRegistry>,
 3576    pub language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
 3577    active_entry: Option<ProjectEntryId>,
 3578    _maintain_workspace_config: (Task<Result<()>>, watch::Sender<()>),
 3579    _maintain_buffer_languages: Task<()>,
 3580    diagnostic_summaries:
 3581        HashMap<WorktreeId, HashMap<Arc<RelPath>, HashMap<LanguageServerId, DiagnosticSummary>>>,
 3582    pub lsp_server_capabilities: HashMap<LanguageServerId, lsp::ServerCapabilities>,
 3583    lsp_data: HashMap<BufferId, BufferLspData>,
 3584    next_hint_id: Arc<AtomicUsize>,
 3585}
 3586
 3587#[derive(Debug)]
 3588pub struct BufferLspData {
 3589    buffer_version: Global,
 3590    document_colors: Option<DocumentColorData>,
 3591    code_lens: Option<CodeLensData>,
 3592    inlay_hints: BufferInlayHints,
 3593    lsp_requests: HashMap<LspKey, HashMap<LspRequestId, Task<()>>>,
 3594    chunk_lsp_requests: HashMap<LspKey, HashMap<BufferChunk, LspRequestId>>,
 3595}
 3596
 3597#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 3598struct LspKey {
 3599    request_type: TypeId,
 3600    server_queried: Option<LanguageServerId>,
 3601}
 3602
 3603impl BufferLspData {
 3604    fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
 3605        Self {
 3606            buffer_version: buffer.read(cx).version(),
 3607            document_colors: None,
 3608            code_lens: None,
 3609            inlay_hints: BufferInlayHints::new(buffer, cx),
 3610            lsp_requests: HashMap::default(),
 3611            chunk_lsp_requests: HashMap::default(),
 3612        }
 3613    }
 3614
 3615    fn remove_server_data(&mut self, for_server: LanguageServerId) {
 3616        if let Some(document_colors) = &mut self.document_colors {
 3617            document_colors.colors.remove(&for_server);
 3618            document_colors.cache_version += 1;
 3619        }
 3620
 3621        if let Some(code_lens) = &mut self.code_lens {
 3622            code_lens.lens.remove(&for_server);
 3623        }
 3624
 3625        self.inlay_hints.remove_server_data(for_server);
 3626    }
 3627
 3628    #[cfg(any(test, feature = "test-support"))]
 3629    pub fn inlay_hints(&self) -> &BufferInlayHints {
 3630        &self.inlay_hints
 3631    }
 3632}
 3633
 3634#[derive(Debug, Default, Clone)]
 3635pub struct DocumentColors {
 3636    pub colors: HashSet<DocumentColor>,
 3637    pub cache_version: Option<usize>,
 3638}
 3639
 3640type DocumentColorTask = Shared<Task<std::result::Result<DocumentColors, Arc<anyhow::Error>>>>;
 3641type CodeLensTask = Shared<Task<std::result::Result<Option<Vec<CodeAction>>, Arc<anyhow::Error>>>>;
 3642
 3643#[derive(Debug, Default)]
 3644struct DocumentColorData {
 3645    colors: HashMap<LanguageServerId, HashSet<DocumentColor>>,
 3646    cache_version: usize,
 3647    colors_update: Option<(Global, DocumentColorTask)>,
 3648}
 3649
 3650#[derive(Debug, Default)]
 3651struct CodeLensData {
 3652    lens: HashMap<LanguageServerId, Vec<CodeAction>>,
 3653    update: Option<(Global, CodeLensTask)>,
 3654}
 3655
 3656#[derive(Debug)]
 3657pub enum LspStoreEvent {
 3658    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),
 3659    LanguageServerRemoved(LanguageServerId),
 3660    LanguageServerUpdate {
 3661        language_server_id: LanguageServerId,
 3662        name: Option<LanguageServerName>,
 3663        message: proto::update_language_server::Variant,
 3664    },
 3665    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
 3666    LanguageServerPrompt(LanguageServerPromptRequest),
 3667    LanguageDetected {
 3668        buffer: Entity<Buffer>,
 3669        new_language: Option<Arc<Language>>,
 3670    },
 3671    Notification(String),
 3672    RefreshInlayHints {
 3673        server_id: LanguageServerId,
 3674        request_id: Option<usize>,
 3675    },
 3676    RefreshCodeLens,
 3677    DiagnosticsUpdated {
 3678        server_id: LanguageServerId,
 3679        paths: Vec<ProjectPath>,
 3680    },
 3681    DiskBasedDiagnosticsStarted {
 3682        language_server_id: LanguageServerId,
 3683    },
 3684    DiskBasedDiagnosticsFinished {
 3685        language_server_id: LanguageServerId,
 3686    },
 3687    SnippetEdit {
 3688        buffer_id: BufferId,
 3689        edits: Vec<(lsp::Range, Snippet)>,
 3690        most_recent_edit: clock::Lamport,
 3691    },
 3692}
 3693
 3694#[derive(Clone, Debug, Serialize)]
 3695pub struct LanguageServerStatus {
 3696    pub name: LanguageServerName,
 3697    pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
 3698    pub has_pending_diagnostic_updates: bool,
 3699    progress_tokens: HashSet<ProgressToken>,
 3700    pub worktree: Option<WorktreeId>,
 3701}
 3702
 3703#[derive(Clone, Debug)]
 3704struct CoreSymbol {
 3705    pub language_server_name: LanguageServerName,
 3706    pub source_worktree_id: WorktreeId,
 3707    pub source_language_server_id: LanguageServerId,
 3708    pub path: SymbolLocation,
 3709    pub name: String,
 3710    pub kind: lsp::SymbolKind,
 3711    pub range: Range<Unclipped<PointUtf16>>,
 3712}
 3713
 3714#[derive(Clone, Debug, PartialEq, Eq)]
 3715pub enum SymbolLocation {
 3716    InProject(ProjectPath),
 3717    OutsideProject {
 3718        abs_path: Arc<Path>,
 3719        signature: [u8; 32],
 3720    },
 3721}
 3722
 3723impl SymbolLocation {
 3724    fn file_name(&self) -> Option<&str> {
 3725        match self {
 3726            Self::InProject(path) => path.path.file_name(),
 3727            Self::OutsideProject { abs_path, .. } => abs_path.file_name()?.to_str(),
 3728        }
 3729    }
 3730}
 3731
 3732impl LspStore {
 3733    pub fn init(client: &AnyProtoClient) {
 3734        client.add_entity_request_handler(Self::handle_lsp_query);
 3735        client.add_entity_message_handler(Self::handle_lsp_query_response);
 3736        client.add_entity_request_handler(Self::handle_restart_language_servers);
 3737        client.add_entity_request_handler(Self::handle_stop_language_servers);
 3738        client.add_entity_request_handler(Self::handle_cancel_language_server_work);
 3739        client.add_entity_message_handler(Self::handle_start_language_server);
 3740        client.add_entity_message_handler(Self::handle_update_language_server);
 3741        client.add_entity_message_handler(Self::handle_language_server_log);
 3742        client.add_entity_message_handler(Self::handle_update_diagnostic_summary);
 3743        client.add_entity_request_handler(Self::handle_format_buffers);
 3744        client.add_entity_request_handler(Self::handle_apply_code_action_kind);
 3745        client.add_entity_request_handler(Self::handle_resolve_completion_documentation);
 3746        client.add_entity_request_handler(Self::handle_apply_code_action);
 3747        client.add_entity_request_handler(Self::handle_get_project_symbols);
 3748        client.add_entity_request_handler(Self::handle_resolve_inlay_hint);
 3749        client.add_entity_request_handler(Self::handle_get_color_presentation);
 3750        client.add_entity_request_handler(Self::handle_open_buffer_for_symbol);
 3751        client.add_entity_request_handler(Self::handle_refresh_inlay_hints);
 3752        client.add_entity_request_handler(Self::handle_refresh_code_lens);
 3753        client.add_entity_request_handler(Self::handle_on_type_formatting);
 3754        client.add_entity_request_handler(Self::handle_apply_additional_edits_for_completion);
 3755        client.add_entity_request_handler(Self::handle_register_buffer_with_language_servers);
 3756        client.add_entity_request_handler(Self::handle_rename_project_entry);
 3757        client.add_entity_request_handler(Self::handle_pull_workspace_diagnostics);
 3758        client.add_entity_request_handler(Self::handle_lsp_command::<GetCompletions>);
 3759        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentHighlights>);
 3760        client.add_entity_request_handler(Self::handle_lsp_command::<GetDocumentSymbols>);
 3761        client.add_entity_request_handler(Self::handle_lsp_command::<PrepareRename>);
 3762        client.add_entity_request_handler(Self::handle_lsp_command::<PerformRename>);
 3763        client.add_entity_request_handler(Self::handle_lsp_command::<LinkedEditingRange>);
 3764
 3765        client.add_entity_request_handler(Self::handle_lsp_ext_cancel_flycheck);
 3766        client.add_entity_request_handler(Self::handle_lsp_ext_run_flycheck);
 3767        client.add_entity_request_handler(Self::handle_lsp_ext_clear_flycheck);
 3768        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::ExpandMacro>);
 3769        client.add_entity_request_handler(Self::handle_lsp_command::<lsp_ext_command::OpenDocs>);
 3770        client.add_entity_request_handler(
 3771            Self::handle_lsp_command::<lsp_ext_command::GoToParentModule>,
 3772        );
 3773        client.add_entity_request_handler(
 3774            Self::handle_lsp_command::<lsp_ext_command::GetLspRunnables>,
 3775        );
 3776        client.add_entity_request_handler(
 3777            Self::handle_lsp_command::<lsp_ext_command::SwitchSourceHeader>,
 3778        );
 3779    }
 3780
 3781    pub fn as_remote(&self) -> Option<&RemoteLspStore> {
 3782        match &self.mode {
 3783            LspStoreMode::Remote(remote_lsp_store) => Some(remote_lsp_store),
 3784            _ => None,
 3785        }
 3786    }
 3787
 3788    pub fn as_local(&self) -> Option<&LocalLspStore> {
 3789        match &self.mode {
 3790            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3791            _ => None,
 3792        }
 3793    }
 3794
 3795    pub fn as_local_mut(&mut self) -> Option<&mut LocalLspStore> {
 3796        match &mut self.mode {
 3797            LspStoreMode::Local(local_lsp_store) => Some(local_lsp_store),
 3798            _ => None,
 3799        }
 3800    }
 3801
 3802    pub fn upstream_client(&self) -> Option<(AnyProtoClient, u64)> {
 3803        match &self.mode {
 3804            LspStoreMode::Remote(RemoteLspStore {
 3805                upstream_client: Some(upstream_client),
 3806                upstream_project_id,
 3807                ..
 3808            }) => Some((upstream_client.clone(), *upstream_project_id)),
 3809
 3810            LspStoreMode::Remote(RemoteLspStore {
 3811                upstream_client: None,
 3812                ..
 3813            }) => None,
 3814            LspStoreMode::Local(_) => None,
 3815        }
 3816    }
 3817
 3818    pub fn new_local(
 3819        buffer_store: Entity<BufferStore>,
 3820        worktree_store: Entity<WorktreeStore>,
 3821        prettier_store: Entity<PrettierStore>,
 3822        toolchain_store: Entity<LocalToolchainStore>,
 3823        environment: Entity<ProjectEnvironment>,
 3824        manifest_tree: Entity<ManifestTree>,
 3825        languages: Arc<LanguageRegistry>,
 3826        http_client: Arc<dyn HttpClient>,
 3827        fs: Arc<dyn Fs>,
 3828        cx: &mut Context<Self>,
 3829    ) -> Self {
 3830        let yarn = YarnPathStore::new(fs.clone(), cx);
 3831        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3832            .detach();
 3833        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3834            .detach();
 3835        cx.subscribe(&prettier_store, Self::on_prettier_store_event)
 3836            .detach();
 3837        cx.subscribe(&toolchain_store, Self::on_toolchain_store_event)
 3838            .detach();
 3839        cx.observe_global::<SettingsStore>(Self::on_settings_changed)
 3840            .detach();
 3841        subscribe_to_binary_statuses(&languages, cx).detach();
 3842
 3843        let _maintain_workspace_config = {
 3844            let (sender, receiver) = watch::channel();
 3845            (Self::maintain_workspace_config(receiver, cx), sender)
 3846        };
 3847
 3848        Self {
 3849            mode: LspStoreMode::Local(LocalLspStore {
 3850                weak: cx.weak_entity(),
 3851                worktree_store: worktree_store.clone(),
 3852
 3853                supplementary_language_servers: Default::default(),
 3854                languages: languages.clone(),
 3855                language_server_ids: Default::default(),
 3856                language_servers: Default::default(),
 3857                last_workspace_edits_by_language_server: Default::default(),
 3858                language_server_watched_paths: Default::default(),
 3859                language_server_paths_watched_for_rename: Default::default(),
 3860                language_server_dynamic_registrations: Default::default(),
 3861                buffers_being_formatted: Default::default(),
 3862                buffer_snapshots: Default::default(),
 3863                prettier_store,
 3864                environment,
 3865                http_client,
 3866                fs,
 3867                yarn,
 3868                next_diagnostic_group_id: Default::default(),
 3869                diagnostics: Default::default(),
 3870                _subscription: cx.on_app_quit(|this, cx| {
 3871                    this.as_local_mut()
 3872                        .unwrap()
 3873                        .shutdown_language_servers_on_quit(cx)
 3874                }),
 3875                lsp_tree: LanguageServerTree::new(
 3876                    manifest_tree,
 3877                    languages.clone(),
 3878                    toolchain_store.clone(),
 3879                ),
 3880                toolchain_store,
 3881                registered_buffers: HashMap::default(),
 3882                buffers_opened_in_servers: HashMap::default(),
 3883                buffer_pull_diagnostics_result_ids: HashMap::default(),
 3884                watched_manifest_filenames: ManifestProvidersStore::global(cx)
 3885                    .manifest_file_names(),
 3886            }),
 3887            last_formatting_failure: None,
 3888            downstream_client: None,
 3889            buffer_store,
 3890            worktree_store,
 3891            languages: languages.clone(),
 3892            language_server_statuses: Default::default(),
 3893            nonce: StdRng::from_os_rng().random(),
 3894            diagnostic_summaries: HashMap::default(),
 3895            lsp_server_capabilities: HashMap::default(),
 3896            lsp_data: HashMap::default(),
 3897            next_hint_id: Arc::default(),
 3898            active_entry: None,
 3899            _maintain_workspace_config,
 3900            _maintain_buffer_languages: Self::maintain_buffer_languages(languages, cx),
 3901        }
 3902    }
 3903
 3904    fn send_lsp_proto_request<R: LspCommand>(
 3905        &self,
 3906        buffer: Entity<Buffer>,
 3907        client: AnyProtoClient,
 3908        upstream_project_id: u64,
 3909        request: R,
 3910        cx: &mut Context<LspStore>,
 3911    ) -> Task<anyhow::Result<<R as LspCommand>::Response>> {
 3912        if !self.is_capable_for_proto_request(&buffer, &request, cx) {
 3913            return Task::ready(Ok(R::Response::default()));
 3914        }
 3915        let message = request.to_proto(upstream_project_id, buffer.read(cx));
 3916        cx.spawn(async move |this, cx| {
 3917            let response = client.request(message).await?;
 3918            let this = this.upgrade().context("project dropped")?;
 3919            request
 3920                .response_from_proto(response, this, buffer, cx.clone())
 3921                .await
 3922        })
 3923    }
 3924
 3925    pub(super) fn new_remote(
 3926        buffer_store: Entity<BufferStore>,
 3927        worktree_store: Entity<WorktreeStore>,
 3928        languages: Arc<LanguageRegistry>,
 3929        upstream_client: AnyProtoClient,
 3930        project_id: u64,
 3931        cx: &mut Context<Self>,
 3932    ) -> Self {
 3933        cx.subscribe(&buffer_store, Self::on_buffer_store_event)
 3934            .detach();
 3935        cx.subscribe(&worktree_store, Self::on_worktree_store_event)
 3936            .detach();
 3937        subscribe_to_binary_statuses(&languages, cx).detach();
 3938        let _maintain_workspace_config = {
 3939            let (sender, receiver) = watch::channel();
 3940            (Self::maintain_workspace_config(receiver, cx), sender)
 3941        };
 3942        Self {
 3943            mode: LspStoreMode::Remote(RemoteLspStore {
 3944                upstream_client: Some(upstream_client),
 3945                upstream_project_id: project_id,
 3946            }),
 3947            downstream_client: None,
 3948            last_formatting_failure: None,
 3949            buffer_store,
 3950            worktree_store,
 3951            languages: languages.clone(),
 3952            language_server_statuses: Default::default(),
 3953            nonce: StdRng::from_os_rng().random(),
 3954            diagnostic_summaries: HashMap::default(),
 3955            lsp_server_capabilities: HashMap::default(),
 3956            next_hint_id: Arc::default(),
 3957            lsp_data: HashMap::default(),
 3958            active_entry: None,
 3959
 3960            _maintain_workspace_config,
 3961            _maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
 3962        }
 3963    }
 3964
 3965    fn on_buffer_store_event(
 3966        &mut self,
 3967        _: Entity<BufferStore>,
 3968        event: &BufferStoreEvent,
 3969        cx: &mut Context<Self>,
 3970    ) {
 3971        match event {
 3972            BufferStoreEvent::BufferAdded(buffer) => {
 3973                self.on_buffer_added(buffer, cx).log_err();
 3974            }
 3975            BufferStoreEvent::BufferChangedFilePath { buffer, old_file } => {
 3976                let buffer_id = buffer.read(cx).remote_id();
 3977                if let Some(local) = self.as_local_mut()
 3978                    && let Some(old_file) = File::from_dyn(old_file.as_ref())
 3979                {
 3980                    local.reset_buffer(buffer, old_file, cx);
 3981
 3982                    if local.registered_buffers.contains_key(&buffer_id) {
 3983                        local.unregister_old_buffer_from_language_servers(buffer, old_file, cx);
 3984                    }
 3985                }
 3986
 3987                self.detect_language_for_buffer(buffer, cx);
 3988                if let Some(local) = self.as_local_mut() {
 3989                    local.initialize_buffer(buffer, cx);
 3990                    if local.registered_buffers.contains_key(&buffer_id) {
 3991                        local.register_buffer_with_language_servers(buffer, HashSet::default(), cx);
 3992                    }
 3993                }
 3994            }
 3995            _ => {}
 3996        }
 3997    }
 3998
 3999    fn on_worktree_store_event(
 4000        &mut self,
 4001        _: Entity<WorktreeStore>,
 4002        event: &WorktreeStoreEvent,
 4003        cx: &mut Context<Self>,
 4004    ) {
 4005        match event {
 4006            WorktreeStoreEvent::WorktreeAdded(worktree) => {
 4007                if !worktree.read(cx).is_local() {
 4008                    return;
 4009                }
 4010                cx.subscribe(worktree, |this, worktree, event, cx| match event {
 4011                    worktree::Event::UpdatedEntries(changes) => {
 4012                        this.update_local_worktree_language_servers(&worktree, changes, cx);
 4013                    }
 4014                    worktree::Event::UpdatedGitRepositories(_)
 4015                    | worktree::Event::DeletedEntry(_) => {}
 4016                })
 4017                .detach()
 4018            }
 4019            WorktreeStoreEvent::WorktreeRemoved(_, id) => self.remove_worktree(*id, cx),
 4020            WorktreeStoreEvent::WorktreeUpdateSent(worktree) => {
 4021                worktree.update(cx, |worktree, _cx| self.send_diagnostic_summaries(worktree));
 4022            }
 4023            WorktreeStoreEvent::WorktreeReleased(..)
 4024            | WorktreeStoreEvent::WorktreeOrderChanged
 4025            | WorktreeStoreEvent::WorktreeUpdatedEntries(..)
 4026            | WorktreeStoreEvent::WorktreeUpdatedGitRepositories(..)
 4027            | WorktreeStoreEvent::WorktreeDeletedEntry(..) => {}
 4028        }
 4029    }
 4030
 4031    fn on_prettier_store_event(
 4032        &mut self,
 4033        _: Entity<PrettierStore>,
 4034        event: &PrettierStoreEvent,
 4035        cx: &mut Context<Self>,
 4036    ) {
 4037        match event {
 4038            PrettierStoreEvent::LanguageServerRemoved(prettier_server_id) => {
 4039                self.unregister_supplementary_language_server(*prettier_server_id, cx);
 4040            }
 4041            PrettierStoreEvent::LanguageServerAdded {
 4042                new_server_id,
 4043                name,
 4044                prettier_server,
 4045            } => {
 4046                self.register_supplementary_language_server(
 4047                    *new_server_id,
 4048                    name.clone(),
 4049                    prettier_server.clone(),
 4050                    cx,
 4051                );
 4052            }
 4053        }
 4054    }
 4055
 4056    fn on_toolchain_store_event(
 4057        &mut self,
 4058        _: Entity<LocalToolchainStore>,
 4059        event: &ToolchainStoreEvent,
 4060        _: &mut Context<Self>,
 4061    ) {
 4062        if let ToolchainStoreEvent::ToolchainActivated = event {
 4063            self.request_workspace_config_refresh()
 4064        }
 4065    }
 4066
 4067    fn request_workspace_config_refresh(&mut self) {
 4068        *self._maintain_workspace_config.1.borrow_mut() = ();
 4069    }
 4070
 4071    pub fn prettier_store(&self) -> Option<Entity<PrettierStore>> {
 4072        self.as_local().map(|local| local.prettier_store.clone())
 4073    }
 4074
 4075    fn on_buffer_event(
 4076        &mut self,
 4077        buffer: Entity<Buffer>,
 4078        event: &language::BufferEvent,
 4079        cx: &mut Context<Self>,
 4080    ) {
 4081        match event {
 4082            language::BufferEvent::Edited => {
 4083                self.on_buffer_edited(buffer, cx);
 4084            }
 4085
 4086            language::BufferEvent::Saved => {
 4087                self.on_buffer_saved(buffer, cx);
 4088            }
 4089
 4090            _ => {}
 4091        }
 4092    }
 4093
 4094    fn on_buffer_added(&mut self, buffer: &Entity<Buffer>, cx: &mut Context<Self>) -> Result<()> {
 4095        buffer
 4096            .read(cx)
 4097            .set_language_registry(self.languages.clone());
 4098
 4099        cx.subscribe(buffer, |this, buffer, event, cx| {
 4100            this.on_buffer_event(buffer, event, cx);
 4101        })
 4102        .detach();
 4103
 4104        self.detect_language_for_buffer(buffer, cx);
 4105        if let Some(local) = self.as_local_mut() {
 4106            local.initialize_buffer(buffer, cx);
 4107        }
 4108
 4109        Ok(())
 4110    }
 4111
 4112    pub(crate) fn register_buffer_with_language_servers(
 4113        &mut self,
 4114        buffer: &Entity<Buffer>,
 4115        only_register_servers: HashSet<LanguageServerSelector>,
 4116        ignore_refcounts: bool,
 4117        cx: &mut Context<Self>,
 4118    ) -> OpenLspBufferHandle {
 4119        let buffer_id = buffer.read(cx).remote_id();
 4120        let handle = cx.new(|_| buffer.clone());
 4121        if let Some(local) = self.as_local_mut() {
 4122            let refcount = local.registered_buffers.entry(buffer_id).or_insert(0);
 4123            if !ignore_refcounts {
 4124                *refcount += 1;
 4125            }
 4126
 4127            // We run early exits on non-existing buffers AFTER we mark the buffer as registered in order to handle buffer saving.
 4128            // 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
 4129            // 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
 4130            // servers in practice (we don't support non-file URI schemes in our LSP impl).
 4131            let Some(file) = File::from_dyn(buffer.read(cx).file()) else {
 4132                return handle;
 4133            };
 4134            if !file.is_local() {
 4135                return handle;
 4136            }
 4137
 4138            if ignore_refcounts || *refcount == 1 {
 4139                local.register_buffer_with_language_servers(buffer, only_register_servers, cx);
 4140            }
 4141            if !ignore_refcounts {
 4142                cx.observe_release(&handle, move |lsp_store, buffer, cx| {
 4143                    let refcount = {
 4144                        let local = lsp_store.as_local_mut().unwrap();
 4145                        let Some(refcount) = local.registered_buffers.get_mut(&buffer_id) else {
 4146                            debug_panic!("bad refcounting");
 4147                            return;
 4148                        };
 4149
 4150                        *refcount -= 1;
 4151                        *refcount
 4152                    };
 4153                    if refcount == 0 {
 4154                        lsp_store.lsp_data.remove(&buffer_id);
 4155                        let local = lsp_store.as_local_mut().unwrap();
 4156                        local.registered_buffers.remove(&buffer_id);
 4157                        local.buffers_opened_in_servers.remove(&buffer_id);
 4158                        if let Some(file) = File::from_dyn(buffer.read(cx).file()).cloned() {
 4159                            local.unregister_old_buffer_from_language_servers(buffer, &file, cx);
 4160                        }
 4161                    }
 4162                })
 4163                .detach();
 4164            }
 4165        } else if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4166            let buffer_id = buffer.read(cx).remote_id().to_proto();
 4167            cx.background_spawn(async move {
 4168                upstream_client
 4169                    .request(proto::RegisterBufferWithLanguageServers {
 4170                        project_id: upstream_project_id,
 4171                        buffer_id,
 4172                        only_servers: only_register_servers
 4173                            .into_iter()
 4174                            .map(|selector| {
 4175                                let selector = match selector {
 4176                                    LanguageServerSelector::Id(language_server_id) => {
 4177                                        proto::language_server_selector::Selector::ServerId(
 4178                                            language_server_id.to_proto(),
 4179                                        )
 4180                                    }
 4181                                    LanguageServerSelector::Name(language_server_name) => {
 4182                                        proto::language_server_selector::Selector::Name(
 4183                                            language_server_name.to_string(),
 4184                                        )
 4185                                    }
 4186                                };
 4187                                proto::LanguageServerSelector {
 4188                                    selector: Some(selector),
 4189                                }
 4190                            })
 4191                            .collect(),
 4192                    })
 4193                    .await
 4194            })
 4195            .detach();
 4196        } else {
 4197            // Our remote connection got closed
 4198        }
 4199        handle
 4200    }
 4201
 4202    fn maintain_buffer_languages(
 4203        languages: Arc<LanguageRegistry>,
 4204        cx: &mut Context<Self>,
 4205    ) -> Task<()> {
 4206        let mut subscription = languages.subscribe();
 4207        let mut prev_reload_count = languages.reload_count();
 4208        cx.spawn(async move |this, cx| {
 4209            while let Some(()) = subscription.next().await {
 4210                if let Some(this) = this.upgrade() {
 4211                    // If the language registry has been reloaded, then remove and
 4212                    // re-assign the languages on all open buffers.
 4213                    let reload_count = languages.reload_count();
 4214                    if reload_count > prev_reload_count {
 4215                        prev_reload_count = reload_count;
 4216                        this.update(cx, |this, cx| {
 4217                            this.buffer_store.clone().update(cx, |buffer_store, cx| {
 4218                                for buffer in buffer_store.buffers() {
 4219                                    if let Some(f) = File::from_dyn(buffer.read(cx).file()).cloned()
 4220                                    {
 4221                                        buffer
 4222                                            .update(cx, |buffer, cx| buffer.set_language(None, cx));
 4223                                        if let Some(local) = this.as_local_mut() {
 4224                                            local.reset_buffer(&buffer, &f, cx);
 4225
 4226                                            if local
 4227                                                .registered_buffers
 4228                                                .contains_key(&buffer.read(cx).remote_id())
 4229                                                && let Some(file_url) =
 4230                                                    file_path_to_lsp_url(&f.abs_path(cx)).log_err()
 4231                                            {
 4232                                                local.unregister_buffer_from_language_servers(
 4233                                                    &buffer, &file_url, cx,
 4234                                                );
 4235                                            }
 4236                                        }
 4237                                    }
 4238                                }
 4239                            });
 4240                        })
 4241                        .ok();
 4242                    }
 4243
 4244                    this.update(cx, |this, cx| {
 4245                        let mut plain_text_buffers = Vec::new();
 4246                        let mut buffers_with_unknown_injections = Vec::new();
 4247                        for handle in this.buffer_store.read(cx).buffers() {
 4248                            let buffer = handle.read(cx);
 4249                            if buffer.language().is_none()
 4250                                || buffer.language() == Some(&*language::PLAIN_TEXT)
 4251                            {
 4252                                plain_text_buffers.push(handle);
 4253                            } else if buffer.contains_unknown_injections() {
 4254                                buffers_with_unknown_injections.push(handle);
 4255                            }
 4256                        }
 4257
 4258                        // Deprioritize the invisible worktrees so main worktrees' language servers can be started first,
 4259                        // and reused later in the invisible worktrees.
 4260                        plain_text_buffers.sort_by_key(|buffer| {
 4261                            Reverse(
 4262                                File::from_dyn(buffer.read(cx).file())
 4263                                    .map(|file| file.worktree.read(cx).is_visible()),
 4264                            )
 4265                        });
 4266
 4267                        for buffer in plain_text_buffers {
 4268                            this.detect_language_for_buffer(&buffer, cx);
 4269                            if let Some(local) = this.as_local_mut() {
 4270                                local.initialize_buffer(&buffer, cx);
 4271                                if local
 4272                                    .registered_buffers
 4273                                    .contains_key(&buffer.read(cx).remote_id())
 4274                                {
 4275                                    local.register_buffer_with_language_servers(
 4276                                        &buffer,
 4277                                        HashSet::default(),
 4278                                        cx,
 4279                                    );
 4280                                }
 4281                            }
 4282                        }
 4283
 4284                        for buffer in buffers_with_unknown_injections {
 4285                            buffer.update(cx, |buffer, cx| buffer.reparse(cx));
 4286                        }
 4287                    })
 4288                    .ok();
 4289                }
 4290            }
 4291        })
 4292    }
 4293
 4294    fn detect_language_for_buffer(
 4295        &mut self,
 4296        buffer_handle: &Entity<Buffer>,
 4297        cx: &mut Context<Self>,
 4298    ) -> Option<language::AvailableLanguage> {
 4299        // If the buffer has a language, set it and start the language server if we haven't already.
 4300        let buffer = buffer_handle.read(cx);
 4301        let file = buffer.file()?;
 4302
 4303        let content = buffer.as_rope();
 4304        let available_language = self.languages.language_for_file(file, Some(content), cx);
 4305        if let Some(available_language) = &available_language {
 4306            if let Some(Ok(Ok(new_language))) = self
 4307                .languages
 4308                .load_language(available_language)
 4309                .now_or_never()
 4310            {
 4311                self.set_language_for_buffer(buffer_handle, new_language, cx);
 4312            }
 4313        } else {
 4314            cx.emit(LspStoreEvent::LanguageDetected {
 4315                buffer: buffer_handle.clone(),
 4316                new_language: None,
 4317            });
 4318        }
 4319
 4320        available_language
 4321    }
 4322
 4323    pub(crate) fn set_language_for_buffer(
 4324        &mut self,
 4325        buffer_entity: &Entity<Buffer>,
 4326        new_language: Arc<Language>,
 4327        cx: &mut Context<Self>,
 4328    ) {
 4329        let buffer = buffer_entity.read(cx);
 4330        let buffer_file = buffer.file().cloned();
 4331        let buffer_id = buffer.remote_id();
 4332        if let Some(local_store) = self.as_local_mut()
 4333            && local_store.registered_buffers.contains_key(&buffer_id)
 4334            && let Some(abs_path) =
 4335                File::from_dyn(buffer_file.as_ref()).map(|file| file.abs_path(cx))
 4336            && let Some(file_url) = file_path_to_lsp_url(&abs_path).log_err()
 4337        {
 4338            local_store.unregister_buffer_from_language_servers(buffer_entity, &file_url, cx);
 4339        }
 4340        buffer_entity.update(cx, |buffer, cx| {
 4341            if buffer
 4342                .language()
 4343                .is_none_or(|old_language| !Arc::ptr_eq(old_language, &new_language))
 4344            {
 4345                buffer.set_language(Some(new_language.clone()), cx);
 4346            }
 4347        });
 4348
 4349        let settings =
 4350            language_settings(Some(new_language.name()), buffer_file.as_ref(), cx).into_owned();
 4351        let buffer_file = File::from_dyn(buffer_file.as_ref());
 4352
 4353        let worktree_id = if let Some(file) = buffer_file {
 4354            let worktree = file.worktree.clone();
 4355
 4356            if let Some(local) = self.as_local_mut()
 4357                && local.registered_buffers.contains_key(&buffer_id)
 4358            {
 4359                local.register_buffer_with_language_servers(buffer_entity, HashSet::default(), cx);
 4360            }
 4361            Some(worktree.read(cx).id())
 4362        } else {
 4363            None
 4364        };
 4365
 4366        if settings.prettier.allowed
 4367            && let Some(prettier_plugins) = prettier_store::prettier_plugins_for_language(&settings)
 4368        {
 4369            let prettier_store = self.as_local().map(|s| s.prettier_store.clone());
 4370            if let Some(prettier_store) = prettier_store {
 4371                prettier_store.update(cx, |prettier_store, cx| {
 4372                    prettier_store.install_default_prettier(
 4373                        worktree_id,
 4374                        prettier_plugins.iter().map(|s| Arc::from(s.as_str())),
 4375                        cx,
 4376                    )
 4377                })
 4378            }
 4379        }
 4380
 4381        cx.emit(LspStoreEvent::LanguageDetected {
 4382            buffer: buffer_entity.clone(),
 4383            new_language: Some(new_language),
 4384        })
 4385    }
 4386
 4387    pub fn buffer_store(&self) -> Entity<BufferStore> {
 4388        self.buffer_store.clone()
 4389    }
 4390
 4391    pub fn set_active_entry(&mut self, active_entry: Option<ProjectEntryId>) {
 4392        self.active_entry = active_entry;
 4393    }
 4394
 4395    pub(crate) fn send_diagnostic_summaries(&self, worktree: &mut Worktree) {
 4396        if let Some((client, downstream_project_id)) = self.downstream_client.clone()
 4397            && let Some(diangostic_summaries) = self.diagnostic_summaries.get(&worktree.id())
 4398        {
 4399            let mut summaries = diangostic_summaries.iter().flat_map(|(path, summaries)| {
 4400                summaries
 4401                    .iter()
 4402                    .map(|(server_id, summary)| summary.to_proto(*server_id, path.as_ref()))
 4403            });
 4404            if let Some(summary) = summaries.next() {
 4405                client
 4406                    .send(proto::UpdateDiagnosticSummary {
 4407                        project_id: downstream_project_id,
 4408                        worktree_id: worktree.id().to_proto(),
 4409                        summary: Some(summary),
 4410                        more_summaries: summaries.collect(),
 4411                    })
 4412                    .log_err();
 4413            }
 4414        }
 4415    }
 4416
 4417    fn is_capable_for_proto_request<R>(
 4418        &self,
 4419        buffer: &Entity<Buffer>,
 4420        request: &R,
 4421        cx: &App,
 4422    ) -> bool
 4423    where
 4424        R: LspCommand,
 4425    {
 4426        self.check_if_capable_for_proto_request(
 4427            buffer,
 4428            |capabilities| {
 4429                request.check_capabilities(AdapterServerCapabilities {
 4430                    server_capabilities: capabilities.clone(),
 4431                    code_action_kinds: None,
 4432                })
 4433            },
 4434            cx,
 4435        )
 4436    }
 4437
 4438    fn check_if_capable_for_proto_request<F>(
 4439        &self,
 4440        buffer: &Entity<Buffer>,
 4441        check: F,
 4442        cx: &App,
 4443    ) -> bool
 4444    where
 4445        F: FnMut(&lsp::ServerCapabilities) -> bool,
 4446    {
 4447        let Some(language) = buffer.read(cx).language().cloned() else {
 4448            return false;
 4449        };
 4450        let relevant_language_servers = self
 4451            .languages
 4452            .lsp_adapters(&language.name())
 4453            .into_iter()
 4454            .map(|lsp_adapter| lsp_adapter.name())
 4455            .collect::<HashSet<_>>();
 4456        self.language_server_statuses
 4457            .iter()
 4458            .filter_map(|(server_id, server_status)| {
 4459                relevant_language_servers
 4460                    .contains(&server_status.name)
 4461                    .then_some(server_id)
 4462            })
 4463            .filter_map(|server_id| self.lsp_server_capabilities.get(server_id))
 4464            .any(check)
 4465    }
 4466
 4467    pub fn request_lsp<R>(
 4468        &mut self,
 4469        buffer: Entity<Buffer>,
 4470        server: LanguageServerToQuery,
 4471        request: R,
 4472        cx: &mut Context<Self>,
 4473    ) -> Task<Result<R::Response>>
 4474    where
 4475        R: LspCommand,
 4476        <R::LspRequest as lsp::request::Request>::Result: Send,
 4477        <R::LspRequest as lsp::request::Request>::Params: Send,
 4478    {
 4479        if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
 4480            return self.send_lsp_proto_request(
 4481                buffer,
 4482                upstream_client,
 4483                upstream_project_id,
 4484                request,
 4485                cx,
 4486            );
 4487        }
 4488
 4489        let Some(language_server) = buffer.update(cx, |buffer, cx| match server {
 4490            LanguageServerToQuery::FirstCapable => self.as_local().and_then(|local| {
 4491                local
 4492                    .language_servers_for_buffer(buffer, cx)
 4493                    .find(|(_, server)| {
 4494                        request.check_capabilities(server.adapter_server_capabilities())
 4495                    })
 4496                    .map(|(_, server)| server.clone())
 4497            }),
 4498            LanguageServerToQuery::Other(id) => self
 4499                .language_server_for_local_buffer(buffer, id, cx)
 4500                .and_then(|(_, server)| {
 4501                    request
 4502                        .check_capabilities(server.adapter_server_capabilities())
 4503                        .then(|| Arc::clone(server))
 4504                }),
 4505        }) else {
 4506            return Task::ready(Ok(Default::default()));
 4507        };
 4508
 4509        let file = File::from_dyn(buffer.read(cx).file()).and_then(File::as_local);
 4510
 4511        let Some(file) = file else {
 4512            return Task::ready(Ok(Default::default()));
 4513        };
 4514
 4515        let lsp_params = match request.to_lsp_params_or_response(
 4516            &file.abs_path(cx),
 4517            buffer.read(cx),
 4518            &language_server,
 4519            cx,
 4520        ) {
 4521            Ok(LspParamsOrResponse::Params(lsp_params)) => lsp_params,
 4522            Ok(LspParamsOrResponse::Response(response)) => return Task::ready(Ok(response)),
 4523            Err(err) => {
 4524                let message = format!(
 4525                    "{} via {} failed: {}",
 4526                    request.display_name(),
 4527                    language_server.name(),
 4528                    err
 4529                );
 4530                // rust-analyzer likes to error with this when its still loading up
 4531                if !message.ends_with("content modified") {
 4532                    log::warn!("{message}");
 4533                }
 4534                return Task::ready(Err(anyhow!(message)));
 4535            }
 4536        };
 4537
 4538        let status = request.status();
 4539        if !request.check_capabilities(language_server.adapter_server_capabilities()) {
 4540            return Task::ready(Ok(Default::default()));
 4541        }
 4542        cx.spawn(async move |this, cx| {
 4543            let lsp_request = language_server.request::<R::LspRequest>(lsp_params);
 4544
 4545            let id = lsp_request.id();
 4546            let _cleanup = if status.is_some() {
 4547                cx.update(|cx| {
 4548                    this.update(cx, |this, cx| {
 4549                        this.on_lsp_work_start(
 4550                            language_server.server_id(),
 4551                            ProgressToken::Number(id),
 4552                            LanguageServerProgress {
 4553                                is_disk_based_diagnostics_progress: false,
 4554                                is_cancellable: false,
 4555                                title: None,
 4556                                message: status.clone(),
 4557                                percentage: None,
 4558                                last_update_at: cx.background_executor().now(),
 4559                            },
 4560                            cx,
 4561                        );
 4562                    })
 4563                })
 4564                .log_err();
 4565
 4566                Some(defer(|| {
 4567                    cx.update(|cx| {
 4568                        this.update(cx, |this, cx| {
 4569                            this.on_lsp_work_end(
 4570                                language_server.server_id(),
 4571                                ProgressToken::Number(id),
 4572                                cx,
 4573                            );
 4574                        })
 4575                    })
 4576                    .log_err();
 4577                }))
 4578            } else {
 4579                None
 4580            };
 4581
 4582            let result = lsp_request.await.into_response();
 4583
 4584            let response = result.map_err(|err| {
 4585                let message = format!(
 4586                    "{} via {} failed: {}",
 4587                    request.display_name(),
 4588                    language_server.name(),
 4589                    err
 4590                );
 4591                // rust-analyzer likes to error with this when its still loading up
 4592                if !message.ends_with("content modified") {
 4593                    log::warn!("{message}");
 4594                }
 4595                anyhow::anyhow!(message)
 4596            })?;
 4597
 4598            request
 4599                .response_from_lsp(
 4600                    response,
 4601                    this.upgrade().context("no app context")?,
 4602                    buffer,
 4603                    language_server.server_id(),
 4604                    cx.clone(),
 4605                )
 4606                .await
 4607        })
 4608    }
 4609
 4610    fn on_settings_changed(&mut self, cx: &mut Context<Self>) {
 4611        let mut language_formatters_to_check = Vec::new();
 4612        for buffer in self.buffer_store.read(cx).buffers() {
 4613            let buffer = buffer.read(cx);
 4614            let buffer_file = File::from_dyn(buffer.file());
 4615            let buffer_language = buffer.language();
 4616            let settings = language_settings(buffer_language.map(|l| l.name()), buffer.file(), cx);
 4617            if buffer_language.is_some() {
 4618                language_formatters_to_check.push((
 4619                    buffer_file.map(|f| f.worktree_id(cx)),
 4620                    settings.into_owned(),
 4621                ));
 4622            }
 4623        }
 4624
 4625        self.request_workspace_config_refresh();
 4626
 4627        if let Some(prettier_store) = self.as_local().map(|s| s.prettier_store.clone()) {
 4628            prettier_store.update(cx, |prettier_store, cx| {
 4629                prettier_store.on_settings_changed(language_formatters_to_check, cx)
 4630            })
 4631        }
 4632
 4633        cx.notify();
 4634    }
 4635
 4636    fn refresh_server_tree(&mut self, cx: &mut Context<Self>) {
 4637        let buffer_store = self.buffer_store.clone();
 4638        let Some(local) = self.as_local_mut() else {
 4639            return;
 4640        };
 4641        let mut adapters = BTreeMap::default();
 4642        let get_adapter = {
 4643            let languages = local.languages.clone();
 4644            let environment = local.environment.clone();
 4645            let weak = local.weak.clone();
 4646            let worktree_store = local.worktree_store.clone();
 4647            let http_client = local.http_client.clone();
 4648            let fs = local.fs.clone();
 4649            move |worktree_id, cx: &mut App| {
 4650                let worktree = worktree_store.read(cx).worktree_for_id(worktree_id, cx)?;
 4651                Some(LocalLspAdapterDelegate::new(
 4652                    languages.clone(),
 4653                    &environment,
 4654                    weak.clone(),
 4655                    &worktree,
 4656                    http_client.clone(),
 4657                    fs.clone(),
 4658                    cx,
 4659                ))
 4660            }
 4661        };
 4662
 4663        let mut messages_to_report = Vec::new();
 4664        let (new_tree, to_stop) = {
 4665            let mut rebase = local.lsp_tree.rebase();
 4666            let buffers = buffer_store
 4667                .read(cx)
 4668                .buffers()
 4669                .filter_map(|buffer| {
 4670                    let raw_buffer = buffer.read(cx);
 4671                    if !local
 4672                        .registered_buffers
 4673                        .contains_key(&raw_buffer.remote_id())
 4674                    {
 4675                        return None;
 4676                    }
 4677                    let file = File::from_dyn(raw_buffer.file()).cloned()?;
 4678                    let language = raw_buffer.language().cloned()?;
 4679                    Some((file, language, raw_buffer.remote_id()))
 4680                })
 4681                .sorted_by_key(|(file, _, _)| Reverse(file.worktree.read(cx).is_visible()));
 4682            for (file, language, buffer_id) in buffers {
 4683                let worktree_id = file.worktree_id(cx);
 4684                let Some(worktree) = local
 4685                    .worktree_store
 4686                    .read(cx)
 4687                    .worktree_for_id(worktree_id, cx)
 4688                else {
 4689                    continue;
 4690                };
 4691
 4692                if let Some((_, apply)) = local.reuse_existing_language_server(
 4693                    rebase.server_tree(),
 4694                    &worktree,
 4695                    &language.name(),
 4696                    cx,
 4697                ) {
 4698                    (apply)(rebase.server_tree());
 4699                } else if let Some(lsp_delegate) = adapters
 4700                    .entry(worktree_id)
 4701                    .or_insert_with(|| get_adapter(worktree_id, cx))
 4702                    .clone()
 4703                {
 4704                    let delegate =
 4705                        Arc::new(ManifestQueryDelegate::new(worktree.read(cx).snapshot()));
 4706                    let path = file
 4707                        .path()
 4708                        .parent()
 4709                        .map(Arc::from)
 4710                        .unwrap_or_else(|| file.path().clone());
 4711                    let worktree_path = ProjectPath { worktree_id, path };
 4712                    let abs_path = file.abs_path(cx);
 4713                    let nodes = rebase
 4714                        .walk(
 4715                            worktree_path,
 4716                            language.name(),
 4717                            language.manifest(),
 4718                            delegate.clone(),
 4719                            cx,
 4720                        )
 4721                        .collect::<Vec<_>>();
 4722                    for node in nodes {
 4723                        let server_id = node.server_id_or_init(|disposition| {
 4724                            let path = &disposition.path;
 4725                            let uri = Uri::from_file_path(worktree.read(cx).absolutize(&path.path));
 4726                            let key = LanguageServerSeed {
 4727                                worktree_id,
 4728                                name: disposition.server_name.clone(),
 4729                                settings: disposition.settings.clone(),
 4730                                toolchain: local.toolchain_store.read(cx).active_toolchain(
 4731                                    path.worktree_id,
 4732                                    &path.path,
 4733                                    language.name(),
 4734                                ),
 4735                            };
 4736                            local.language_server_ids.remove(&key);
 4737
 4738                            let server_id = local.get_or_insert_language_server(
 4739                                &worktree,
 4740                                lsp_delegate.clone(),
 4741                                disposition,
 4742                                &language.name(),
 4743                                cx,
 4744                            );
 4745                            if let Some(state) = local.language_servers.get(&server_id)
 4746                                && let Ok(uri) = uri
 4747                            {
 4748                                state.add_workspace_folder(uri);
 4749                            };
 4750                            server_id
 4751                        });
 4752
 4753                        if let Some(language_server_id) = server_id {
 4754                            messages_to_report.push(LspStoreEvent::LanguageServerUpdate {
 4755                                language_server_id,
 4756                                name: node.name(),
 4757                                message:
 4758                                    proto::update_language_server::Variant::RegisteredForBuffer(
 4759                                        proto::RegisteredForBuffer {
 4760                                            buffer_abs_path: abs_path
 4761                                                .to_string_lossy()
 4762                                                .into_owned(),
 4763                                            buffer_id: buffer_id.to_proto(),
 4764                                        },
 4765                                    ),
 4766                            });
 4767                        }
 4768                    }
 4769                } else {
 4770                    continue;
 4771                }
 4772            }
 4773            rebase.finish()
 4774        };
 4775        for message in messages_to_report {
 4776            cx.emit(message);
 4777        }
 4778        local.lsp_tree = new_tree;
 4779        for (id, _) in to_stop {
 4780            self.stop_local_language_server(id, cx).detach();
 4781        }
 4782    }
 4783
 4784    pub fn apply_code_action(
 4785        &self,
 4786        buffer_handle: Entity<Buffer>,
 4787        mut action: CodeAction,
 4788        push_to_history: bool,
 4789        cx: &mut Context<Self>,
 4790    ) -> Task<Result<ProjectTransaction>> {
 4791        if let Some((upstream_client, project_id)) = self.upstream_client() {
 4792            let request = proto::ApplyCodeAction {
 4793                project_id,
 4794                buffer_id: buffer_handle.read(cx).remote_id().into(),
 4795                action: Some(Self::serialize_code_action(&action)),
 4796            };
 4797            let buffer_store = self.buffer_store();
 4798            cx.spawn(async move |_, cx| {
 4799                let response = upstream_client
 4800                    .request(request)
 4801                    .await?
 4802                    .transaction
 4803                    .context("missing transaction")?;
 4804
 4805                buffer_store
 4806                    .update(cx, |buffer_store, cx| {
 4807                        buffer_store.deserialize_project_transaction(response, push_to_history, cx)
 4808                    })?
 4809                    .await
 4810            })
 4811        } else if self.mode.is_local() {
 4812            let Some((_, lang_server)) = buffer_handle.update(cx, |buffer, cx| {
 4813                self.language_server_for_local_buffer(buffer, action.server_id, cx)
 4814                    .map(|(adapter, server)| (adapter.clone(), server.clone()))
 4815            }) else {
 4816                return Task::ready(Ok(ProjectTransaction::default()));
 4817            };
 4818            cx.spawn(async move |this,  cx| {
 4819                LocalLspStore::try_resolve_code_action(&lang_server, &mut action)
 4820                    .await
 4821                    .context("resolving a code action")?;
 4822                if let Some(edit) = action.lsp_action.edit()
 4823                    && (edit.changes.is_some() || edit.document_changes.is_some()) {
 4824                        return LocalLspStore::deserialize_workspace_edit(
 4825                            this.upgrade().context("no app present")?,
 4826                            edit.clone(),
 4827                            push_to_history,
 4828
 4829                            lang_server.clone(),
 4830                            cx,
 4831                        )
 4832                        .await;
 4833                    }
 4834
 4835                if let Some(command) = action.lsp_action.command() {
 4836                    let server_capabilities = lang_server.capabilities();
 4837                    let available_commands = server_capabilities
 4838                        .execute_command_provider
 4839                        .as_ref()
 4840                        .map(|options| options.commands.as_slice())
 4841                        .unwrap_or_default();
 4842                    if available_commands.contains(&command.command) {
 4843                        this.update(cx, |this, _| {
 4844                            this.as_local_mut()
 4845                                .unwrap()
 4846                                .last_workspace_edits_by_language_server
 4847                                .remove(&lang_server.server_id());
 4848                        })?;
 4849
 4850                        let _result = lang_server
 4851                            .request::<lsp::request::ExecuteCommand>(lsp::ExecuteCommandParams {
 4852                                command: command.command.clone(),
 4853                                arguments: command.arguments.clone().unwrap_or_default(),
 4854                                ..lsp::ExecuteCommandParams::default()
 4855                            })
 4856                            .await.into_response()
 4857                            .context("execute command")?;
 4858
 4859                        return this.update(cx, |this, _| {
 4860                            this.as_local_mut()
 4861                                .unwrap()
 4862                                .last_workspace_edits_by_language_server
 4863                                .remove(&lang_server.server_id())
 4864                                .unwrap_or_default()
 4865                        });
 4866                    } else {
 4867                        log::warn!("Cannot execute a command {} not listed in the language server capabilities", command.command);
 4868                    }
 4869                }
 4870
 4871                Ok(ProjectTransaction::default())
 4872            })
 4873        } else {
 4874            Task::ready(Err(anyhow!("no upstream client and not local")))
 4875        }
 4876    }
 4877
 4878    pub fn apply_code_action_kind(
 4879        &mut self,
 4880        buffers: HashSet<Entity<Buffer>>,
 4881        kind: CodeActionKind,
 4882        push_to_history: bool,
 4883        cx: &mut Context<Self>,
 4884    ) -> Task<anyhow::Result<ProjectTransaction>> {
 4885        if self.as_local().is_some() {
 4886            cx.spawn(async move |lsp_store, cx| {
 4887                let buffers = buffers.into_iter().collect::<Vec<_>>();
 4888                let result = LocalLspStore::execute_code_action_kind_locally(
 4889                    lsp_store.clone(),
 4890                    buffers,
 4891                    kind,
 4892                    push_to_history,
 4893                    cx,
 4894                )
 4895                .await;
 4896                lsp_store.update(cx, |lsp_store, _| {
 4897                    lsp_store.update_last_formatting_failure(&result);
 4898                })?;
 4899                result
 4900            })
 4901        } else if let Some((client, project_id)) = self.upstream_client() {
 4902            let buffer_store = self.buffer_store();
 4903            cx.spawn(async move |lsp_store, cx| {
 4904                let result = client
 4905                    .request(proto::ApplyCodeActionKind {
 4906                        project_id,
 4907                        kind: kind.as_str().to_owned(),
 4908                        buffer_ids: buffers
 4909                            .iter()
 4910                            .map(|buffer| {
 4911                                buffer.read_with(cx, |buffer, _| buffer.remote_id().into())
 4912                            })
 4913                            .collect::<Result<_>>()?,
 4914                    })
 4915                    .await
 4916                    .and_then(|result| result.transaction.context("missing transaction"));
 4917                lsp_store.update(cx, |lsp_store, _| {
 4918                    lsp_store.update_last_formatting_failure(&result);
 4919                })?;
 4920
 4921                let transaction_response = result?;
 4922                buffer_store
 4923                    .update(cx, |buffer_store, cx| {
 4924                        buffer_store.deserialize_project_transaction(
 4925                            transaction_response,
 4926                            push_to_history,
 4927                            cx,
 4928                        )
 4929                    })?
 4930                    .await
 4931            })
 4932        } else {
 4933            Task::ready(Ok(ProjectTransaction::default()))
 4934        }
 4935    }
 4936
 4937    pub fn resolved_hint(
 4938        &mut self,
 4939        buffer_id: BufferId,
 4940        id: InlayId,
 4941        cx: &mut Context<Self>,
 4942    ) -> Option<ResolvedHint> {
 4943        let buffer = self.buffer_store.read(cx).get(buffer_id)?;
 4944
 4945        let lsp_data = self.lsp_data.get_mut(&buffer_id)?;
 4946        let buffer_lsp_hints = &mut lsp_data.inlay_hints;
 4947        let hint = buffer_lsp_hints.hint_for_id(id)?.clone();
 4948        let (server_id, resolve_data) = match &hint.resolve_state {
 4949            ResolveState::Resolved => return Some(ResolvedHint::Resolved(hint)),
 4950            ResolveState::Resolving => {
 4951                return Some(ResolvedHint::Resolving(
 4952                    buffer_lsp_hints.hint_resolves.get(&id)?.clone(),
 4953                ));
 4954            }
 4955            ResolveState::CanResolve(server_id, resolve_data) => (*server_id, resolve_data.clone()),
 4956        };
 4957
 4958        let resolve_task = self.resolve_inlay_hint(hint, buffer, server_id, cx);
 4959        let buffer_lsp_hints = &mut self.lsp_data.get_mut(&buffer_id)?.inlay_hints;
 4960        let previous_task = buffer_lsp_hints.hint_resolves.insert(
 4961            id,
 4962            cx.spawn(async move |lsp_store, cx| {
 4963                let resolved_hint = resolve_task.await;
 4964                lsp_store
 4965                    .update(cx, |lsp_store, _| {
 4966                        if let Some(old_inlay_hint) = lsp_store
 4967                            .lsp_data
 4968                            .get_mut(&buffer_id)
 4969                            .and_then(|buffer_lsp_data| buffer_lsp_data.inlay_hints.hint_for_id(id))
 4970                        {
 4971                            match resolved_hint {
 4972                                Ok(resolved_hint) => {
 4973                                    *old_inlay_hint = resolved_hint;
 4974                                }
 4975                                Err(e) => {
 4976                                    old_inlay_hint.resolve_state =
 4977                                        ResolveState::CanResolve(server_id, resolve_data);
 4978                                    log::error!("Inlay hint resolve failed: {e:#}");
 4979                                }
 4980                            }
 4981                        }
 4982                    })
 4983                    .ok();
 4984            })
 4985            .shared(),
 4986        );
 4987        debug_assert!(
 4988            previous_task.is_none(),
 4989            "Did not change hint's resolve state after spawning its resolve"
 4990        );
 4991        buffer_lsp_hints.hint_for_id(id)?.resolve_state = ResolveState::Resolving;
 4992        None
 4993    }
 4994
 4995    fn resolve_inlay_hint(
 4996        &self,
 4997        mut hint: InlayHint,
 4998        buffer: Entity<Buffer>,
 4999        server_id: LanguageServerId,
 5000        cx: &mut Context<Self>,
 5001    ) -> Task<anyhow::Result<InlayHint>> {
 5002        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5003            if !self.check_if_capable_for_proto_request(&buffer, InlayHints::can_resolve_inlays, cx)
 5004            {
 5005                hint.resolve_state = ResolveState::Resolved;
 5006                return Task::ready(Ok(hint));
 5007            }
 5008            let request = proto::ResolveInlayHint {
 5009                project_id,
 5010                buffer_id: buffer.read(cx).remote_id().into(),
 5011                language_server_id: server_id.0 as u64,
 5012                hint: Some(InlayHints::project_to_proto_hint(hint.clone())),
 5013            };
 5014            cx.background_spawn(async move {
 5015                let response = upstream_client
 5016                    .request(request)
 5017                    .await
 5018                    .context("inlay hints proto request")?;
 5019                match response.hint {
 5020                    Some(resolved_hint) => InlayHints::proto_to_project_hint(resolved_hint)
 5021                        .context("inlay hints proto resolve response conversion"),
 5022                    None => Ok(hint),
 5023                }
 5024            })
 5025        } else {
 5026            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5027                self.language_server_for_local_buffer(buffer, server_id, cx)
 5028                    .map(|(_, server)| server.clone())
 5029            }) else {
 5030                return Task::ready(Ok(hint));
 5031            };
 5032            if !InlayHints::can_resolve_inlays(&lang_server.capabilities()) {
 5033                return Task::ready(Ok(hint));
 5034            }
 5035            let buffer_snapshot = buffer.read(cx).snapshot();
 5036            cx.spawn(async move |_, cx| {
 5037                let resolve_task = lang_server.request::<lsp::request::InlayHintResolveRequest>(
 5038                    InlayHints::project_to_lsp_hint(hint, &buffer_snapshot),
 5039                );
 5040                let resolved_hint = resolve_task
 5041                    .await
 5042                    .into_response()
 5043                    .context("inlay hint resolve LSP request")?;
 5044                let resolved_hint = InlayHints::lsp_to_project_hint(
 5045                    resolved_hint,
 5046                    &buffer,
 5047                    server_id,
 5048                    ResolveState::Resolved,
 5049                    false,
 5050                    cx,
 5051                )
 5052                .await?;
 5053                Ok(resolved_hint)
 5054            })
 5055        }
 5056    }
 5057
 5058    pub fn resolve_color_presentation(
 5059        &mut self,
 5060        mut color: DocumentColor,
 5061        buffer: Entity<Buffer>,
 5062        server_id: LanguageServerId,
 5063        cx: &mut Context<Self>,
 5064    ) -> Task<Result<DocumentColor>> {
 5065        if color.resolved {
 5066            return Task::ready(Ok(color));
 5067        }
 5068
 5069        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5070            let start = color.lsp_range.start;
 5071            let end = color.lsp_range.end;
 5072            let request = proto::GetColorPresentation {
 5073                project_id,
 5074                server_id: server_id.to_proto(),
 5075                buffer_id: buffer.read(cx).remote_id().into(),
 5076                color: Some(proto::ColorInformation {
 5077                    red: color.color.red,
 5078                    green: color.color.green,
 5079                    blue: color.color.blue,
 5080                    alpha: color.color.alpha,
 5081                    lsp_range_start: Some(proto::PointUtf16 {
 5082                        row: start.line,
 5083                        column: start.character,
 5084                    }),
 5085                    lsp_range_end: Some(proto::PointUtf16 {
 5086                        row: end.line,
 5087                        column: end.character,
 5088                    }),
 5089                }),
 5090            };
 5091            cx.background_spawn(async move {
 5092                let response = upstream_client
 5093                    .request(request)
 5094                    .await
 5095                    .context("color presentation proto request")?;
 5096                color.resolved = true;
 5097                color.color_presentations = response
 5098                    .presentations
 5099                    .into_iter()
 5100                    .map(|presentation| ColorPresentation {
 5101                        label: SharedString::from(presentation.label),
 5102                        text_edit: presentation.text_edit.and_then(deserialize_lsp_edit),
 5103                        additional_text_edits: presentation
 5104                            .additional_text_edits
 5105                            .into_iter()
 5106                            .filter_map(deserialize_lsp_edit)
 5107                            .collect(),
 5108                    })
 5109                    .collect();
 5110                Ok(color)
 5111            })
 5112        } else {
 5113            let path = match buffer
 5114                .update(cx, |buffer, cx| {
 5115                    Some(File::from_dyn(buffer.file())?.abs_path(cx))
 5116                })
 5117                .context("buffer with the missing path")
 5118            {
 5119                Ok(path) => path,
 5120                Err(e) => return Task::ready(Err(e)),
 5121            };
 5122            let Some(lang_server) = buffer.update(cx, |buffer, cx| {
 5123                self.language_server_for_local_buffer(buffer, server_id, cx)
 5124                    .map(|(_, server)| server.clone())
 5125            }) else {
 5126                return Task::ready(Ok(color));
 5127            };
 5128            cx.background_spawn(async move {
 5129                let resolve_task = lang_server.request::<lsp::request::ColorPresentationRequest>(
 5130                    lsp::ColorPresentationParams {
 5131                        text_document: make_text_document_identifier(&path)?,
 5132                        color: color.color,
 5133                        range: color.lsp_range,
 5134                        work_done_progress_params: Default::default(),
 5135                        partial_result_params: Default::default(),
 5136                    },
 5137                );
 5138                color.color_presentations = resolve_task
 5139                    .await
 5140                    .into_response()
 5141                    .context("color presentation resolve LSP request")?
 5142                    .into_iter()
 5143                    .map(|presentation| ColorPresentation {
 5144                        label: SharedString::from(presentation.label),
 5145                        text_edit: presentation.text_edit,
 5146                        additional_text_edits: presentation
 5147                            .additional_text_edits
 5148                            .unwrap_or_default(),
 5149                    })
 5150                    .collect();
 5151                color.resolved = true;
 5152                Ok(color)
 5153            })
 5154        }
 5155    }
 5156
 5157    pub(crate) fn linked_edits(
 5158        &mut self,
 5159        buffer: &Entity<Buffer>,
 5160        position: Anchor,
 5161        cx: &mut Context<Self>,
 5162    ) -> Task<Result<Vec<Range<Anchor>>>> {
 5163        let snapshot = buffer.read(cx).snapshot();
 5164        let scope = snapshot.language_scope_at(position);
 5165        let Some(server_id) = self
 5166            .as_local()
 5167            .and_then(|local| {
 5168                buffer.update(cx, |buffer, cx| {
 5169                    local
 5170                        .language_servers_for_buffer(buffer, cx)
 5171                        .filter(|(_, server)| {
 5172                            LinkedEditingRange::check_server_capabilities(server.capabilities())
 5173                        })
 5174                        .filter(|(adapter, _)| {
 5175                            scope
 5176                                .as_ref()
 5177                                .map(|scope| scope.language_allowed(&adapter.name))
 5178                                .unwrap_or(true)
 5179                        })
 5180                        .map(|(_, server)| LanguageServerToQuery::Other(server.server_id()))
 5181                        .next()
 5182                })
 5183            })
 5184            .or_else(|| {
 5185                self.upstream_client()
 5186                    .is_some()
 5187                    .then_some(LanguageServerToQuery::FirstCapable)
 5188            })
 5189            .filter(|_| {
 5190                maybe!({
 5191                    let language = buffer.read(cx).language_at(position)?;
 5192                    Some(
 5193                        language_settings(Some(language.name()), buffer.read(cx).file(), cx)
 5194                            .linked_edits,
 5195                    )
 5196                }) == Some(true)
 5197            })
 5198        else {
 5199            return Task::ready(Ok(Vec::new()));
 5200        };
 5201
 5202        self.request_lsp(
 5203            buffer.clone(),
 5204            server_id,
 5205            LinkedEditingRange { position },
 5206            cx,
 5207        )
 5208    }
 5209
 5210    fn apply_on_type_formatting(
 5211        &mut self,
 5212        buffer: Entity<Buffer>,
 5213        position: Anchor,
 5214        trigger: String,
 5215        cx: &mut Context<Self>,
 5216    ) -> Task<Result<Option<Transaction>>> {
 5217        if let Some((client, project_id)) = self.upstream_client() {
 5218            if !self.check_if_capable_for_proto_request(
 5219                &buffer,
 5220                |capabilities| {
 5221                    OnTypeFormatting::supports_on_type_formatting(&trigger, capabilities)
 5222                },
 5223                cx,
 5224            ) {
 5225                return Task::ready(Ok(None));
 5226            }
 5227            let request = proto::OnTypeFormatting {
 5228                project_id,
 5229                buffer_id: buffer.read(cx).remote_id().into(),
 5230                position: Some(serialize_anchor(&position)),
 5231                trigger,
 5232                version: serialize_version(&buffer.read(cx).version()),
 5233            };
 5234            cx.background_spawn(async move {
 5235                client
 5236                    .request(request)
 5237                    .await?
 5238                    .transaction
 5239                    .map(language::proto::deserialize_transaction)
 5240                    .transpose()
 5241            })
 5242        } else if let Some(local) = self.as_local_mut() {
 5243            let buffer_id = buffer.read(cx).remote_id();
 5244            local.buffers_being_formatted.insert(buffer_id);
 5245            cx.spawn(async move |this, cx| {
 5246                let _cleanup = defer({
 5247                    let this = this.clone();
 5248                    let mut cx = cx.clone();
 5249                    move || {
 5250                        this.update(&mut cx, |this, _| {
 5251                            if let Some(local) = this.as_local_mut() {
 5252                                local.buffers_being_formatted.remove(&buffer_id);
 5253                            }
 5254                        })
 5255                        .ok();
 5256                    }
 5257                });
 5258
 5259                buffer
 5260                    .update(cx, |buffer, _| {
 5261                        buffer.wait_for_edits(Some(position.timestamp))
 5262                    })?
 5263                    .await?;
 5264                this.update(cx, |this, cx| {
 5265                    let position = position.to_point_utf16(buffer.read(cx));
 5266                    this.on_type_format(buffer, position, trigger, false, cx)
 5267                })?
 5268                .await
 5269            })
 5270        } else {
 5271            Task::ready(Err(anyhow!("No upstream client or local language server")))
 5272        }
 5273    }
 5274
 5275    pub fn on_type_format<T: ToPointUtf16>(
 5276        &mut self,
 5277        buffer: Entity<Buffer>,
 5278        position: T,
 5279        trigger: String,
 5280        push_to_history: bool,
 5281        cx: &mut Context<Self>,
 5282    ) -> Task<Result<Option<Transaction>>> {
 5283        let position = position.to_point_utf16(buffer.read(cx));
 5284        self.on_type_format_impl(buffer, position, trigger, push_to_history, cx)
 5285    }
 5286
 5287    fn on_type_format_impl(
 5288        &mut self,
 5289        buffer: Entity<Buffer>,
 5290        position: PointUtf16,
 5291        trigger: String,
 5292        push_to_history: bool,
 5293        cx: &mut Context<Self>,
 5294    ) -> Task<Result<Option<Transaction>>> {
 5295        let options = buffer.update(cx, |buffer, cx| {
 5296            lsp_command::lsp_formatting_options(
 5297                language_settings(
 5298                    buffer.language_at(position).map(|l| l.name()),
 5299                    buffer.file(),
 5300                    cx,
 5301                )
 5302                .as_ref(),
 5303            )
 5304        });
 5305
 5306        cx.spawn(async move |this, cx| {
 5307            if let Some(waiter) =
 5308                buffer.update(cx, |buffer, _| buffer.wait_for_autoindent_applied())?
 5309            {
 5310                waiter.await?;
 5311            }
 5312            cx.update(|cx| {
 5313                this.update(cx, |this, cx| {
 5314                    this.request_lsp(
 5315                        buffer.clone(),
 5316                        LanguageServerToQuery::FirstCapable,
 5317                        OnTypeFormatting {
 5318                            position,
 5319                            trigger,
 5320                            options,
 5321                            push_to_history,
 5322                        },
 5323                        cx,
 5324                    )
 5325                })
 5326            })??
 5327            .await
 5328        })
 5329    }
 5330
 5331    pub fn definitions(
 5332        &mut self,
 5333        buffer: &Entity<Buffer>,
 5334        position: PointUtf16,
 5335        cx: &mut Context<Self>,
 5336    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5337        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5338            let request = GetDefinitions { position };
 5339            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5340                return Task::ready(Ok(None));
 5341            }
 5342            let request_task = upstream_client.request_lsp(
 5343                project_id,
 5344                None,
 5345                LSP_REQUEST_TIMEOUT,
 5346                cx.background_executor().clone(),
 5347                request.to_proto(project_id, buffer.read(cx)),
 5348            );
 5349            let buffer = buffer.clone();
 5350            cx.spawn(async move |weak_lsp_store, cx| {
 5351                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5352                    return Ok(None);
 5353                };
 5354                let Some(responses) = request_task.await? else {
 5355                    return Ok(None);
 5356                };
 5357                let actions = join_all(responses.payload.into_iter().map(|response| {
 5358                    GetDefinitions { position }.response_from_proto(
 5359                        response.response,
 5360                        lsp_store.clone(),
 5361                        buffer.clone(),
 5362                        cx.clone(),
 5363                    )
 5364                }))
 5365                .await;
 5366
 5367                Ok(Some(
 5368                    actions
 5369                        .into_iter()
 5370                        .collect::<Result<Vec<Vec<_>>>>()?
 5371                        .into_iter()
 5372                        .flatten()
 5373                        .dedup()
 5374                        .collect(),
 5375                ))
 5376            })
 5377        } else {
 5378            let definitions_task = self.request_multiple_lsp_locally(
 5379                buffer,
 5380                Some(position),
 5381                GetDefinitions { position },
 5382                cx,
 5383            );
 5384            cx.background_spawn(async move {
 5385                Ok(Some(
 5386                    definitions_task
 5387                        .await
 5388                        .into_iter()
 5389                        .flat_map(|(_, definitions)| definitions)
 5390                        .dedup()
 5391                        .collect(),
 5392                ))
 5393            })
 5394        }
 5395    }
 5396
 5397    pub fn declarations(
 5398        &mut self,
 5399        buffer: &Entity<Buffer>,
 5400        position: PointUtf16,
 5401        cx: &mut Context<Self>,
 5402    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5403        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5404            let request = GetDeclarations { position };
 5405            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5406                return Task::ready(Ok(None));
 5407            }
 5408            let request_task = upstream_client.request_lsp(
 5409                project_id,
 5410                None,
 5411                LSP_REQUEST_TIMEOUT,
 5412                cx.background_executor().clone(),
 5413                request.to_proto(project_id, buffer.read(cx)),
 5414            );
 5415            let buffer = buffer.clone();
 5416            cx.spawn(async move |weak_lsp_store, cx| {
 5417                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5418                    return Ok(None);
 5419                };
 5420                let Some(responses) = request_task.await? else {
 5421                    return Ok(None);
 5422                };
 5423                let actions = join_all(responses.payload.into_iter().map(|response| {
 5424                    GetDeclarations { position }.response_from_proto(
 5425                        response.response,
 5426                        lsp_store.clone(),
 5427                        buffer.clone(),
 5428                        cx.clone(),
 5429                    )
 5430                }))
 5431                .await;
 5432
 5433                Ok(Some(
 5434                    actions
 5435                        .into_iter()
 5436                        .collect::<Result<Vec<Vec<_>>>>()?
 5437                        .into_iter()
 5438                        .flatten()
 5439                        .dedup()
 5440                        .collect(),
 5441                ))
 5442            })
 5443        } else {
 5444            let declarations_task = self.request_multiple_lsp_locally(
 5445                buffer,
 5446                Some(position),
 5447                GetDeclarations { position },
 5448                cx,
 5449            );
 5450            cx.background_spawn(async move {
 5451                Ok(Some(
 5452                    declarations_task
 5453                        .await
 5454                        .into_iter()
 5455                        .flat_map(|(_, declarations)| declarations)
 5456                        .dedup()
 5457                        .collect(),
 5458                ))
 5459            })
 5460        }
 5461    }
 5462
 5463    pub fn type_definitions(
 5464        &mut self,
 5465        buffer: &Entity<Buffer>,
 5466        position: PointUtf16,
 5467        cx: &mut Context<Self>,
 5468    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5469        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5470            let request = GetTypeDefinitions { position };
 5471            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5472                return Task::ready(Ok(None));
 5473            }
 5474            let request_task = upstream_client.request_lsp(
 5475                project_id,
 5476                None,
 5477                LSP_REQUEST_TIMEOUT,
 5478                cx.background_executor().clone(),
 5479                request.to_proto(project_id, buffer.read(cx)),
 5480            );
 5481            let buffer = buffer.clone();
 5482            cx.spawn(async move |weak_lsp_store, cx| {
 5483                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5484                    return Ok(None);
 5485                };
 5486                let Some(responses) = request_task.await? else {
 5487                    return Ok(None);
 5488                };
 5489                let actions = join_all(responses.payload.into_iter().map(|response| {
 5490                    GetTypeDefinitions { position }.response_from_proto(
 5491                        response.response,
 5492                        lsp_store.clone(),
 5493                        buffer.clone(),
 5494                        cx.clone(),
 5495                    )
 5496                }))
 5497                .await;
 5498
 5499                Ok(Some(
 5500                    actions
 5501                        .into_iter()
 5502                        .collect::<Result<Vec<Vec<_>>>>()?
 5503                        .into_iter()
 5504                        .flatten()
 5505                        .dedup()
 5506                        .collect(),
 5507                ))
 5508            })
 5509        } else {
 5510            let type_definitions_task = self.request_multiple_lsp_locally(
 5511                buffer,
 5512                Some(position),
 5513                GetTypeDefinitions { position },
 5514                cx,
 5515            );
 5516            cx.background_spawn(async move {
 5517                Ok(Some(
 5518                    type_definitions_task
 5519                        .await
 5520                        .into_iter()
 5521                        .flat_map(|(_, type_definitions)| type_definitions)
 5522                        .dedup()
 5523                        .collect(),
 5524                ))
 5525            })
 5526        }
 5527    }
 5528
 5529    pub fn implementations(
 5530        &mut self,
 5531        buffer: &Entity<Buffer>,
 5532        position: PointUtf16,
 5533        cx: &mut Context<Self>,
 5534    ) -> Task<Result<Option<Vec<LocationLink>>>> {
 5535        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5536            let request = GetImplementations { position };
 5537            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5538                return Task::ready(Ok(None));
 5539            }
 5540            let request_task = upstream_client.request_lsp(
 5541                project_id,
 5542                None,
 5543                LSP_REQUEST_TIMEOUT,
 5544                cx.background_executor().clone(),
 5545                request.to_proto(project_id, buffer.read(cx)),
 5546            );
 5547            let buffer = buffer.clone();
 5548            cx.spawn(async move |weak_lsp_store, cx| {
 5549                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5550                    return Ok(None);
 5551                };
 5552                let Some(responses) = request_task.await? else {
 5553                    return Ok(None);
 5554                };
 5555                let actions = join_all(responses.payload.into_iter().map(|response| {
 5556                    GetImplementations { position }.response_from_proto(
 5557                        response.response,
 5558                        lsp_store.clone(),
 5559                        buffer.clone(),
 5560                        cx.clone(),
 5561                    )
 5562                }))
 5563                .await;
 5564
 5565                Ok(Some(
 5566                    actions
 5567                        .into_iter()
 5568                        .collect::<Result<Vec<Vec<_>>>>()?
 5569                        .into_iter()
 5570                        .flatten()
 5571                        .dedup()
 5572                        .collect(),
 5573                ))
 5574            })
 5575        } else {
 5576            let implementations_task = self.request_multiple_lsp_locally(
 5577                buffer,
 5578                Some(position),
 5579                GetImplementations { position },
 5580                cx,
 5581            );
 5582            cx.background_spawn(async move {
 5583                Ok(Some(
 5584                    implementations_task
 5585                        .await
 5586                        .into_iter()
 5587                        .flat_map(|(_, implementations)| implementations)
 5588                        .dedup()
 5589                        .collect(),
 5590                ))
 5591            })
 5592        }
 5593    }
 5594
 5595    pub fn references(
 5596        &mut self,
 5597        buffer: &Entity<Buffer>,
 5598        position: PointUtf16,
 5599        cx: &mut Context<Self>,
 5600    ) -> Task<Result<Option<Vec<Location>>>> {
 5601        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5602            let request = GetReferences { position };
 5603            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5604                return Task::ready(Ok(None));
 5605            }
 5606
 5607            let request_task = upstream_client.request_lsp(
 5608                project_id,
 5609                None,
 5610                LSP_REQUEST_TIMEOUT,
 5611                cx.background_executor().clone(),
 5612                request.to_proto(project_id, buffer.read(cx)),
 5613            );
 5614            let buffer = buffer.clone();
 5615            cx.spawn(async move |weak_lsp_store, cx| {
 5616                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5617                    return Ok(None);
 5618                };
 5619                let Some(responses) = request_task.await? else {
 5620                    return Ok(None);
 5621                };
 5622
 5623                let locations = join_all(responses.payload.into_iter().map(|lsp_response| {
 5624                    GetReferences { position }.response_from_proto(
 5625                        lsp_response.response,
 5626                        lsp_store.clone(),
 5627                        buffer.clone(),
 5628                        cx.clone(),
 5629                    )
 5630                }))
 5631                .await
 5632                .into_iter()
 5633                .collect::<Result<Vec<Vec<_>>>>()?
 5634                .into_iter()
 5635                .flatten()
 5636                .dedup()
 5637                .collect();
 5638                Ok(Some(locations))
 5639            })
 5640        } else {
 5641            let references_task = self.request_multiple_lsp_locally(
 5642                buffer,
 5643                Some(position),
 5644                GetReferences { position },
 5645                cx,
 5646            );
 5647            cx.background_spawn(async move {
 5648                Ok(Some(
 5649                    references_task
 5650                        .await
 5651                        .into_iter()
 5652                        .flat_map(|(_, references)| references)
 5653                        .dedup()
 5654                        .collect(),
 5655                ))
 5656            })
 5657        }
 5658    }
 5659
 5660    pub fn code_actions(
 5661        &mut self,
 5662        buffer: &Entity<Buffer>,
 5663        range: Range<Anchor>,
 5664        kinds: Option<Vec<CodeActionKind>>,
 5665        cx: &mut Context<Self>,
 5666    ) -> Task<Result<Option<Vec<CodeAction>>>> {
 5667        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5668            let request = GetCodeActions {
 5669                range: range.clone(),
 5670                kinds: kinds.clone(),
 5671            };
 5672            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5673                return Task::ready(Ok(None));
 5674            }
 5675            let request_task = upstream_client.request_lsp(
 5676                project_id,
 5677                None,
 5678                LSP_REQUEST_TIMEOUT,
 5679                cx.background_executor().clone(),
 5680                request.to_proto(project_id, buffer.read(cx)),
 5681            );
 5682            let buffer = buffer.clone();
 5683            cx.spawn(async move |weak_lsp_store, cx| {
 5684                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5685                    return Ok(None);
 5686                };
 5687                let Some(responses) = request_task.await? else {
 5688                    return Ok(None);
 5689                };
 5690                let actions = join_all(responses.payload.into_iter().map(|response| {
 5691                    GetCodeActions {
 5692                        range: range.clone(),
 5693                        kinds: kinds.clone(),
 5694                    }
 5695                    .response_from_proto(
 5696                        response.response,
 5697                        lsp_store.clone(),
 5698                        buffer.clone(),
 5699                        cx.clone(),
 5700                    )
 5701                }))
 5702                .await;
 5703
 5704                Ok(Some(
 5705                    actions
 5706                        .into_iter()
 5707                        .collect::<Result<Vec<Vec<_>>>>()?
 5708                        .into_iter()
 5709                        .flatten()
 5710                        .collect(),
 5711                ))
 5712            })
 5713        } else {
 5714            let all_actions_task = self.request_multiple_lsp_locally(
 5715                buffer,
 5716                Some(range.start),
 5717                GetCodeActions { range, kinds },
 5718                cx,
 5719            );
 5720            cx.background_spawn(async move {
 5721                Ok(Some(
 5722                    all_actions_task
 5723                        .await
 5724                        .into_iter()
 5725                        .flat_map(|(_, actions)| actions)
 5726                        .collect(),
 5727                ))
 5728            })
 5729        }
 5730    }
 5731
 5732    pub fn code_lens_actions(
 5733        &mut self,
 5734        buffer: &Entity<Buffer>,
 5735        cx: &mut Context<Self>,
 5736    ) -> CodeLensTask {
 5737        let version_queried_for = buffer.read(cx).version();
 5738        let buffer_id = buffer.read(cx).remote_id();
 5739        let existing_servers = self.as_local().map(|local| {
 5740            local
 5741                .buffers_opened_in_servers
 5742                .get(&buffer_id)
 5743                .cloned()
 5744                .unwrap_or_default()
 5745        });
 5746
 5747        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 5748            if let Some(cached_lens) = &lsp_data.code_lens {
 5749                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 5750                    let has_different_servers = existing_servers.is_some_and(|existing_servers| {
 5751                        existing_servers != cached_lens.lens.keys().copied().collect()
 5752                    });
 5753                    if !has_different_servers {
 5754                        return Task::ready(Ok(Some(
 5755                            cached_lens.lens.values().flatten().cloned().collect(),
 5756                        )))
 5757                        .shared();
 5758                    }
 5759                } else if let Some((updating_for, running_update)) = cached_lens.update.as_ref() {
 5760                    if !version_queried_for.changed_since(updating_for) {
 5761                        return running_update.clone();
 5762                    }
 5763                }
 5764            }
 5765        }
 5766
 5767        let lens_lsp_data = self
 5768            .latest_lsp_data(buffer, cx)
 5769            .code_lens
 5770            .get_or_insert_default();
 5771        let buffer = buffer.clone();
 5772        let query_version_queried_for = version_queried_for.clone();
 5773        let new_task = cx
 5774            .spawn(async move |lsp_store, cx| {
 5775                cx.background_executor()
 5776                    .timer(Duration::from_millis(30))
 5777                    .await;
 5778                let fetched_lens = lsp_store
 5779                    .update(cx, |lsp_store, cx| lsp_store.fetch_code_lens(&buffer, cx))
 5780                    .map_err(Arc::new)?
 5781                    .await
 5782                    .context("fetching code lens")
 5783                    .map_err(Arc::new);
 5784                let fetched_lens = match fetched_lens {
 5785                    Ok(fetched_lens) => fetched_lens,
 5786                    Err(e) => {
 5787                        lsp_store
 5788                            .update(cx, |lsp_store, _| {
 5789                                if let Some(lens_lsp_data) = lsp_store
 5790                                    .lsp_data
 5791                                    .get_mut(&buffer_id)
 5792                                    .and_then(|lsp_data| lsp_data.code_lens.as_mut())
 5793                                {
 5794                                    lens_lsp_data.update = None;
 5795                                }
 5796                            })
 5797                            .ok();
 5798                        return Err(e);
 5799                    }
 5800                };
 5801
 5802                lsp_store
 5803                    .update(cx, |lsp_store, _| {
 5804                        let lsp_data = lsp_store.current_lsp_data(buffer_id)?;
 5805                        let code_lens = lsp_data.code_lens.as_mut()?;
 5806                        if let Some(fetched_lens) = fetched_lens {
 5807                            if lsp_data.buffer_version == query_version_queried_for {
 5808                                code_lens.lens.extend(fetched_lens);
 5809                            } else if !lsp_data
 5810                                .buffer_version
 5811                                .changed_since(&query_version_queried_for)
 5812                            {
 5813                                lsp_data.buffer_version = query_version_queried_for;
 5814                                code_lens.lens = fetched_lens;
 5815                            }
 5816                        }
 5817                        code_lens.update = None;
 5818                        Some(code_lens.lens.values().flatten().cloned().collect())
 5819                    })
 5820                    .map_err(Arc::new)
 5821            })
 5822            .shared();
 5823        lens_lsp_data.update = Some((version_queried_for, new_task.clone()));
 5824        new_task
 5825    }
 5826
 5827    fn fetch_code_lens(
 5828        &mut self,
 5829        buffer: &Entity<Buffer>,
 5830        cx: &mut Context<Self>,
 5831    ) -> Task<Result<Option<HashMap<LanguageServerId, Vec<CodeAction>>>>> {
 5832        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5833            let request = GetCodeLens;
 5834            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5835                return Task::ready(Ok(None));
 5836            }
 5837            let request_task = upstream_client.request_lsp(
 5838                project_id,
 5839                None,
 5840                LSP_REQUEST_TIMEOUT,
 5841                cx.background_executor().clone(),
 5842                request.to_proto(project_id, buffer.read(cx)),
 5843            );
 5844            let buffer = buffer.clone();
 5845            cx.spawn(async move |weak_lsp_store, cx| {
 5846                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 5847                    return Ok(None);
 5848                };
 5849                let Some(responses) = request_task.await? else {
 5850                    return Ok(None);
 5851                };
 5852
 5853                let code_lens_actions = join_all(responses.payload.into_iter().map(|response| {
 5854                    let lsp_store = lsp_store.clone();
 5855                    let buffer = buffer.clone();
 5856                    let cx = cx.clone();
 5857                    async move {
 5858                        (
 5859                            LanguageServerId::from_proto(response.server_id),
 5860                            GetCodeLens
 5861                                .response_from_proto(response.response, lsp_store, buffer, cx)
 5862                                .await,
 5863                        )
 5864                    }
 5865                }))
 5866                .await;
 5867
 5868                let mut has_errors = false;
 5869                let code_lens_actions = code_lens_actions
 5870                    .into_iter()
 5871                    .filter_map(|(server_id, code_lens)| match code_lens {
 5872                        Ok(code_lens) => Some((server_id, code_lens)),
 5873                        Err(e) => {
 5874                            has_errors = true;
 5875                            log::error!("{e:#}");
 5876                            None
 5877                        }
 5878                    })
 5879                    .collect::<HashMap<_, _>>();
 5880                anyhow::ensure!(
 5881                    !has_errors || !code_lens_actions.is_empty(),
 5882                    "Failed to fetch code lens"
 5883                );
 5884                Ok(Some(code_lens_actions))
 5885            })
 5886        } else {
 5887            let code_lens_actions_task =
 5888                self.request_multiple_lsp_locally(buffer, None::<usize>, GetCodeLens, cx);
 5889            cx.background_spawn(async move {
 5890                Ok(Some(code_lens_actions_task.await.into_iter().collect()))
 5891            })
 5892        }
 5893    }
 5894
 5895    #[inline(never)]
 5896    pub fn completions(
 5897        &self,
 5898        buffer: &Entity<Buffer>,
 5899        position: PointUtf16,
 5900        context: CompletionContext,
 5901        cx: &mut Context<Self>,
 5902    ) -> Task<Result<Vec<CompletionResponse>>> {
 5903        let language_registry = self.languages.clone();
 5904
 5905        if let Some((upstream_client, project_id)) = self.upstream_client() {
 5906            let request = GetCompletions { position, context };
 5907            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 5908                return Task::ready(Ok(Vec::new()));
 5909            }
 5910            let task = self.send_lsp_proto_request(
 5911                buffer.clone(),
 5912                upstream_client,
 5913                project_id,
 5914                request,
 5915                cx,
 5916            );
 5917            let language = buffer.read(cx).language().cloned();
 5918
 5919            // In the future, we should provide project guests with the names of LSP adapters,
 5920            // so that they can use the correct LSP adapter when computing labels. For now,
 5921            // guests just use the first LSP adapter associated with the buffer's language.
 5922            let lsp_adapter = language.as_ref().and_then(|language| {
 5923                language_registry
 5924                    .lsp_adapters(&language.name())
 5925                    .first()
 5926                    .cloned()
 5927            });
 5928
 5929            cx.foreground_executor().spawn(async move {
 5930                let completion_response = task.await?;
 5931                let completions = populate_labels_for_completions(
 5932                    completion_response.completions,
 5933                    language,
 5934                    lsp_adapter,
 5935                )
 5936                .await;
 5937                Ok(vec![CompletionResponse {
 5938                    completions,
 5939                    display_options: CompletionDisplayOptions::default(),
 5940                    is_incomplete: completion_response.is_incomplete,
 5941                }])
 5942            })
 5943        } else if let Some(local) = self.as_local() {
 5944            let snapshot = buffer.read(cx).snapshot();
 5945            let offset = position.to_offset(&snapshot);
 5946            let scope = snapshot.language_scope_at(offset);
 5947            let language = snapshot.language().cloned();
 5948            let completion_settings = language_settings(
 5949                language.as_ref().map(|language| language.name()),
 5950                buffer.read(cx).file(),
 5951                cx,
 5952            )
 5953            .completions
 5954            .clone();
 5955            if !completion_settings.lsp {
 5956                return Task::ready(Ok(Vec::new()));
 5957            }
 5958
 5959            let server_ids: Vec<_> = buffer.update(cx, |buffer, cx| {
 5960                local
 5961                    .language_servers_for_buffer(buffer, cx)
 5962                    .filter(|(_, server)| server.capabilities().completion_provider.is_some())
 5963                    .filter(|(adapter, _)| {
 5964                        scope
 5965                            .as_ref()
 5966                            .map(|scope| scope.language_allowed(&adapter.name))
 5967                            .unwrap_or(true)
 5968                    })
 5969                    .map(|(_, server)| server.server_id())
 5970                    .collect()
 5971            });
 5972
 5973            let buffer = buffer.clone();
 5974            let lsp_timeout = completion_settings.lsp_fetch_timeout_ms;
 5975            let lsp_timeout = if lsp_timeout > 0 {
 5976                Some(Duration::from_millis(lsp_timeout))
 5977            } else {
 5978                None
 5979            };
 5980            cx.spawn(async move |this,  cx| {
 5981                let mut tasks = Vec::with_capacity(server_ids.len());
 5982                this.update(cx, |lsp_store, cx| {
 5983                    for server_id in server_ids {
 5984                        let lsp_adapter = lsp_store.language_server_adapter_for_id(server_id);
 5985                        let lsp_timeout = lsp_timeout
 5986                            .map(|lsp_timeout| cx.background_executor().timer(lsp_timeout));
 5987                        let mut timeout = cx.background_spawn(async move {
 5988                            match lsp_timeout {
 5989                                Some(lsp_timeout) => {
 5990                                    lsp_timeout.await;
 5991                                    true
 5992                                },
 5993                                None => false,
 5994                            }
 5995                        }).fuse();
 5996                        let mut lsp_request = lsp_store.request_lsp(
 5997                            buffer.clone(),
 5998                            LanguageServerToQuery::Other(server_id),
 5999                            GetCompletions {
 6000                                position,
 6001                                context: context.clone(),
 6002                            },
 6003                            cx,
 6004                        ).fuse();
 6005                        let new_task = cx.background_spawn(async move {
 6006                            select_biased! {
 6007                                response = lsp_request => anyhow::Ok(Some(response?)),
 6008                                timeout_happened = timeout => {
 6009                                    if timeout_happened {
 6010                                        log::warn!("Fetching completions from server {server_id} timed out, timeout ms: {}", completion_settings.lsp_fetch_timeout_ms);
 6011                                        Ok(None)
 6012                                    } else {
 6013                                        let completions = lsp_request.await?;
 6014                                        Ok(Some(completions))
 6015                                    }
 6016                                },
 6017                            }
 6018                        });
 6019                        tasks.push((lsp_adapter, new_task));
 6020                    }
 6021                })?;
 6022
 6023                let futures = tasks.into_iter().map(async |(lsp_adapter, task)| {
 6024                    let completion_response = task.await.ok()??;
 6025                    let completions = populate_labels_for_completions(
 6026                            completion_response.completions,
 6027                            language.clone(),
 6028                            lsp_adapter,
 6029                        )
 6030                        .await;
 6031                    Some(CompletionResponse {
 6032                        completions,
 6033                        display_options: CompletionDisplayOptions::default(),
 6034                        is_incomplete: completion_response.is_incomplete,
 6035                    })
 6036                });
 6037
 6038                let responses: Vec<Option<CompletionResponse>> = join_all(futures).await;
 6039
 6040                Ok(responses.into_iter().flatten().collect())
 6041            })
 6042        } else {
 6043            Task::ready(Err(anyhow!("No upstream client or local language server")))
 6044        }
 6045    }
 6046
 6047    pub fn resolve_completions(
 6048        &self,
 6049        buffer: Entity<Buffer>,
 6050        completion_indices: Vec<usize>,
 6051        completions: Rc<RefCell<Box<[Completion]>>>,
 6052        cx: &mut Context<Self>,
 6053    ) -> Task<Result<bool>> {
 6054        let client = self.upstream_client();
 6055        let buffer_id = buffer.read(cx).remote_id();
 6056        let buffer_snapshot = buffer.read(cx).snapshot();
 6057
 6058        if !self.check_if_capable_for_proto_request(
 6059            &buffer,
 6060            GetCompletions::can_resolve_completions,
 6061            cx,
 6062        ) {
 6063            return Task::ready(Ok(false));
 6064        }
 6065        cx.spawn(async move |lsp_store, cx| {
 6066            let mut did_resolve = false;
 6067            if let Some((client, project_id)) = client {
 6068                for completion_index in completion_indices {
 6069                    let server_id = {
 6070                        let completion = &completions.borrow()[completion_index];
 6071                        completion.source.server_id()
 6072                    };
 6073                    if let Some(server_id) = server_id {
 6074                        if Self::resolve_completion_remote(
 6075                            project_id,
 6076                            server_id,
 6077                            buffer_id,
 6078                            completions.clone(),
 6079                            completion_index,
 6080                            client.clone(),
 6081                        )
 6082                        .await
 6083                        .log_err()
 6084                        .is_some()
 6085                        {
 6086                            did_resolve = true;
 6087                        }
 6088                    } else {
 6089                        resolve_word_completion(
 6090                            &buffer_snapshot,
 6091                            &mut completions.borrow_mut()[completion_index],
 6092                        );
 6093                    }
 6094                }
 6095            } else {
 6096                for completion_index in completion_indices {
 6097                    let server_id = {
 6098                        let completion = &completions.borrow()[completion_index];
 6099                        completion.source.server_id()
 6100                    };
 6101                    if let Some(server_id) = server_id {
 6102                        let server_and_adapter = lsp_store
 6103                            .read_with(cx, |lsp_store, _| {
 6104                                let server = lsp_store.language_server_for_id(server_id)?;
 6105                                let adapter =
 6106                                    lsp_store.language_server_adapter_for_id(server.server_id())?;
 6107                                Some((server, adapter))
 6108                            })
 6109                            .ok()
 6110                            .flatten();
 6111                        let Some((server, adapter)) = server_and_adapter else {
 6112                            continue;
 6113                        };
 6114
 6115                        let resolved = Self::resolve_completion_local(
 6116                            server,
 6117                            completions.clone(),
 6118                            completion_index,
 6119                        )
 6120                        .await
 6121                        .log_err()
 6122                        .is_some();
 6123                        if resolved {
 6124                            Self::regenerate_completion_labels(
 6125                                adapter,
 6126                                &buffer_snapshot,
 6127                                completions.clone(),
 6128                                completion_index,
 6129                            )
 6130                            .await
 6131                            .log_err();
 6132                            did_resolve = true;
 6133                        }
 6134                    } else {
 6135                        resolve_word_completion(
 6136                            &buffer_snapshot,
 6137                            &mut completions.borrow_mut()[completion_index],
 6138                        );
 6139                    }
 6140                }
 6141            }
 6142
 6143            Ok(did_resolve)
 6144        })
 6145    }
 6146
 6147    async fn resolve_completion_local(
 6148        server: Arc<lsp::LanguageServer>,
 6149        completions: Rc<RefCell<Box<[Completion]>>>,
 6150        completion_index: usize,
 6151    ) -> Result<()> {
 6152        let server_id = server.server_id();
 6153        if !GetCompletions::can_resolve_completions(&server.capabilities()) {
 6154            return Ok(());
 6155        }
 6156
 6157        let request = {
 6158            let completion = &completions.borrow()[completion_index];
 6159            match &completion.source {
 6160                CompletionSource::Lsp {
 6161                    lsp_completion,
 6162                    resolved,
 6163                    server_id: completion_server_id,
 6164                    ..
 6165                } => {
 6166                    if *resolved {
 6167                        return Ok(());
 6168                    }
 6169                    anyhow::ensure!(
 6170                        server_id == *completion_server_id,
 6171                        "server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6172                    );
 6173                    server.request::<lsp::request::ResolveCompletionItem>(*lsp_completion.clone())
 6174                }
 6175                CompletionSource::BufferWord { .. }
 6176                | CompletionSource::Dap { .. }
 6177                | CompletionSource::Custom => {
 6178                    return Ok(());
 6179                }
 6180            }
 6181        };
 6182        let resolved_completion = request
 6183            .await
 6184            .into_response()
 6185            .context("resolve completion")?;
 6186
 6187        // We must not use any data such as sortText, filterText, insertText and textEdit to edit `Completion` since they are not suppose change during resolve.
 6188        // Refer: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
 6189
 6190        let mut completions = completions.borrow_mut();
 6191        let completion = &mut completions[completion_index];
 6192        if let CompletionSource::Lsp {
 6193            lsp_completion,
 6194            resolved,
 6195            server_id: completion_server_id,
 6196            ..
 6197        } = &mut completion.source
 6198        {
 6199            if *resolved {
 6200                return Ok(());
 6201            }
 6202            anyhow::ensure!(
 6203                server_id == *completion_server_id,
 6204                "server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6205            );
 6206            *lsp_completion = Box::new(resolved_completion);
 6207            *resolved = true;
 6208        }
 6209        Ok(())
 6210    }
 6211
 6212    async fn regenerate_completion_labels(
 6213        adapter: Arc<CachedLspAdapter>,
 6214        snapshot: &BufferSnapshot,
 6215        completions: Rc<RefCell<Box<[Completion]>>>,
 6216        completion_index: usize,
 6217    ) -> Result<()> {
 6218        let completion_item = completions.borrow()[completion_index]
 6219            .source
 6220            .lsp_completion(true)
 6221            .map(Cow::into_owned);
 6222        if let Some(lsp_documentation) = completion_item
 6223            .as_ref()
 6224            .and_then(|completion_item| completion_item.documentation.clone())
 6225        {
 6226            let mut completions = completions.borrow_mut();
 6227            let completion = &mut completions[completion_index];
 6228            completion.documentation = Some(lsp_documentation.into());
 6229        } else {
 6230            let mut completions = completions.borrow_mut();
 6231            let completion = &mut completions[completion_index];
 6232            completion.documentation = Some(CompletionDocumentation::Undocumented);
 6233        }
 6234
 6235        let mut new_label = match completion_item {
 6236            Some(completion_item) => {
 6237                // 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
 6238                // So we have to update the label here anyway...
 6239                let language = snapshot.language();
 6240                match language {
 6241                    Some(language) => {
 6242                        adapter
 6243                            .labels_for_completions(
 6244                                std::slice::from_ref(&completion_item),
 6245                                language,
 6246                            )
 6247                            .await?
 6248                    }
 6249                    None => Vec::new(),
 6250                }
 6251                .pop()
 6252                .flatten()
 6253                .unwrap_or_else(|| {
 6254                    CodeLabel::fallback_for_completion(
 6255                        &completion_item,
 6256                        language.map(|language| language.as_ref()),
 6257                    )
 6258                })
 6259            }
 6260            None => CodeLabel::plain(
 6261                completions.borrow()[completion_index].new_text.clone(),
 6262                None,
 6263            ),
 6264        };
 6265        ensure_uniform_list_compatible_label(&mut new_label);
 6266
 6267        let mut completions = completions.borrow_mut();
 6268        let completion = &mut completions[completion_index];
 6269        if completion.label.filter_text() == new_label.filter_text() {
 6270            completion.label = new_label;
 6271        } else {
 6272            log::error!(
 6273                "Resolved completion changed display label from {} to {}. \
 6274                 Refusing to apply this because it changes the fuzzy match text from {} to {}",
 6275                completion.label.text(),
 6276                new_label.text(),
 6277                completion.label.filter_text(),
 6278                new_label.filter_text()
 6279            );
 6280        }
 6281
 6282        Ok(())
 6283    }
 6284
 6285    async fn resolve_completion_remote(
 6286        project_id: u64,
 6287        server_id: LanguageServerId,
 6288        buffer_id: BufferId,
 6289        completions: Rc<RefCell<Box<[Completion]>>>,
 6290        completion_index: usize,
 6291        client: AnyProtoClient,
 6292    ) -> Result<()> {
 6293        let lsp_completion = {
 6294            let completion = &completions.borrow()[completion_index];
 6295            match &completion.source {
 6296                CompletionSource::Lsp {
 6297                    lsp_completion,
 6298                    resolved,
 6299                    server_id: completion_server_id,
 6300                    ..
 6301                } => {
 6302                    anyhow::ensure!(
 6303                        server_id == *completion_server_id,
 6304                        "remote server_id mismatch, querying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6305                    );
 6306                    if *resolved {
 6307                        return Ok(());
 6308                    }
 6309                    serde_json::to_string(lsp_completion).unwrap().into_bytes()
 6310                }
 6311                CompletionSource::Custom
 6312                | CompletionSource::Dap { .. }
 6313                | CompletionSource::BufferWord { .. } => {
 6314                    return Ok(());
 6315                }
 6316            }
 6317        };
 6318        let request = proto::ResolveCompletionDocumentation {
 6319            project_id,
 6320            language_server_id: server_id.0 as u64,
 6321            lsp_completion,
 6322            buffer_id: buffer_id.into(),
 6323        };
 6324
 6325        let response = client
 6326            .request(request)
 6327            .await
 6328            .context("completion documentation resolve proto request")?;
 6329        let resolved_lsp_completion = serde_json::from_slice(&response.lsp_completion)?;
 6330
 6331        let documentation = if response.documentation.is_empty() {
 6332            CompletionDocumentation::Undocumented
 6333        } else if response.documentation_is_markdown {
 6334            CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
 6335        } else if response.documentation.lines().count() <= 1 {
 6336            CompletionDocumentation::SingleLine(response.documentation.into())
 6337        } else {
 6338            CompletionDocumentation::MultiLinePlainText(response.documentation.into())
 6339        };
 6340
 6341        let mut completions = completions.borrow_mut();
 6342        let completion = &mut completions[completion_index];
 6343        completion.documentation = Some(documentation);
 6344        if let CompletionSource::Lsp {
 6345            insert_range,
 6346            lsp_completion,
 6347            resolved,
 6348            server_id: completion_server_id,
 6349            lsp_defaults: _,
 6350        } = &mut completion.source
 6351        {
 6352            let completion_insert_range = response
 6353                .old_insert_start
 6354                .and_then(deserialize_anchor)
 6355                .zip(response.old_insert_end.and_then(deserialize_anchor));
 6356            *insert_range = completion_insert_range.map(|(start, end)| start..end);
 6357
 6358            if *resolved {
 6359                return Ok(());
 6360            }
 6361            anyhow::ensure!(
 6362                server_id == *completion_server_id,
 6363                "remote server_id mismatch, applying completion resolve for {server_id} but completion server id is {completion_server_id}"
 6364            );
 6365            *lsp_completion = Box::new(resolved_lsp_completion);
 6366            *resolved = true;
 6367        }
 6368
 6369        let replace_range = response
 6370            .old_replace_start
 6371            .and_then(deserialize_anchor)
 6372            .zip(response.old_replace_end.and_then(deserialize_anchor));
 6373        if let Some((old_replace_start, old_replace_end)) = replace_range
 6374            && !response.new_text.is_empty()
 6375        {
 6376            completion.new_text = response.new_text;
 6377            completion.replace_range = old_replace_start..old_replace_end;
 6378        }
 6379
 6380        Ok(())
 6381    }
 6382
 6383    pub fn apply_additional_edits_for_completion(
 6384        &self,
 6385        buffer_handle: Entity<Buffer>,
 6386        completions: Rc<RefCell<Box<[Completion]>>>,
 6387        completion_index: usize,
 6388        push_to_history: bool,
 6389        cx: &mut Context<Self>,
 6390    ) -> Task<Result<Option<Transaction>>> {
 6391        if let Some((client, project_id)) = self.upstream_client() {
 6392            let buffer = buffer_handle.read(cx);
 6393            let buffer_id = buffer.remote_id();
 6394            cx.spawn(async move |_, cx| {
 6395                let request = {
 6396                    let completion = completions.borrow()[completion_index].clone();
 6397                    proto::ApplyCompletionAdditionalEdits {
 6398                        project_id,
 6399                        buffer_id: buffer_id.into(),
 6400                        completion: Some(Self::serialize_completion(&CoreCompletion {
 6401                            replace_range: completion.replace_range,
 6402                            new_text: completion.new_text,
 6403                            source: completion.source,
 6404                        })),
 6405                    }
 6406                };
 6407
 6408                if let Some(transaction) = client.request(request).await?.transaction {
 6409                    let transaction = language::proto::deserialize_transaction(transaction)?;
 6410                    buffer_handle
 6411                        .update(cx, |buffer, _| {
 6412                            buffer.wait_for_edits(transaction.edit_ids.iter().copied())
 6413                        })?
 6414                        .await?;
 6415                    if push_to_history {
 6416                        buffer_handle.update(cx, |buffer, _| {
 6417                            buffer.push_transaction(transaction.clone(), Instant::now());
 6418                            buffer.finalize_last_transaction();
 6419                        })?;
 6420                    }
 6421                    Ok(Some(transaction))
 6422                } else {
 6423                    Ok(None)
 6424                }
 6425            })
 6426        } else {
 6427            let Some(server) = buffer_handle.update(cx, |buffer, cx| {
 6428                let completion = &completions.borrow()[completion_index];
 6429                let server_id = completion.source.server_id()?;
 6430                Some(
 6431                    self.language_server_for_local_buffer(buffer, server_id, cx)?
 6432                        .1
 6433                        .clone(),
 6434                )
 6435            }) else {
 6436                return Task::ready(Ok(None));
 6437            };
 6438
 6439            cx.spawn(async move |this, cx| {
 6440                Self::resolve_completion_local(
 6441                    server.clone(),
 6442                    completions.clone(),
 6443                    completion_index,
 6444                )
 6445                .await
 6446                .context("resolving completion")?;
 6447                let completion = completions.borrow()[completion_index].clone();
 6448                let additional_text_edits = completion
 6449                    .source
 6450                    .lsp_completion(true)
 6451                    .as_ref()
 6452                    .and_then(|lsp_completion| lsp_completion.additional_text_edits.clone());
 6453                if let Some(edits) = additional_text_edits {
 6454                    let edits = this
 6455                        .update(cx, |this, cx| {
 6456                            this.as_local_mut().unwrap().edits_from_lsp(
 6457                                &buffer_handle,
 6458                                edits,
 6459                                server.server_id(),
 6460                                None,
 6461                                cx,
 6462                            )
 6463                        })?
 6464                        .await?;
 6465
 6466                    buffer_handle.update(cx, |buffer, cx| {
 6467                        buffer.finalize_last_transaction();
 6468                        buffer.start_transaction();
 6469
 6470                        for (range, text) in edits {
 6471                            let primary = &completion.replace_range;
 6472
 6473                            // Special case: if both ranges start at the very beginning of the file (line 0, column 0),
 6474                            // and the primary completion is just an insertion (empty range), then this is likely
 6475                            // an auto-import scenario and should not be considered overlapping
 6476                            // https://github.com/zed-industries/zed/issues/26136
 6477                            let is_file_start_auto_import = {
 6478                                let snapshot = buffer.snapshot();
 6479                                let primary_start_point = primary.start.to_point(&snapshot);
 6480                                let range_start_point = range.start.to_point(&snapshot);
 6481
 6482                                let result = primary_start_point.row == 0
 6483                                    && primary_start_point.column == 0
 6484                                    && range_start_point.row == 0
 6485                                    && range_start_point.column == 0;
 6486
 6487                                result
 6488                            };
 6489
 6490                            let has_overlap = if is_file_start_auto_import {
 6491                                false
 6492                            } else {
 6493                                let start_within = primary.start.cmp(&range.start, buffer).is_le()
 6494                                    && primary.end.cmp(&range.start, buffer).is_ge();
 6495                                let end_within = range.start.cmp(&primary.end, buffer).is_le()
 6496                                    && range.end.cmp(&primary.end, buffer).is_ge();
 6497                                let result = start_within || end_within;
 6498                                result
 6499                            };
 6500
 6501                            //Skip additional edits which overlap with the primary completion edit
 6502                            //https://github.com/zed-industries/zed/pull/1871
 6503                            if !has_overlap {
 6504                                buffer.edit([(range, text)], None, cx);
 6505                            }
 6506                        }
 6507
 6508                        let transaction = if buffer.end_transaction(cx).is_some() {
 6509                            let transaction = buffer.finalize_last_transaction().unwrap().clone();
 6510                            if !push_to_history {
 6511                                buffer.forget_transaction(transaction.id);
 6512                            }
 6513                            Some(transaction)
 6514                        } else {
 6515                            None
 6516                        };
 6517                        Ok(transaction)
 6518                    })?
 6519                } else {
 6520                    Ok(None)
 6521                }
 6522            })
 6523        }
 6524    }
 6525
 6526    pub fn pull_diagnostics(
 6527        &mut self,
 6528        buffer: Entity<Buffer>,
 6529        cx: &mut Context<Self>,
 6530    ) -> Task<Result<Option<Vec<LspPullDiagnostics>>>> {
 6531        let buffer_id = buffer.read(cx).remote_id();
 6532
 6533        if let Some((client, upstream_project_id)) = self.upstream_client() {
 6534            let mut suitable_capabilities = None;
 6535            // Are we capable for proto request?
 6536            let any_server_has_diagnostics_provider = self.check_if_capable_for_proto_request(
 6537                &buffer,
 6538                |capabilities| {
 6539                    if let Some(caps) = &capabilities.diagnostic_provider {
 6540                        suitable_capabilities = Some(caps.clone());
 6541                        true
 6542                    } else {
 6543                        false
 6544                    }
 6545                },
 6546                cx,
 6547            );
 6548            // We don't really care which caps are passed into the request, as they're ignored by RPC anyways.
 6549            let Some(dynamic_caps) = suitable_capabilities else {
 6550                return Task::ready(Ok(None));
 6551            };
 6552            assert!(any_server_has_diagnostics_provider);
 6553
 6554            let request = GetDocumentDiagnostics {
 6555                previous_result_id: None,
 6556                dynamic_caps,
 6557            };
 6558            let request_task = client.request_lsp(
 6559                upstream_project_id,
 6560                None,
 6561                LSP_REQUEST_TIMEOUT,
 6562                cx.background_executor().clone(),
 6563                request.to_proto(upstream_project_id, buffer.read(cx)),
 6564            );
 6565            cx.background_spawn(async move {
 6566                // Proto requests cause the diagnostics to be pulled from language server(s) on the local side
 6567                // and then, buffer state updated with the diagnostics received, which will be later propagated to the client.
 6568                // Do not attempt to further process the dummy responses here.
 6569                let _response = request_task.await?;
 6570                Ok(None)
 6571            })
 6572        } else {
 6573            let servers = buffer.update(cx, |buffer, cx| {
 6574                self.language_servers_for_local_buffer(buffer, cx)
 6575                    .map(|(_, server)| server.clone())
 6576                    .collect::<Vec<_>>()
 6577            });
 6578
 6579            let pull_diagnostics = servers
 6580                .into_iter()
 6581                .flat_map(|server| {
 6582                    let result = maybe!({
 6583                        let local = self.as_local()?;
 6584                        let server_id = server.server_id();
 6585                        let providers_with_identifiers = local
 6586                            .language_server_dynamic_registrations
 6587                            .get(&server_id)
 6588                            .into_iter()
 6589                            .flat_map(|registrations| registrations.diagnostics.values().cloned())
 6590                            .collect::<Vec<_>>();
 6591                        Some(
 6592                            providers_with_identifiers
 6593                                .into_iter()
 6594                                .map(|dynamic_caps| {
 6595                                    let result_id = self.result_id(server_id, buffer_id, cx);
 6596                                    self.request_lsp(
 6597                                        buffer.clone(),
 6598                                        LanguageServerToQuery::Other(server_id),
 6599                                        GetDocumentDiagnostics {
 6600                                            previous_result_id: result_id,
 6601                                            dynamic_caps,
 6602                                        },
 6603                                        cx,
 6604                                    )
 6605                                })
 6606                                .collect::<Vec<_>>(),
 6607                        )
 6608                    });
 6609
 6610                    result.unwrap_or_default()
 6611                })
 6612                .collect::<Vec<_>>();
 6613
 6614            cx.background_spawn(async move {
 6615                let mut responses = Vec::new();
 6616                for diagnostics in join_all(pull_diagnostics).await {
 6617                    responses.extend(diagnostics?);
 6618                }
 6619                Ok(Some(responses))
 6620            })
 6621        }
 6622    }
 6623
 6624    pub fn applicable_inlay_chunks(
 6625        &mut self,
 6626        buffer: &Entity<Buffer>,
 6627        ranges: &[Range<text::Anchor>],
 6628        cx: &mut Context<Self>,
 6629    ) -> Vec<Range<BufferRow>> {
 6630        self.latest_lsp_data(buffer, cx)
 6631            .inlay_hints
 6632            .applicable_chunks(ranges)
 6633            .map(|chunk| chunk.start..chunk.end)
 6634            .collect()
 6635    }
 6636
 6637    pub fn invalidate_inlay_hints<'a>(
 6638        &'a mut self,
 6639        for_buffers: impl IntoIterator<Item = &'a BufferId> + 'a,
 6640    ) {
 6641        for buffer_id in for_buffers {
 6642            if let Some(lsp_data) = self.lsp_data.get_mut(buffer_id) {
 6643                lsp_data.inlay_hints.clear();
 6644            }
 6645        }
 6646    }
 6647
 6648    pub fn inlay_hints(
 6649        &mut self,
 6650        invalidate: InvalidationStrategy,
 6651        buffer: Entity<Buffer>,
 6652        ranges: Vec<Range<text::Anchor>>,
 6653        known_chunks: Option<(clock::Global, HashSet<Range<BufferRow>>)>,
 6654        cx: &mut Context<Self>,
 6655    ) -> HashMap<Range<BufferRow>, Task<Result<CacheInlayHints>>> {
 6656        let buffer_snapshot = buffer.read(cx).snapshot();
 6657        let next_hint_id = self.next_hint_id.clone();
 6658        let lsp_data = self.latest_lsp_data(&buffer, cx);
 6659        let mut lsp_refresh_requested = false;
 6660        let for_server = if let InvalidationStrategy::RefreshRequested {
 6661            server_id,
 6662            request_id,
 6663        } = invalidate
 6664        {
 6665            let invalidated = lsp_data
 6666                .inlay_hints
 6667                .invalidate_for_server_refresh(server_id, request_id);
 6668            lsp_refresh_requested = invalidated;
 6669            Some(server_id)
 6670        } else {
 6671            None
 6672        };
 6673        let existing_inlay_hints = &mut lsp_data.inlay_hints;
 6674        let known_chunks = known_chunks
 6675            .filter(|(known_version, _)| !lsp_data.buffer_version.changed_since(known_version))
 6676            .map(|(_, known_chunks)| known_chunks)
 6677            .unwrap_or_default();
 6678
 6679        let mut hint_fetch_tasks = Vec::new();
 6680        let mut cached_inlay_hints = None;
 6681        let mut ranges_to_query = None;
 6682        let applicable_chunks = existing_inlay_hints
 6683            .applicable_chunks(ranges.as_slice())
 6684            .filter(|chunk| !known_chunks.contains(&(chunk.start..chunk.end)))
 6685            .collect::<Vec<_>>();
 6686        if applicable_chunks.is_empty() {
 6687            return HashMap::default();
 6688        }
 6689
 6690        let last_chunk_number = existing_inlay_hints.buffer_chunks_len() - 1;
 6691
 6692        for row_chunk in applicable_chunks {
 6693            match (
 6694                existing_inlay_hints
 6695                    .cached_hints(&row_chunk)
 6696                    .filter(|_| !lsp_refresh_requested)
 6697                    .cloned(),
 6698                existing_inlay_hints
 6699                    .fetched_hints(&row_chunk)
 6700                    .as_ref()
 6701                    .filter(|_| !lsp_refresh_requested)
 6702                    .cloned(),
 6703            ) {
 6704                (None, None) => {
 6705                    let end = if last_chunk_number == row_chunk.id {
 6706                        Point::new(row_chunk.end, buffer_snapshot.line_len(row_chunk.end))
 6707                    } else {
 6708                        Point::new(row_chunk.end, 0)
 6709                    };
 6710                    ranges_to_query.get_or_insert_with(Vec::new).push((
 6711                        row_chunk,
 6712                        buffer_snapshot.anchor_before(Point::new(row_chunk.start, 0))
 6713                            ..buffer_snapshot.anchor_after(end),
 6714                    ));
 6715                }
 6716                (None, Some(fetched_hints)) => hint_fetch_tasks.push((row_chunk, fetched_hints)),
 6717                (Some(cached_hints), None) => {
 6718                    for (server_id, cached_hints) in cached_hints {
 6719                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6720                            cached_inlay_hints
 6721                                .get_or_insert_with(HashMap::default)
 6722                                .entry(row_chunk.start..row_chunk.end)
 6723                                .or_insert_with(HashMap::default)
 6724                                .entry(server_id)
 6725                                .or_insert_with(Vec::new)
 6726                                .extend(cached_hints);
 6727                        }
 6728                    }
 6729                }
 6730                (Some(cached_hints), Some(fetched_hints)) => {
 6731                    hint_fetch_tasks.push((row_chunk, fetched_hints));
 6732                    for (server_id, cached_hints) in cached_hints {
 6733                        if for_server.is_none_or(|for_server| for_server == server_id) {
 6734                            cached_inlay_hints
 6735                                .get_or_insert_with(HashMap::default)
 6736                                .entry(row_chunk.start..row_chunk.end)
 6737                                .or_insert_with(HashMap::default)
 6738                                .entry(server_id)
 6739                                .or_insert_with(Vec::new)
 6740                                .extend(cached_hints);
 6741                        }
 6742                    }
 6743                }
 6744            }
 6745        }
 6746
 6747        if hint_fetch_tasks.is_empty()
 6748            && ranges_to_query
 6749                .as_ref()
 6750                .is_none_or(|ranges| ranges.is_empty())
 6751            && let Some(cached_inlay_hints) = cached_inlay_hints
 6752        {
 6753            cached_inlay_hints
 6754                .into_iter()
 6755                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 6756                .collect()
 6757        } else {
 6758            for (chunk, range_to_query) in ranges_to_query.into_iter().flatten() {
 6759                let next_hint_id = next_hint_id.clone();
 6760                let buffer = buffer.clone();
 6761                let new_inlay_hints = cx
 6762                    .spawn(async move |lsp_store, cx| {
 6763                        let new_fetch_task = lsp_store.update(cx, |lsp_store, cx| {
 6764                            lsp_store.fetch_inlay_hints(for_server, &buffer, range_to_query, cx)
 6765                        })?;
 6766                        new_fetch_task
 6767                            .await
 6768                            .and_then(|new_hints_by_server| {
 6769                                lsp_store.update(cx, |lsp_store, cx| {
 6770                                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 6771                                    let update_cache = !lsp_data
 6772                                        .buffer_version
 6773                                        .changed_since(&buffer.read(cx).version());
 6774                                    if new_hints_by_server.is_empty() {
 6775                                        if update_cache {
 6776                                            lsp_data.inlay_hints.invalidate_for_chunk(chunk);
 6777                                        }
 6778                                        HashMap::default()
 6779                                    } else {
 6780                                        new_hints_by_server
 6781                                            .into_iter()
 6782                                            .map(|(server_id, new_hints)| {
 6783                                                let new_hints = new_hints
 6784                                                    .into_iter()
 6785                                                    .map(|new_hint| {
 6786                                                        (
 6787                                                            InlayId::Hint(next_hint_id.fetch_add(
 6788                                                                1,
 6789                                                                atomic::Ordering::AcqRel,
 6790                                                            )),
 6791                                                            new_hint,
 6792                                                        )
 6793                                                    })
 6794                                                    .collect::<Vec<_>>();
 6795                                                if update_cache {
 6796                                                    lsp_data.inlay_hints.insert_new_hints(
 6797                                                        chunk,
 6798                                                        server_id,
 6799                                                        new_hints.clone(),
 6800                                                    );
 6801                                                }
 6802                                                (server_id, new_hints)
 6803                                            })
 6804                                            .collect()
 6805                                    }
 6806                                })
 6807                            })
 6808                            .map_err(Arc::new)
 6809                    })
 6810                    .shared();
 6811
 6812                let fetch_task = lsp_data.inlay_hints.fetched_hints(&chunk);
 6813                *fetch_task = Some(new_inlay_hints.clone());
 6814                hint_fetch_tasks.push((chunk, new_inlay_hints));
 6815            }
 6816
 6817            cached_inlay_hints
 6818                .unwrap_or_default()
 6819                .into_iter()
 6820                .map(|(row_chunk, hints)| (row_chunk, Task::ready(Ok(hints))))
 6821                .chain(hint_fetch_tasks.into_iter().map(|(chunk, hints_fetch)| {
 6822                    (
 6823                        chunk.start..chunk.end,
 6824                        cx.spawn(async move |_, _| {
 6825                            hints_fetch.await.map_err(|e| {
 6826                                if e.error_code() != ErrorCode::Internal {
 6827                                    anyhow!(e.error_code())
 6828                                } else {
 6829                                    anyhow!("{e:#}")
 6830                                }
 6831                            })
 6832                        }),
 6833                    )
 6834                }))
 6835                .collect()
 6836        }
 6837    }
 6838
 6839    fn fetch_inlay_hints(
 6840        &mut self,
 6841        for_server: Option<LanguageServerId>,
 6842        buffer: &Entity<Buffer>,
 6843        range: Range<Anchor>,
 6844        cx: &mut Context<Self>,
 6845    ) -> Task<Result<HashMap<LanguageServerId, Vec<InlayHint>>>> {
 6846        let request = InlayHints {
 6847            range: range.clone(),
 6848        };
 6849        if let Some((upstream_client, project_id)) = self.upstream_client() {
 6850            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 6851                return Task::ready(Ok(HashMap::default()));
 6852            }
 6853            let request_task = upstream_client.request_lsp(
 6854                project_id,
 6855                for_server.map(|id| id.to_proto()),
 6856                LSP_REQUEST_TIMEOUT,
 6857                cx.background_executor().clone(),
 6858                request.to_proto(project_id, buffer.read(cx)),
 6859            );
 6860            let buffer = buffer.clone();
 6861            cx.spawn(async move |weak_lsp_store, cx| {
 6862                let Some(lsp_store) = weak_lsp_store.upgrade() else {
 6863                    return Ok(HashMap::default());
 6864                };
 6865                let Some(responses) = request_task.await? else {
 6866                    return Ok(HashMap::default());
 6867                };
 6868
 6869                let inlay_hints = join_all(responses.payload.into_iter().map(|response| {
 6870                    let lsp_store = lsp_store.clone();
 6871                    let buffer = buffer.clone();
 6872                    let cx = cx.clone();
 6873                    let request = request.clone();
 6874                    async move {
 6875                        (
 6876                            LanguageServerId::from_proto(response.server_id),
 6877                            request
 6878                                .response_from_proto(response.response, lsp_store, buffer, cx)
 6879                                .await,
 6880                        )
 6881                    }
 6882                }))
 6883                .await;
 6884
 6885                let mut has_errors = false;
 6886                let inlay_hints = inlay_hints
 6887                    .into_iter()
 6888                    .filter_map(|(server_id, inlay_hints)| match inlay_hints {
 6889                        Ok(inlay_hints) => Some((server_id, inlay_hints)),
 6890                        Err(e) => {
 6891                            has_errors = true;
 6892                            log::error!("{e:#}");
 6893                            None
 6894                        }
 6895                    })
 6896                    .collect::<HashMap<_, _>>();
 6897                anyhow::ensure!(
 6898                    !has_errors || !inlay_hints.is_empty(),
 6899                    "Failed to fetch inlay hints"
 6900                );
 6901                Ok(inlay_hints)
 6902            })
 6903        } else {
 6904            let inlay_hints_task = match for_server {
 6905                Some(server_id) => {
 6906                    let server_task = self.request_lsp(
 6907                        buffer.clone(),
 6908                        LanguageServerToQuery::Other(server_id),
 6909                        request,
 6910                        cx,
 6911                    );
 6912                    cx.background_spawn(async move {
 6913                        let mut responses = Vec::new();
 6914                        match server_task.await {
 6915                            Ok(response) => responses.push((server_id, response)),
 6916                            // rust-analyzer likes to error with this when its still loading up
 6917                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
 6918                            Err(e) => log::error!(
 6919                                "Error handling response for inlay hints request: {e:#}"
 6920                            ),
 6921                        }
 6922                        responses
 6923                    })
 6924                }
 6925                None => self.request_multiple_lsp_locally(buffer, None::<usize>, request, cx),
 6926            };
 6927            let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
 6928            cx.background_spawn(async move {
 6929                Ok(inlay_hints_task
 6930                    .await
 6931                    .into_iter()
 6932                    .map(|(server_id, mut new_hints)| {
 6933                        new_hints.retain(|hint| {
 6934                            hint.position.is_valid(&buffer_snapshot)
 6935                                && range.start.is_valid(&buffer_snapshot)
 6936                                && range.end.is_valid(&buffer_snapshot)
 6937                                && hint.position.cmp(&range.start, &buffer_snapshot).is_ge()
 6938                                && hint.position.cmp(&range.end, &buffer_snapshot).is_lt()
 6939                        });
 6940                        (server_id, new_hints)
 6941                    })
 6942                    .collect())
 6943            })
 6944        }
 6945    }
 6946
 6947    pub fn pull_diagnostics_for_buffer(
 6948        &mut self,
 6949        buffer: Entity<Buffer>,
 6950        cx: &mut Context<Self>,
 6951    ) -> Task<anyhow::Result<()>> {
 6952        let diagnostics = self.pull_diagnostics(buffer, cx);
 6953        cx.spawn(async move |lsp_store, cx| {
 6954            let Some(diagnostics) = diagnostics.await.context("pulling diagnostics")? else {
 6955                return Ok(());
 6956            };
 6957            lsp_store.update(cx, |lsp_store, cx| {
 6958                if lsp_store.as_local().is_none() {
 6959                    return;
 6960                }
 6961
 6962                let mut unchanged_buffers = HashSet::default();
 6963                let mut changed_buffers = HashSet::default();
 6964                let server_diagnostics_updates = diagnostics
 6965                    .into_iter()
 6966                    .filter_map(|diagnostics_set| match diagnostics_set {
 6967                        LspPullDiagnostics::Response {
 6968                            server_id,
 6969                            uri,
 6970                            diagnostics,
 6971                        } => Some((server_id, uri, diagnostics)),
 6972                        LspPullDiagnostics::Default => None,
 6973                    })
 6974                    .fold(
 6975                        HashMap::default(),
 6976                        |mut acc, (server_id, uri, diagnostics)| {
 6977                            let (result_id, diagnostics) = match diagnostics {
 6978                                PulledDiagnostics::Unchanged { result_id } => {
 6979                                    unchanged_buffers.insert(uri.clone());
 6980                                    (Some(result_id), Vec::new())
 6981                                }
 6982                                PulledDiagnostics::Changed {
 6983                                    result_id,
 6984                                    diagnostics,
 6985                                } => {
 6986                                    changed_buffers.insert(uri.clone());
 6987                                    (result_id, diagnostics)
 6988                                }
 6989                            };
 6990                            let disk_based_sources = Cow::Owned(
 6991                                lsp_store
 6992                                    .language_server_adapter_for_id(server_id)
 6993                                    .as_ref()
 6994                                    .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
 6995                                    .unwrap_or(&[])
 6996                                    .to_vec(),
 6997                            );
 6998                            acc.entry(server_id).or_insert_with(Vec::new).push(
 6999                                DocumentDiagnosticsUpdate {
 7000                                    server_id,
 7001                                    diagnostics: lsp::PublishDiagnosticsParams {
 7002                                        uri,
 7003                                        diagnostics,
 7004                                        version: None,
 7005                                    },
 7006                                    result_id,
 7007                                    disk_based_sources,
 7008                                },
 7009                            );
 7010                            acc
 7011                        },
 7012                    );
 7013
 7014                for diagnostic_updates in server_diagnostics_updates.into_values() {
 7015                    lsp_store
 7016                        .merge_lsp_diagnostics(
 7017                            DiagnosticSourceKind::Pulled,
 7018                            diagnostic_updates,
 7019                            |buffer, old_diagnostic, cx| {
 7020                                File::from_dyn(buffer.file())
 7021                                    .and_then(|file| {
 7022                                        let abs_path = file.as_local()?.abs_path(cx);
 7023                                        lsp::Uri::from_file_path(abs_path).ok()
 7024                                    })
 7025                                    .is_none_or(|buffer_uri| {
 7026                                        unchanged_buffers.contains(&buffer_uri)
 7027                                            || match old_diagnostic.source_kind {
 7028                                                DiagnosticSourceKind::Pulled => {
 7029                                                    !changed_buffers.contains(&buffer_uri)
 7030                                                }
 7031                                                DiagnosticSourceKind::Other
 7032                                                | DiagnosticSourceKind::Pushed => true,
 7033                                            }
 7034                                    })
 7035                            },
 7036                            cx,
 7037                        )
 7038                        .log_err();
 7039                }
 7040            })
 7041        })
 7042    }
 7043
 7044    pub fn document_colors(
 7045        &mut self,
 7046        known_cache_version: Option<usize>,
 7047        buffer: Entity<Buffer>,
 7048        cx: &mut Context<Self>,
 7049    ) -> Option<DocumentColorTask> {
 7050        let version_queried_for = buffer.read(cx).version();
 7051        let buffer_id = buffer.read(cx).remote_id();
 7052
 7053        let current_language_servers = self.as_local().map(|local| {
 7054            local
 7055                .buffers_opened_in_servers
 7056                .get(&buffer_id)
 7057                .cloned()
 7058                .unwrap_or_default()
 7059        });
 7060
 7061        if let Some(lsp_data) = self.current_lsp_data(buffer_id) {
 7062            if let Some(cached_colors) = &lsp_data.document_colors {
 7063                if !version_queried_for.changed_since(&lsp_data.buffer_version) {
 7064                    let has_different_servers =
 7065                        current_language_servers.is_some_and(|current_language_servers| {
 7066                            current_language_servers
 7067                                != cached_colors.colors.keys().copied().collect()
 7068                        });
 7069                    if !has_different_servers {
 7070                        let cache_version = cached_colors.cache_version;
 7071                        if Some(cache_version) == known_cache_version {
 7072                            return None;
 7073                        } else {
 7074                            return Some(
 7075                                Task::ready(Ok(DocumentColors {
 7076                                    colors: cached_colors
 7077                                        .colors
 7078                                        .values()
 7079                                        .flatten()
 7080                                        .cloned()
 7081                                        .collect(),
 7082                                    cache_version: Some(cache_version),
 7083                                }))
 7084                                .shared(),
 7085                            );
 7086                        }
 7087                    }
 7088                }
 7089            }
 7090        }
 7091
 7092        let color_lsp_data = self
 7093            .latest_lsp_data(&buffer, cx)
 7094            .document_colors
 7095            .get_or_insert_default();
 7096        if let Some((updating_for, running_update)) = &color_lsp_data.colors_update
 7097            && !version_queried_for.changed_since(updating_for)
 7098        {
 7099            return Some(running_update.clone());
 7100        }
 7101        let buffer_version_queried_for = version_queried_for.clone();
 7102        let new_task = cx
 7103            .spawn(async move |lsp_store, cx| {
 7104                cx.background_executor()
 7105                    .timer(Duration::from_millis(30))
 7106                    .await;
 7107                let fetched_colors = lsp_store
 7108                    .update(cx, |lsp_store, cx| {
 7109                        lsp_store.fetch_document_colors_for_buffer(&buffer, cx)
 7110                    })?
 7111                    .await
 7112                    .context("fetching document colors")
 7113                    .map_err(Arc::new);
 7114                let fetched_colors = match fetched_colors {
 7115                    Ok(fetched_colors) => {
 7116                        if Some(true)
 7117                            == buffer
 7118                                .update(cx, |buffer, _| {
 7119                                    buffer.version() != buffer_version_queried_for
 7120                                })
 7121                                .ok()
 7122                        {
 7123                            return Ok(DocumentColors::default());
 7124                        }
 7125                        fetched_colors
 7126                    }
 7127                    Err(e) => {
 7128                        lsp_store
 7129                            .update(cx, |lsp_store, _| {
 7130                                if let Some(lsp_data) = lsp_store.lsp_data.get_mut(&buffer_id) {
 7131                                    if let Some(document_colors) = &mut lsp_data.document_colors {
 7132                                        document_colors.colors_update = None;
 7133                                    }
 7134                                }
 7135                            })
 7136                            .ok();
 7137                        return Err(e);
 7138                    }
 7139                };
 7140
 7141                lsp_store
 7142                    .update(cx, |lsp_store, cx| {
 7143                        let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 7144                        let lsp_colors = lsp_data.document_colors.get_or_insert_default();
 7145
 7146                        if let Some(fetched_colors) = fetched_colors {
 7147                            if lsp_data.buffer_version == buffer_version_queried_for {
 7148                                lsp_colors.colors.extend(fetched_colors);
 7149                                lsp_colors.cache_version += 1;
 7150                            } else if !lsp_data
 7151                                .buffer_version
 7152                                .changed_since(&buffer_version_queried_for)
 7153                            {
 7154                                lsp_data.buffer_version = buffer_version_queried_for;
 7155                                lsp_colors.colors = fetched_colors;
 7156                                lsp_colors.cache_version += 1;
 7157                            }
 7158                        }
 7159                        lsp_colors.colors_update = None;
 7160                        let colors = lsp_colors
 7161                            .colors
 7162                            .values()
 7163                            .flatten()
 7164                            .cloned()
 7165                            .collect::<HashSet<_>>();
 7166                        DocumentColors {
 7167                            colors,
 7168                            cache_version: Some(lsp_colors.cache_version),
 7169                        }
 7170                    })
 7171                    .map_err(Arc::new)
 7172            })
 7173            .shared();
 7174        color_lsp_data.colors_update = Some((version_queried_for, new_task.clone()));
 7175        Some(new_task)
 7176    }
 7177
 7178    fn fetch_document_colors_for_buffer(
 7179        &mut self,
 7180        buffer: &Entity<Buffer>,
 7181        cx: &mut Context<Self>,
 7182    ) -> Task<anyhow::Result<Option<HashMap<LanguageServerId, HashSet<DocumentColor>>>>> {
 7183        if let Some((client, project_id)) = self.upstream_client() {
 7184            let request = GetDocumentColor {};
 7185            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7186                return Task::ready(Ok(None));
 7187            }
 7188
 7189            let request_task = client.request_lsp(
 7190                project_id,
 7191                None,
 7192                LSP_REQUEST_TIMEOUT,
 7193                cx.background_executor().clone(),
 7194                request.to_proto(project_id, buffer.read(cx)),
 7195            );
 7196            let buffer = buffer.clone();
 7197            cx.spawn(async move |lsp_store, cx| {
 7198                let Some(lsp_store) = lsp_store.upgrade() else {
 7199                    return Ok(None);
 7200                };
 7201                let colors = join_all(
 7202                    request_task
 7203                        .await
 7204                        .log_err()
 7205                        .flatten()
 7206                        .map(|response| response.payload)
 7207                        .unwrap_or_default()
 7208                        .into_iter()
 7209                        .map(|color_response| {
 7210                            let response = request.response_from_proto(
 7211                                color_response.response,
 7212                                lsp_store.clone(),
 7213                                buffer.clone(),
 7214                                cx.clone(),
 7215                            );
 7216                            async move {
 7217                                (
 7218                                    LanguageServerId::from_proto(color_response.server_id),
 7219                                    response.await.log_err().unwrap_or_default(),
 7220                                )
 7221                            }
 7222                        }),
 7223                )
 7224                .await
 7225                .into_iter()
 7226                .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7227                    acc.entry(server_id)
 7228                        .or_insert_with(HashSet::default)
 7229                        .extend(colors);
 7230                    acc
 7231                });
 7232                Ok(Some(colors))
 7233            })
 7234        } else {
 7235            let document_colors_task =
 7236                self.request_multiple_lsp_locally(buffer, None::<usize>, GetDocumentColor, cx);
 7237            cx.background_spawn(async move {
 7238                Ok(Some(
 7239                    document_colors_task
 7240                        .await
 7241                        .into_iter()
 7242                        .fold(HashMap::default(), |mut acc, (server_id, colors)| {
 7243                            acc.entry(server_id)
 7244                                .or_insert_with(HashSet::default)
 7245                                .extend(colors);
 7246                            acc
 7247                        })
 7248                        .into_iter()
 7249                        .collect(),
 7250                ))
 7251            })
 7252        }
 7253    }
 7254
 7255    pub fn signature_help<T: ToPointUtf16>(
 7256        &mut self,
 7257        buffer: &Entity<Buffer>,
 7258        position: T,
 7259        cx: &mut Context<Self>,
 7260    ) -> Task<Option<Vec<SignatureHelp>>> {
 7261        let position = position.to_point_utf16(buffer.read(cx));
 7262
 7263        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7264            let request = GetSignatureHelp { position };
 7265            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7266                return Task::ready(None);
 7267            }
 7268            let request_task = client.request_lsp(
 7269                upstream_project_id,
 7270                None,
 7271                LSP_REQUEST_TIMEOUT,
 7272                cx.background_executor().clone(),
 7273                request.to_proto(upstream_project_id, buffer.read(cx)),
 7274            );
 7275            let buffer = buffer.clone();
 7276            cx.spawn(async move |weak_lsp_store, cx| {
 7277                let lsp_store = weak_lsp_store.upgrade()?;
 7278                let signatures = join_all(
 7279                    request_task
 7280                        .await
 7281                        .log_err()
 7282                        .flatten()
 7283                        .map(|response| response.payload)
 7284                        .unwrap_or_default()
 7285                        .into_iter()
 7286                        .map(|response| {
 7287                            let response = GetSignatureHelp { position }.response_from_proto(
 7288                                response.response,
 7289                                lsp_store.clone(),
 7290                                buffer.clone(),
 7291                                cx.clone(),
 7292                            );
 7293                            async move { response.await.log_err().flatten() }
 7294                        }),
 7295                )
 7296                .await
 7297                .into_iter()
 7298                .flatten()
 7299                .collect();
 7300                Some(signatures)
 7301            })
 7302        } else {
 7303            let all_actions_task = self.request_multiple_lsp_locally(
 7304                buffer,
 7305                Some(position),
 7306                GetSignatureHelp { position },
 7307                cx,
 7308            );
 7309            cx.background_spawn(async move {
 7310                Some(
 7311                    all_actions_task
 7312                        .await
 7313                        .into_iter()
 7314                        .flat_map(|(_, actions)| actions)
 7315                        .collect::<Vec<_>>(),
 7316                )
 7317            })
 7318        }
 7319    }
 7320
 7321    pub fn hover(
 7322        &mut self,
 7323        buffer: &Entity<Buffer>,
 7324        position: PointUtf16,
 7325        cx: &mut Context<Self>,
 7326    ) -> Task<Option<Vec<Hover>>> {
 7327        if let Some((client, upstream_project_id)) = self.upstream_client() {
 7328            let request = GetHover { position };
 7329            if !self.is_capable_for_proto_request(buffer, &request, cx) {
 7330                return Task::ready(None);
 7331            }
 7332            let request_task = client.request_lsp(
 7333                upstream_project_id,
 7334                None,
 7335                LSP_REQUEST_TIMEOUT,
 7336                cx.background_executor().clone(),
 7337                request.to_proto(upstream_project_id, buffer.read(cx)),
 7338            );
 7339            let buffer = buffer.clone();
 7340            cx.spawn(async move |weak_lsp_store, cx| {
 7341                let lsp_store = weak_lsp_store.upgrade()?;
 7342                let hovers = join_all(
 7343                    request_task
 7344                        .await
 7345                        .log_err()
 7346                        .flatten()
 7347                        .map(|response| response.payload)
 7348                        .unwrap_or_default()
 7349                        .into_iter()
 7350                        .map(|response| {
 7351                            let response = GetHover { position }.response_from_proto(
 7352                                response.response,
 7353                                lsp_store.clone(),
 7354                                buffer.clone(),
 7355                                cx.clone(),
 7356                            );
 7357                            async move {
 7358                                response
 7359                                    .await
 7360                                    .log_err()
 7361                                    .flatten()
 7362                                    .and_then(remove_empty_hover_blocks)
 7363                            }
 7364                        }),
 7365                )
 7366                .await
 7367                .into_iter()
 7368                .flatten()
 7369                .collect();
 7370                Some(hovers)
 7371            })
 7372        } else {
 7373            let all_actions_task = self.request_multiple_lsp_locally(
 7374                buffer,
 7375                Some(position),
 7376                GetHover { position },
 7377                cx,
 7378            );
 7379            cx.background_spawn(async move {
 7380                Some(
 7381                    all_actions_task
 7382                        .await
 7383                        .into_iter()
 7384                        .filter_map(|(_, hover)| remove_empty_hover_blocks(hover?))
 7385                        .collect::<Vec<Hover>>(),
 7386                )
 7387            })
 7388        }
 7389    }
 7390
 7391    pub fn symbols(&self, query: &str, cx: &mut Context<Self>) -> Task<Result<Vec<Symbol>>> {
 7392        let language_registry = self.languages.clone();
 7393
 7394        if let Some((upstream_client, project_id)) = self.upstream_client().as_ref() {
 7395            let request = upstream_client.request(proto::GetProjectSymbols {
 7396                project_id: *project_id,
 7397                query: query.to_string(),
 7398            });
 7399            cx.foreground_executor().spawn(async move {
 7400                let response = request.await?;
 7401                let mut symbols = Vec::new();
 7402                let core_symbols = response
 7403                    .symbols
 7404                    .into_iter()
 7405                    .filter_map(|symbol| Self::deserialize_symbol(symbol).log_err())
 7406                    .collect::<Vec<_>>();
 7407                populate_labels_for_symbols(core_symbols, &language_registry, None, &mut symbols)
 7408                    .await;
 7409                Ok(symbols)
 7410            })
 7411        } else if let Some(local) = self.as_local() {
 7412            struct WorkspaceSymbolsResult {
 7413                server_id: LanguageServerId,
 7414                lsp_adapter: Arc<CachedLspAdapter>,
 7415                worktree: WeakEntity<Worktree>,
 7416                lsp_symbols: Vec<(String, SymbolKind, lsp::Location)>,
 7417            }
 7418
 7419            let mut requests = Vec::new();
 7420            let mut requested_servers = BTreeSet::new();
 7421            for (seed, state) in local.language_server_ids.iter() {
 7422                let Some(worktree_handle) = self
 7423                    .worktree_store
 7424                    .read(cx)
 7425                    .worktree_for_id(seed.worktree_id, cx)
 7426                else {
 7427                    continue;
 7428                };
 7429                let worktree = worktree_handle.read(cx);
 7430                if !worktree.is_visible() {
 7431                    continue;
 7432                }
 7433
 7434                if !requested_servers.insert(state.id) {
 7435                    continue;
 7436                }
 7437
 7438                let (lsp_adapter, server) = match local.language_servers.get(&state.id) {
 7439                    Some(LanguageServerState::Running {
 7440                        adapter, server, ..
 7441                    }) => (adapter.clone(), server),
 7442
 7443                    _ => continue,
 7444                };
 7445                let supports_workspace_symbol_request =
 7446                    match server.capabilities().workspace_symbol_provider {
 7447                        Some(OneOf::Left(supported)) => supported,
 7448                        Some(OneOf::Right(_)) => true,
 7449                        None => false,
 7450                    };
 7451                if !supports_workspace_symbol_request {
 7452                    continue;
 7453                }
 7454                let worktree_handle = worktree_handle.clone();
 7455                let server_id = server.server_id();
 7456                requests.push(
 7457                        server
 7458                            .request::<lsp::request::WorkspaceSymbolRequest>(
 7459                                lsp::WorkspaceSymbolParams {
 7460                                    query: query.to_string(),
 7461                                    ..Default::default()
 7462                                },
 7463                            )
 7464                            .map(move |response| {
 7465                                let lsp_symbols = response.into_response()
 7466                                    .context("workspace symbols request")
 7467                                    .log_err()
 7468                                    .flatten()
 7469                                    .map(|symbol_response| match symbol_response {
 7470                                        lsp::WorkspaceSymbolResponse::Flat(flat_responses) => {
 7471                                            flat_responses.into_iter().map(|lsp_symbol| {
 7472                                            (lsp_symbol.name, lsp_symbol.kind, lsp_symbol.location)
 7473                                            }).collect::<Vec<_>>()
 7474                                        }
 7475                                        lsp::WorkspaceSymbolResponse::Nested(nested_responses) => {
 7476                                            nested_responses.into_iter().filter_map(|lsp_symbol| {
 7477                                                let location = match lsp_symbol.location {
 7478                                                    OneOf::Left(location) => location,
 7479                                                    OneOf::Right(_) => {
 7480                                                        log::error!("Unexpected: client capabilities forbid symbol resolutions in workspace.symbol.resolveSupport");
 7481                                                        return None
 7482                                                    }
 7483                                                };
 7484                                                Some((lsp_symbol.name, lsp_symbol.kind, location))
 7485                                            }).collect::<Vec<_>>()
 7486                                        }
 7487                                    }).unwrap_or_default();
 7488
 7489                                WorkspaceSymbolsResult {
 7490                                    server_id,
 7491                                    lsp_adapter,
 7492                                    worktree: worktree_handle.downgrade(),
 7493                                    lsp_symbols,
 7494                                }
 7495                            }),
 7496                    );
 7497            }
 7498
 7499            cx.spawn(async move |this, cx| {
 7500                let responses = futures::future::join_all(requests).await;
 7501                let this = match this.upgrade() {
 7502                    Some(this) => this,
 7503                    None => return Ok(Vec::new()),
 7504                };
 7505
 7506                let mut symbols = Vec::new();
 7507                for result in responses {
 7508                    let core_symbols = this.update(cx, |this, cx| {
 7509                        result
 7510                            .lsp_symbols
 7511                            .into_iter()
 7512                            .filter_map(|(symbol_name, symbol_kind, symbol_location)| {
 7513                                let abs_path = symbol_location.uri.to_file_path().ok()?;
 7514                                let source_worktree = result.worktree.upgrade()?;
 7515                                let source_worktree_id = source_worktree.read(cx).id();
 7516
 7517                                let path = if let Some((tree, rel_path)) =
 7518                                    this.worktree_store.read(cx).find_worktree(&abs_path, cx)
 7519                                {
 7520                                    let worktree_id = tree.read(cx).id();
 7521                                    SymbolLocation::InProject(ProjectPath {
 7522                                        worktree_id,
 7523                                        path: rel_path,
 7524                                    })
 7525                                } else {
 7526                                    SymbolLocation::OutsideProject {
 7527                                        signature: this.symbol_signature(&abs_path),
 7528                                        abs_path: abs_path.into(),
 7529                                    }
 7530                                };
 7531
 7532                                Some(CoreSymbol {
 7533                                    source_language_server_id: result.server_id,
 7534                                    language_server_name: result.lsp_adapter.name.clone(),
 7535                                    source_worktree_id,
 7536                                    path,
 7537                                    kind: symbol_kind,
 7538                                    name: symbol_name,
 7539                                    range: range_from_lsp(symbol_location.range),
 7540                                })
 7541                            })
 7542                            .collect()
 7543                    })?;
 7544
 7545                    populate_labels_for_symbols(
 7546                        core_symbols,
 7547                        &language_registry,
 7548                        Some(result.lsp_adapter),
 7549                        &mut symbols,
 7550                    )
 7551                    .await;
 7552                }
 7553
 7554                Ok(symbols)
 7555            })
 7556        } else {
 7557            Task::ready(Err(anyhow!("No upstream client or local language server")))
 7558        }
 7559    }
 7560
 7561    pub fn diagnostic_summary(&self, include_ignored: bool, cx: &App) -> DiagnosticSummary {
 7562        let mut summary = DiagnosticSummary::default();
 7563        for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
 7564            summary.error_count += path_summary.error_count;
 7565            summary.warning_count += path_summary.warning_count;
 7566        }
 7567        summary
 7568    }
 7569
 7570    /// Returns the diagnostic summary for a specific project path.
 7571    pub fn diagnostic_summary_for_path(
 7572        &self,
 7573        project_path: &ProjectPath,
 7574        _: &App,
 7575    ) -> DiagnosticSummary {
 7576        if let Some(summaries) = self
 7577            .diagnostic_summaries
 7578            .get(&project_path.worktree_id)
 7579            .and_then(|map| map.get(&project_path.path))
 7580        {
 7581            let (error_count, warning_count) = summaries.iter().fold(
 7582                (0, 0),
 7583                |(error_count, warning_count), (_language_server_id, summary)| {
 7584                    (
 7585                        error_count + summary.error_count,
 7586                        warning_count + summary.warning_count,
 7587                    )
 7588                },
 7589            );
 7590
 7591            DiagnosticSummary {
 7592                error_count,
 7593                warning_count,
 7594            }
 7595        } else {
 7596            DiagnosticSummary::default()
 7597        }
 7598    }
 7599
 7600    pub fn diagnostic_summaries<'a>(
 7601        &'a self,
 7602        include_ignored: bool,
 7603        cx: &'a App,
 7604    ) -> impl Iterator<Item = (ProjectPath, LanguageServerId, DiagnosticSummary)> + 'a {
 7605        self.worktree_store
 7606            .read(cx)
 7607            .visible_worktrees(cx)
 7608            .filter_map(|worktree| {
 7609                let worktree = worktree.read(cx);
 7610                Some((worktree, self.diagnostic_summaries.get(&worktree.id())?))
 7611            })
 7612            .flat_map(move |(worktree, summaries)| {
 7613                let worktree_id = worktree.id();
 7614                summaries
 7615                    .iter()
 7616                    .filter(move |(path, _)| {
 7617                        include_ignored
 7618                            || worktree
 7619                                .entry_for_path(path.as_ref())
 7620                                .is_some_and(|entry| !entry.is_ignored)
 7621                    })
 7622                    .flat_map(move |(path, summaries)| {
 7623                        summaries.iter().map(move |(server_id, summary)| {
 7624                            (
 7625                                ProjectPath {
 7626                                    worktree_id,
 7627                                    path: path.clone(),
 7628                                },
 7629                                *server_id,
 7630                                *summary,
 7631                            )
 7632                        })
 7633                    })
 7634            })
 7635    }
 7636
 7637    pub fn on_buffer_edited(
 7638        &mut self,
 7639        buffer: Entity<Buffer>,
 7640        cx: &mut Context<Self>,
 7641    ) -> Option<()> {
 7642        let language_servers: Vec<_> = buffer.update(cx, |buffer, cx| {
 7643            Some(
 7644                self.as_local()?
 7645                    .language_servers_for_buffer(buffer, cx)
 7646                    .map(|i| i.1.clone())
 7647                    .collect(),
 7648            )
 7649        })?;
 7650
 7651        let buffer = buffer.read(cx);
 7652        let file = File::from_dyn(buffer.file())?;
 7653        let abs_path = file.as_local()?.abs_path(cx);
 7654        let uri = lsp::Uri::from_file_path(&abs_path)
 7655            .ok()
 7656            .with_context(|| format!("Failed to convert path to URI: {}", abs_path.display()))
 7657            .unwrap();
 7658        let next_snapshot = buffer.text_snapshot();
 7659        for language_server in language_servers {
 7660            let language_server = language_server.clone();
 7661
 7662            let buffer_snapshots = self
 7663                .as_local_mut()
 7664                .unwrap()
 7665                .buffer_snapshots
 7666                .get_mut(&buffer.remote_id())
 7667                .and_then(|m| m.get_mut(&language_server.server_id()))?;
 7668            let previous_snapshot = buffer_snapshots.last()?;
 7669
 7670            let build_incremental_change = || {
 7671                buffer
 7672                    .edits_since::<Dimensions<PointUtf16, usize>>(
 7673                        previous_snapshot.snapshot.version(),
 7674                    )
 7675                    .map(|edit| {
 7676                        let edit_start = edit.new.start.0;
 7677                        let edit_end = edit_start + (edit.old.end.0 - edit.old.start.0);
 7678                        let new_text = next_snapshot
 7679                            .text_for_range(edit.new.start.1..edit.new.end.1)
 7680                            .collect();
 7681                        lsp::TextDocumentContentChangeEvent {
 7682                            range: Some(lsp::Range::new(
 7683                                point_to_lsp(edit_start),
 7684                                point_to_lsp(edit_end),
 7685                            )),
 7686                            range_length: None,
 7687                            text: new_text,
 7688                        }
 7689                    })
 7690                    .collect()
 7691            };
 7692
 7693            let document_sync_kind = language_server
 7694                .capabilities()
 7695                .text_document_sync
 7696                .as_ref()
 7697                .and_then(|sync| match sync {
 7698                    lsp::TextDocumentSyncCapability::Kind(kind) => Some(*kind),
 7699                    lsp::TextDocumentSyncCapability::Options(options) => options.change,
 7700                });
 7701
 7702            let content_changes: Vec<_> = match document_sync_kind {
 7703                Some(lsp::TextDocumentSyncKind::FULL) => {
 7704                    vec![lsp::TextDocumentContentChangeEvent {
 7705                        range: None,
 7706                        range_length: None,
 7707                        text: next_snapshot.text(),
 7708                    }]
 7709                }
 7710                Some(lsp::TextDocumentSyncKind::INCREMENTAL) => build_incremental_change(),
 7711                _ => {
 7712                    #[cfg(any(test, feature = "test-support"))]
 7713                    {
 7714                        build_incremental_change()
 7715                    }
 7716
 7717                    #[cfg(not(any(test, feature = "test-support")))]
 7718                    {
 7719                        continue;
 7720                    }
 7721                }
 7722            };
 7723
 7724            let next_version = previous_snapshot.version + 1;
 7725            buffer_snapshots.push(LspBufferSnapshot {
 7726                version: next_version,
 7727                snapshot: next_snapshot.clone(),
 7728            });
 7729
 7730            language_server
 7731                .notify::<lsp::notification::DidChangeTextDocument>(
 7732                    lsp::DidChangeTextDocumentParams {
 7733                        text_document: lsp::VersionedTextDocumentIdentifier::new(
 7734                            uri.clone(),
 7735                            next_version,
 7736                        ),
 7737                        content_changes,
 7738                    },
 7739                )
 7740                .ok();
 7741            self.pull_workspace_diagnostics(language_server.server_id());
 7742        }
 7743
 7744        None
 7745    }
 7746
 7747    pub fn on_buffer_saved(
 7748        &mut self,
 7749        buffer: Entity<Buffer>,
 7750        cx: &mut Context<Self>,
 7751    ) -> Option<()> {
 7752        let file = File::from_dyn(buffer.read(cx).file())?;
 7753        let worktree_id = file.worktree_id(cx);
 7754        let abs_path = file.as_local()?.abs_path(cx);
 7755        let text_document = lsp::TextDocumentIdentifier {
 7756            uri: file_path_to_lsp_url(&abs_path).log_err()?,
 7757        };
 7758        let local = self.as_local()?;
 7759
 7760        for server in local.language_servers_for_worktree(worktree_id) {
 7761            if let Some(include_text) = include_text(server.as_ref()) {
 7762                let text = if include_text {
 7763                    Some(buffer.read(cx).text())
 7764                } else {
 7765                    None
 7766                };
 7767                server
 7768                    .notify::<lsp::notification::DidSaveTextDocument>(
 7769                        lsp::DidSaveTextDocumentParams {
 7770                            text_document: text_document.clone(),
 7771                            text,
 7772                        },
 7773                    )
 7774                    .ok();
 7775            }
 7776        }
 7777
 7778        let language_servers = buffer.update(cx, |buffer, cx| {
 7779            local.language_server_ids_for_buffer(buffer, cx)
 7780        });
 7781        for language_server_id in language_servers {
 7782            self.simulate_disk_based_diagnostics_events_if_needed(language_server_id, cx);
 7783        }
 7784
 7785        None
 7786    }
 7787
 7788    async fn refresh_workspace_configurations(lsp_store: &WeakEntity<Self>, cx: &mut AsyncApp) {
 7789        maybe!(async move {
 7790            let mut refreshed_servers = HashSet::default();
 7791            let servers = lsp_store
 7792                .update(cx, |lsp_store, cx| {
 7793                    let local = lsp_store.as_local()?;
 7794
 7795                    let servers = local
 7796                        .language_server_ids
 7797                        .iter()
 7798                        .filter_map(|(seed, state)| {
 7799                            let worktree = lsp_store
 7800                                .worktree_store
 7801                                .read(cx)
 7802                                .worktree_for_id(seed.worktree_id, cx);
 7803                            let delegate: Arc<dyn LspAdapterDelegate> =
 7804                                worktree.map(|worktree| {
 7805                                    LocalLspAdapterDelegate::new(
 7806                                        local.languages.clone(),
 7807                                        &local.environment,
 7808                                        cx.weak_entity(),
 7809                                        &worktree,
 7810                                        local.http_client.clone(),
 7811                                        local.fs.clone(),
 7812                                        cx,
 7813                                    )
 7814                                })?;
 7815                            let server_id = state.id;
 7816
 7817                            let states = local.language_servers.get(&server_id)?;
 7818
 7819                            match states {
 7820                                LanguageServerState::Starting { .. } => None,
 7821                                LanguageServerState::Running {
 7822                                    adapter, server, ..
 7823                                } => {
 7824                                    let adapter = adapter.clone();
 7825                                    let server = server.clone();
 7826                                    refreshed_servers.insert(server.name());
 7827                                    let toolchain = seed.toolchain.clone();
 7828                                    Some(cx.spawn(async move |_, cx| {
 7829                                        let settings =
 7830                                            LocalLspStore::workspace_configuration_for_adapter(
 7831                                                adapter.adapter.clone(),
 7832                                                &delegate,
 7833                                                toolchain,
 7834                                                cx,
 7835                                            )
 7836                                            .await
 7837                                            .ok()?;
 7838                                        server
 7839                                            .notify::<lsp::notification::DidChangeConfiguration>(
 7840                                                lsp::DidChangeConfigurationParams { settings },
 7841                                            )
 7842                                            .ok()?;
 7843                                        Some(())
 7844                                    }))
 7845                                }
 7846                            }
 7847                        })
 7848                        .collect::<Vec<_>>();
 7849
 7850                    Some(servers)
 7851                })
 7852                .ok()
 7853                .flatten()?;
 7854
 7855            log::debug!("Refreshing workspace configurations for servers {refreshed_servers:?}");
 7856            // TODO this asynchronous job runs concurrently with extension (de)registration and may take enough time for a certain extension
 7857            // to stop and unregister its language server wrapper.
 7858            // This is racy : an extension might have already removed all `local.language_servers` state, but here we `.clone()` and hold onto it anyway.
 7859            // This now causes errors in the logs, we should find a way to remove such servers from the processing everywhere.
 7860            let _: Vec<Option<()>> = join_all(servers).await;
 7861
 7862            Some(())
 7863        })
 7864        .await;
 7865    }
 7866
 7867    fn maintain_workspace_config(
 7868        external_refresh_requests: watch::Receiver<()>,
 7869        cx: &mut Context<Self>,
 7870    ) -> Task<Result<()>> {
 7871        let (mut settings_changed_tx, mut settings_changed_rx) = watch::channel();
 7872        let _ = postage::stream::Stream::try_recv(&mut settings_changed_rx);
 7873
 7874        let settings_observation = cx.observe_global::<SettingsStore>(move |_, _| {
 7875            *settings_changed_tx.borrow_mut() = ();
 7876        });
 7877
 7878        let mut joint_future =
 7879            futures::stream::select(settings_changed_rx, external_refresh_requests);
 7880        // Multiple things can happen when a workspace environment (selected toolchain + settings) change:
 7881        // - 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).
 7882        // - 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.
 7883        // - In the same vein, we might also decide to start a new language server if the workspace configuration *diverges* from the other.
 7884        // - 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,
 7885        // but it is still different to what we had before, we're gonna send out a workspace configuration update.
 7886        cx.spawn(async move |this, cx| {
 7887            while let Some(()) = joint_future.next().await {
 7888                this.update(cx, |this, cx| {
 7889                    this.refresh_server_tree(cx);
 7890                })
 7891                .ok();
 7892
 7893                Self::refresh_workspace_configurations(&this, cx).await;
 7894            }
 7895
 7896            drop(settings_observation);
 7897            anyhow::Ok(())
 7898        })
 7899    }
 7900
 7901    pub fn language_servers_for_local_buffer<'a>(
 7902        &'a self,
 7903        buffer: &Buffer,
 7904        cx: &mut App,
 7905    ) -> impl Iterator<Item = (&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7906        let local = self.as_local();
 7907        let language_server_ids = local
 7908            .map(|local| local.language_server_ids_for_buffer(buffer, cx))
 7909            .unwrap_or_default();
 7910
 7911        language_server_ids
 7912            .into_iter()
 7913            .filter_map(
 7914                move |server_id| match local?.language_servers.get(&server_id)? {
 7915                    LanguageServerState::Running {
 7916                        adapter, server, ..
 7917                    } => Some((adapter, server)),
 7918                    _ => None,
 7919                },
 7920            )
 7921    }
 7922
 7923    pub fn language_server_for_local_buffer<'a>(
 7924        &'a self,
 7925        buffer: &'a Buffer,
 7926        server_id: LanguageServerId,
 7927        cx: &'a mut App,
 7928    ) -> Option<(&'a Arc<CachedLspAdapter>, &'a Arc<LanguageServer>)> {
 7929        self.as_local()?
 7930            .language_servers_for_buffer(buffer, cx)
 7931            .find(|(_, s)| s.server_id() == server_id)
 7932    }
 7933
 7934    fn remove_worktree(&mut self, id_to_remove: WorktreeId, cx: &mut Context<Self>) {
 7935        self.diagnostic_summaries.remove(&id_to_remove);
 7936        if let Some(local) = self.as_local_mut() {
 7937            let to_remove = local.remove_worktree(id_to_remove, cx);
 7938            for server in to_remove {
 7939                self.language_server_statuses.remove(&server);
 7940            }
 7941        }
 7942    }
 7943
 7944    pub fn shared(
 7945        &mut self,
 7946        project_id: u64,
 7947        downstream_client: AnyProtoClient,
 7948        _: &mut Context<Self>,
 7949    ) {
 7950        self.downstream_client = Some((downstream_client.clone(), project_id));
 7951
 7952        for (server_id, status) in &self.language_server_statuses {
 7953            if let Some(server) = self.language_server_for_id(*server_id) {
 7954                downstream_client
 7955                    .send(proto::StartLanguageServer {
 7956                        project_id,
 7957                        server: Some(proto::LanguageServer {
 7958                            id: server_id.to_proto(),
 7959                            name: status.name.to_string(),
 7960                            worktree_id: status.worktree.map(|id| id.to_proto()),
 7961                        }),
 7962                        capabilities: serde_json::to_string(&server.capabilities())
 7963                            .expect("serializing server LSP capabilities"),
 7964                    })
 7965                    .log_err();
 7966            }
 7967        }
 7968    }
 7969
 7970    pub fn disconnected_from_host(&mut self) {
 7971        self.downstream_client.take();
 7972    }
 7973
 7974    pub fn disconnected_from_ssh_remote(&mut self) {
 7975        if let LspStoreMode::Remote(RemoteLspStore {
 7976            upstream_client, ..
 7977        }) = &mut self.mode
 7978        {
 7979            upstream_client.take();
 7980        }
 7981    }
 7982
 7983    pub(crate) fn set_language_server_statuses_from_proto(
 7984        &mut self,
 7985        project: WeakEntity<Project>,
 7986        language_servers: Vec<proto::LanguageServer>,
 7987        server_capabilities: Vec<String>,
 7988        cx: &mut Context<Self>,
 7989    ) {
 7990        let lsp_logs = cx
 7991            .try_global::<GlobalLogStore>()
 7992            .map(|lsp_store| lsp_store.0.clone());
 7993
 7994        self.language_server_statuses = language_servers
 7995            .into_iter()
 7996            .zip(server_capabilities)
 7997            .map(|(server, server_capabilities)| {
 7998                let server_id = LanguageServerId(server.id as usize);
 7999                if let Ok(server_capabilities) = serde_json::from_str(&server_capabilities) {
 8000                    self.lsp_server_capabilities
 8001                        .insert(server_id, server_capabilities);
 8002                }
 8003
 8004                let name = LanguageServerName::from_proto(server.name);
 8005                let worktree = server.worktree_id.map(WorktreeId::from_proto);
 8006
 8007                if let Some(lsp_logs) = &lsp_logs {
 8008                    lsp_logs.update(cx, |lsp_logs, cx| {
 8009                        lsp_logs.add_language_server(
 8010                            // Only remote clients get their language servers set from proto
 8011                            LanguageServerKind::Remote {
 8012                                project: project.clone(),
 8013                            },
 8014                            server_id,
 8015                            Some(name.clone()),
 8016                            worktree,
 8017                            None,
 8018                            cx,
 8019                        );
 8020                    });
 8021                }
 8022
 8023                (
 8024                    server_id,
 8025                    LanguageServerStatus {
 8026                        name,
 8027                        pending_work: Default::default(),
 8028                        has_pending_diagnostic_updates: false,
 8029                        progress_tokens: Default::default(),
 8030                        worktree,
 8031                    },
 8032                )
 8033            })
 8034            .collect();
 8035    }
 8036
 8037    #[cfg(test)]
 8038    pub fn update_diagnostic_entries(
 8039        &mut self,
 8040        server_id: LanguageServerId,
 8041        abs_path: PathBuf,
 8042        result_id: Option<String>,
 8043        version: Option<i32>,
 8044        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8045        cx: &mut Context<Self>,
 8046    ) -> anyhow::Result<()> {
 8047        self.merge_diagnostic_entries(
 8048            vec![DocumentDiagnosticsUpdate {
 8049                diagnostics: DocumentDiagnostics {
 8050                    diagnostics,
 8051                    document_abs_path: abs_path,
 8052                    version,
 8053                },
 8054                result_id,
 8055                server_id,
 8056                disk_based_sources: Cow::Borrowed(&[]),
 8057            }],
 8058            |_, _, _| false,
 8059            cx,
 8060        )?;
 8061        Ok(())
 8062    }
 8063
 8064    pub fn merge_diagnostic_entries<'a>(
 8065        &mut self,
 8066        diagnostic_updates: Vec<DocumentDiagnosticsUpdate<'a, DocumentDiagnostics>>,
 8067        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
 8068        cx: &mut Context<Self>,
 8069    ) -> anyhow::Result<()> {
 8070        let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8071        let mut updated_diagnostics_paths = HashMap::default();
 8072        for mut update in diagnostic_updates {
 8073            let abs_path = &update.diagnostics.document_abs_path;
 8074            let server_id = update.server_id;
 8075            let Some((worktree, relative_path)) =
 8076                self.worktree_store.read(cx).find_worktree(abs_path, cx)
 8077            else {
 8078                log::warn!("skipping diagnostics update, no worktree found for path {abs_path:?}");
 8079                return Ok(());
 8080            };
 8081
 8082            let worktree_id = worktree.read(cx).id();
 8083            let project_path = ProjectPath {
 8084                worktree_id,
 8085                path: relative_path,
 8086            };
 8087
 8088            if let Some(buffer_handle) = self.buffer_store.read(cx).get_by_path(&project_path) {
 8089                let snapshot = buffer_handle.read(cx).snapshot();
 8090                let buffer = buffer_handle.read(cx);
 8091                let reused_diagnostics = buffer
 8092                    .buffer_diagnostics(Some(server_id))
 8093                    .iter()
 8094                    .filter(|v| merge(buffer, &v.diagnostic, cx))
 8095                    .map(|v| {
 8096                        let start = Unclipped(v.range.start.to_point_utf16(&snapshot));
 8097                        let end = Unclipped(v.range.end.to_point_utf16(&snapshot));
 8098                        DiagnosticEntry {
 8099                            range: start..end,
 8100                            diagnostic: v.diagnostic.clone(),
 8101                        }
 8102                    })
 8103                    .collect::<Vec<_>>();
 8104
 8105                self.as_local_mut()
 8106                    .context("cannot merge diagnostics on a remote LspStore")?
 8107                    .update_buffer_diagnostics(
 8108                        &buffer_handle,
 8109                        server_id,
 8110                        update.result_id,
 8111                        update.diagnostics.version,
 8112                        update.diagnostics.diagnostics.clone(),
 8113                        reused_diagnostics.clone(),
 8114                        cx,
 8115                    )?;
 8116
 8117                update.diagnostics.diagnostics.extend(reused_diagnostics);
 8118            }
 8119
 8120            let updated = worktree.update(cx, |worktree, cx| {
 8121                self.update_worktree_diagnostics(
 8122                    worktree.id(),
 8123                    server_id,
 8124                    project_path.path.clone(),
 8125                    update.diagnostics.diagnostics,
 8126                    cx,
 8127                )
 8128            })?;
 8129            match updated {
 8130                ControlFlow::Continue(new_summary) => {
 8131                    if let Some((project_id, new_summary)) = new_summary {
 8132                        match &mut diagnostics_summary {
 8133                            Some(diagnostics_summary) => {
 8134                                diagnostics_summary
 8135                                    .more_summaries
 8136                                    .push(proto::DiagnosticSummary {
 8137                                        path: project_path.path.as_ref().to_proto(),
 8138                                        language_server_id: server_id.0 as u64,
 8139                                        error_count: new_summary.error_count,
 8140                                        warning_count: new_summary.warning_count,
 8141                                    })
 8142                            }
 8143                            None => {
 8144                                diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8145                                    project_id,
 8146                                    worktree_id: worktree_id.to_proto(),
 8147                                    summary: Some(proto::DiagnosticSummary {
 8148                                        path: project_path.path.as_ref().to_proto(),
 8149                                        language_server_id: server_id.0 as u64,
 8150                                        error_count: new_summary.error_count,
 8151                                        warning_count: new_summary.warning_count,
 8152                                    }),
 8153                                    more_summaries: Vec::new(),
 8154                                })
 8155                            }
 8156                        }
 8157                    }
 8158                    updated_diagnostics_paths
 8159                        .entry(server_id)
 8160                        .or_insert_with(Vec::new)
 8161                        .push(project_path);
 8162                }
 8163                ControlFlow::Break(()) => {}
 8164            }
 8165        }
 8166
 8167        if let Some((diagnostics_summary, (downstream_client, _))) =
 8168            diagnostics_summary.zip(self.downstream_client.as_ref())
 8169        {
 8170            downstream_client.send(diagnostics_summary).log_err();
 8171        }
 8172        for (server_id, paths) in updated_diagnostics_paths {
 8173            cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8174        }
 8175        Ok(())
 8176    }
 8177
 8178    fn update_worktree_diagnostics(
 8179        &mut self,
 8180        worktree_id: WorktreeId,
 8181        server_id: LanguageServerId,
 8182        path_in_worktree: Arc<RelPath>,
 8183        diagnostics: Vec<DiagnosticEntry<Unclipped<PointUtf16>>>,
 8184        _: &mut Context<Worktree>,
 8185    ) -> Result<ControlFlow<(), Option<(u64, proto::DiagnosticSummary)>>> {
 8186        let local = match &mut self.mode {
 8187            LspStoreMode::Local(local_lsp_store) => local_lsp_store,
 8188            _ => anyhow::bail!("update_worktree_diagnostics called on remote"),
 8189        };
 8190
 8191        let summaries_for_tree = self.diagnostic_summaries.entry(worktree_id).or_default();
 8192        let diagnostics_for_tree = local.diagnostics.entry(worktree_id).or_default();
 8193        let summaries_by_server_id = summaries_for_tree
 8194            .entry(path_in_worktree.clone())
 8195            .or_default();
 8196
 8197        let old_summary = summaries_by_server_id
 8198            .remove(&server_id)
 8199            .unwrap_or_default();
 8200
 8201        let new_summary = DiagnosticSummary::new(&diagnostics);
 8202        if new_summary.is_empty() {
 8203            if let Some(diagnostics_by_server_id) = diagnostics_for_tree.get_mut(&path_in_worktree)
 8204            {
 8205                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8206                    diagnostics_by_server_id.remove(ix);
 8207                }
 8208                if diagnostics_by_server_id.is_empty() {
 8209                    diagnostics_for_tree.remove(&path_in_worktree);
 8210                }
 8211            }
 8212        } else {
 8213            summaries_by_server_id.insert(server_id, new_summary);
 8214            let diagnostics_by_server_id = diagnostics_for_tree
 8215                .entry(path_in_worktree.clone())
 8216                .or_default();
 8217            match diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
 8218                Ok(ix) => {
 8219                    diagnostics_by_server_id[ix] = (server_id, diagnostics);
 8220                }
 8221                Err(ix) => {
 8222                    diagnostics_by_server_id.insert(ix, (server_id, diagnostics));
 8223                }
 8224            }
 8225        }
 8226
 8227        if !old_summary.is_empty() || !new_summary.is_empty() {
 8228            if let Some((_, project_id)) = &self.downstream_client {
 8229                Ok(ControlFlow::Continue(Some((
 8230                    *project_id,
 8231                    proto::DiagnosticSummary {
 8232                        path: path_in_worktree.to_proto(),
 8233                        language_server_id: server_id.0 as u64,
 8234                        error_count: new_summary.error_count as u32,
 8235                        warning_count: new_summary.warning_count as u32,
 8236                    },
 8237                ))))
 8238            } else {
 8239                Ok(ControlFlow::Continue(None))
 8240            }
 8241        } else {
 8242            Ok(ControlFlow::Break(()))
 8243        }
 8244    }
 8245
 8246    pub fn open_buffer_for_symbol(
 8247        &mut self,
 8248        symbol: &Symbol,
 8249        cx: &mut Context<Self>,
 8250    ) -> Task<Result<Entity<Buffer>>> {
 8251        if let Some((client, project_id)) = self.upstream_client() {
 8252            let request = client.request(proto::OpenBufferForSymbol {
 8253                project_id,
 8254                symbol: Some(Self::serialize_symbol(symbol)),
 8255            });
 8256            cx.spawn(async move |this, cx| {
 8257                let response = request.await?;
 8258                let buffer_id = BufferId::new(response.buffer_id)?;
 8259                this.update(cx, |this, cx| this.wait_for_remote_buffer(buffer_id, cx))?
 8260                    .await
 8261            })
 8262        } else if let Some(local) = self.as_local() {
 8263            let is_valid = local.language_server_ids.iter().any(|(seed, state)| {
 8264                seed.worktree_id == symbol.source_worktree_id
 8265                    && state.id == symbol.source_language_server_id
 8266                    && symbol.language_server_name == seed.name
 8267            });
 8268            if !is_valid {
 8269                return Task::ready(Err(anyhow!(
 8270                    "language server for worktree and language not found"
 8271                )));
 8272            };
 8273
 8274            let symbol_abs_path = match &symbol.path {
 8275                SymbolLocation::InProject(project_path) => self
 8276                    .worktree_store
 8277                    .read(cx)
 8278                    .absolutize(&project_path, cx)
 8279                    .context("no such worktree"),
 8280                SymbolLocation::OutsideProject {
 8281                    abs_path,
 8282                    signature: _,
 8283                } => Ok(abs_path.to_path_buf()),
 8284            };
 8285            let symbol_abs_path = match symbol_abs_path {
 8286                Ok(abs_path) => abs_path,
 8287                Err(err) => return Task::ready(Err(err)),
 8288            };
 8289            let symbol_uri = if let Ok(uri) = lsp::Uri::from_file_path(symbol_abs_path) {
 8290                uri
 8291            } else {
 8292                return Task::ready(Err(anyhow!("invalid symbol path")));
 8293            };
 8294
 8295            self.open_local_buffer_via_lsp(symbol_uri, symbol.source_language_server_id, cx)
 8296        } else {
 8297            Task::ready(Err(anyhow!("no upstream client or local store")))
 8298        }
 8299    }
 8300
 8301    pub(crate) fn open_local_buffer_via_lsp(
 8302        &mut self,
 8303        abs_path: lsp::Uri,
 8304        language_server_id: LanguageServerId,
 8305        cx: &mut Context<Self>,
 8306    ) -> Task<Result<Entity<Buffer>>> {
 8307        cx.spawn(async move |lsp_store, cx| {
 8308            // Escape percent-encoded string.
 8309            let current_scheme = abs_path.scheme().to_owned();
 8310            // Uri is immutable, so we can't modify the scheme
 8311
 8312            let abs_path = abs_path
 8313                .to_file_path()
 8314                .map_err(|()| anyhow!("can't convert URI to path"))?;
 8315            let p = abs_path.clone();
 8316            let yarn_worktree = lsp_store
 8317                .update(cx, move |lsp_store, cx| match lsp_store.as_local() {
 8318                    Some(local_lsp_store) => local_lsp_store.yarn.update(cx, |_, cx| {
 8319                        cx.spawn(async move |this, cx| {
 8320                            let t = this
 8321                                .update(cx, |this, cx| this.process_path(&p, &current_scheme, cx))
 8322                                .ok()?;
 8323                            t.await
 8324                        })
 8325                    }),
 8326                    None => Task::ready(None),
 8327                })?
 8328                .await;
 8329            let (worktree_root_target, known_relative_path) =
 8330                if let Some((zip_root, relative_path)) = yarn_worktree {
 8331                    (zip_root, Some(relative_path))
 8332                } else {
 8333                    (Arc::<Path>::from(abs_path.as_path()), None)
 8334                };
 8335            let (worktree, relative_path) = if let Some(result) =
 8336                lsp_store.update(cx, |lsp_store, cx| {
 8337                    lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8338                        worktree_store.find_worktree(&worktree_root_target, cx)
 8339                    })
 8340                })? {
 8341                let relative_path = known_relative_path.unwrap_or_else(|| result.1.clone());
 8342                (result.0, relative_path)
 8343            } else {
 8344                let worktree = lsp_store
 8345                    .update(cx, |lsp_store, cx| {
 8346                        lsp_store.worktree_store.update(cx, |worktree_store, cx| {
 8347                            worktree_store.create_worktree(&worktree_root_target, false, cx)
 8348                        })
 8349                    })?
 8350                    .await?;
 8351                if worktree.read_with(cx, |worktree, _| worktree.is_local())? {
 8352                    lsp_store
 8353                        .update(cx, |lsp_store, cx| {
 8354                            if let Some(local) = lsp_store.as_local_mut() {
 8355                                local.register_language_server_for_invisible_worktree(
 8356                                    &worktree,
 8357                                    language_server_id,
 8358                                    cx,
 8359                                )
 8360                            }
 8361                        })
 8362                        .ok();
 8363                }
 8364                let worktree_root = worktree.read_with(cx, |worktree, _| worktree.abs_path())?;
 8365                let relative_path = if let Some(known_path) = known_relative_path {
 8366                    known_path
 8367                } else {
 8368                    RelPath::new(abs_path.strip_prefix(worktree_root)?, PathStyle::local())?
 8369                        .into_arc()
 8370                };
 8371                (worktree, relative_path)
 8372            };
 8373            let project_path = ProjectPath {
 8374                worktree_id: worktree.read_with(cx, |worktree, _| worktree.id())?,
 8375                path: relative_path,
 8376            };
 8377            lsp_store
 8378                .update(cx, |lsp_store, cx| {
 8379                    lsp_store.buffer_store().update(cx, |buffer_store, cx| {
 8380                        buffer_store.open_buffer(project_path, cx)
 8381                    })
 8382                })?
 8383                .await
 8384        })
 8385    }
 8386
 8387    fn request_multiple_lsp_locally<P, R>(
 8388        &mut self,
 8389        buffer: &Entity<Buffer>,
 8390        position: Option<P>,
 8391        request: R,
 8392        cx: &mut Context<Self>,
 8393    ) -> Task<Vec<(LanguageServerId, R::Response)>>
 8394    where
 8395        P: ToOffset,
 8396        R: LspCommand + Clone,
 8397        <R::LspRequest as lsp::request::Request>::Result: Send,
 8398        <R::LspRequest as lsp::request::Request>::Params: Send,
 8399    {
 8400        let Some(local) = self.as_local() else {
 8401            return Task::ready(Vec::new());
 8402        };
 8403
 8404        let snapshot = buffer.read(cx).snapshot();
 8405        let scope = position.and_then(|position| snapshot.language_scope_at(position));
 8406
 8407        let server_ids = buffer.update(cx, |buffer, cx| {
 8408            local
 8409                .language_servers_for_buffer(buffer, cx)
 8410                .filter(|(adapter, _)| {
 8411                    scope
 8412                        .as_ref()
 8413                        .map(|scope| scope.language_allowed(&adapter.name))
 8414                        .unwrap_or(true)
 8415                })
 8416                .map(|(_, server)| server.server_id())
 8417                .filter(|server_id| {
 8418                    self.as_local().is_none_or(|local| {
 8419                        local
 8420                            .buffers_opened_in_servers
 8421                            .get(&snapshot.remote_id())
 8422                            .is_some_and(|servers| servers.contains(server_id))
 8423                    })
 8424                })
 8425                .collect::<Vec<_>>()
 8426        });
 8427
 8428        let mut response_results = server_ids
 8429            .into_iter()
 8430            .map(|server_id| {
 8431                let task = self.request_lsp(
 8432                    buffer.clone(),
 8433                    LanguageServerToQuery::Other(server_id),
 8434                    request.clone(),
 8435                    cx,
 8436                );
 8437                async move { (server_id, task.await) }
 8438            })
 8439            .collect::<FuturesUnordered<_>>();
 8440
 8441        cx.background_spawn(async move {
 8442            let mut responses = Vec::with_capacity(response_results.len());
 8443            while let Some((server_id, response_result)) = response_results.next().await {
 8444                match response_result {
 8445                    Ok(response) => responses.push((server_id, response)),
 8446                    // rust-analyzer likes to error with this when its still loading up
 8447                    Err(e) if format!("{e:#}").ends_with("content modified") => (),
 8448                    Err(e) => log::error!("Error handling response for request {request:?}: {e:#}"),
 8449                }
 8450            }
 8451            responses
 8452        })
 8453    }
 8454
 8455    async fn handle_lsp_command<T: LspCommand>(
 8456        this: Entity<Self>,
 8457        envelope: TypedEnvelope<T::ProtoRequest>,
 8458        mut cx: AsyncApp,
 8459    ) -> Result<<T::ProtoRequest as proto::RequestMessage>::Response>
 8460    where
 8461        <T::LspRequest as lsp::request::Request>::Params: Send,
 8462        <T::LspRequest as lsp::request::Request>::Result: Send,
 8463    {
 8464        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8465        let buffer_id = T::buffer_id_from_proto(&envelope.payload)?;
 8466        let buffer_handle = this.update(&mut cx, |this, cx| {
 8467            this.buffer_store.read(cx).get_existing(buffer_id)
 8468        })??;
 8469        let request = T::from_proto(
 8470            envelope.payload,
 8471            this.clone(),
 8472            buffer_handle.clone(),
 8473            cx.clone(),
 8474        )
 8475        .await?;
 8476        let response = this
 8477            .update(&mut cx, |this, cx| {
 8478                this.request_lsp(
 8479                    buffer_handle.clone(),
 8480                    LanguageServerToQuery::FirstCapable,
 8481                    request,
 8482                    cx,
 8483                )
 8484            })?
 8485            .await?;
 8486        this.update(&mut cx, |this, cx| {
 8487            Ok(T::response_to_proto(
 8488                response,
 8489                this,
 8490                sender_id,
 8491                &buffer_handle.read(cx).version(),
 8492                cx,
 8493            ))
 8494        })?
 8495    }
 8496
 8497    async fn handle_lsp_query(
 8498        lsp_store: Entity<Self>,
 8499        envelope: TypedEnvelope<proto::LspQuery>,
 8500        mut cx: AsyncApp,
 8501    ) -> Result<proto::Ack> {
 8502        use proto::lsp_query::Request;
 8503        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8504        let lsp_query = envelope.payload;
 8505        let lsp_request_id = LspRequestId(lsp_query.lsp_request_id);
 8506        let server_id = lsp_query.server_id.map(LanguageServerId::from_proto);
 8507        match lsp_query.request.context("invalid LSP query request")? {
 8508            Request::GetReferences(get_references) => {
 8509                let position = get_references.position.clone().and_then(deserialize_anchor);
 8510                Self::query_lsp_locally::<GetReferences>(
 8511                    lsp_store,
 8512                    server_id,
 8513                    sender_id,
 8514                    lsp_request_id,
 8515                    get_references,
 8516                    position,
 8517                    &mut cx,
 8518                )
 8519                .await?;
 8520            }
 8521            Request::GetDocumentColor(get_document_color) => {
 8522                Self::query_lsp_locally::<GetDocumentColor>(
 8523                    lsp_store,
 8524                    server_id,
 8525                    sender_id,
 8526                    lsp_request_id,
 8527                    get_document_color,
 8528                    None,
 8529                    &mut cx,
 8530                )
 8531                .await?;
 8532            }
 8533            Request::GetHover(get_hover) => {
 8534                let position = get_hover.position.clone().and_then(deserialize_anchor);
 8535                Self::query_lsp_locally::<GetHover>(
 8536                    lsp_store,
 8537                    server_id,
 8538                    sender_id,
 8539                    lsp_request_id,
 8540                    get_hover,
 8541                    position,
 8542                    &mut cx,
 8543                )
 8544                .await?;
 8545            }
 8546            Request::GetCodeActions(get_code_actions) => {
 8547                Self::query_lsp_locally::<GetCodeActions>(
 8548                    lsp_store,
 8549                    server_id,
 8550                    sender_id,
 8551                    lsp_request_id,
 8552                    get_code_actions,
 8553                    None,
 8554                    &mut cx,
 8555                )
 8556                .await?;
 8557            }
 8558            Request::GetSignatureHelp(get_signature_help) => {
 8559                let position = get_signature_help
 8560                    .position
 8561                    .clone()
 8562                    .and_then(deserialize_anchor);
 8563                Self::query_lsp_locally::<GetSignatureHelp>(
 8564                    lsp_store,
 8565                    server_id,
 8566                    sender_id,
 8567                    lsp_request_id,
 8568                    get_signature_help,
 8569                    position,
 8570                    &mut cx,
 8571                )
 8572                .await?;
 8573            }
 8574            Request::GetCodeLens(get_code_lens) => {
 8575                Self::query_lsp_locally::<GetCodeLens>(
 8576                    lsp_store,
 8577                    server_id,
 8578                    sender_id,
 8579                    lsp_request_id,
 8580                    get_code_lens,
 8581                    None,
 8582                    &mut cx,
 8583                )
 8584                .await?;
 8585            }
 8586            Request::GetDefinition(get_definition) => {
 8587                let position = get_definition.position.clone().and_then(deserialize_anchor);
 8588                Self::query_lsp_locally::<GetDefinitions>(
 8589                    lsp_store,
 8590                    server_id,
 8591                    sender_id,
 8592                    lsp_request_id,
 8593                    get_definition,
 8594                    position,
 8595                    &mut cx,
 8596                )
 8597                .await?;
 8598            }
 8599            Request::GetDeclaration(get_declaration) => {
 8600                let position = get_declaration
 8601                    .position
 8602                    .clone()
 8603                    .and_then(deserialize_anchor);
 8604                Self::query_lsp_locally::<GetDeclarations>(
 8605                    lsp_store,
 8606                    server_id,
 8607                    sender_id,
 8608                    lsp_request_id,
 8609                    get_declaration,
 8610                    position,
 8611                    &mut cx,
 8612                )
 8613                .await?;
 8614            }
 8615            Request::GetTypeDefinition(get_type_definition) => {
 8616                let position = get_type_definition
 8617                    .position
 8618                    .clone()
 8619                    .and_then(deserialize_anchor);
 8620                Self::query_lsp_locally::<GetTypeDefinitions>(
 8621                    lsp_store,
 8622                    server_id,
 8623                    sender_id,
 8624                    lsp_request_id,
 8625                    get_type_definition,
 8626                    position,
 8627                    &mut cx,
 8628                )
 8629                .await?;
 8630            }
 8631            Request::GetImplementation(get_implementation) => {
 8632                let position = get_implementation
 8633                    .position
 8634                    .clone()
 8635                    .and_then(deserialize_anchor);
 8636                Self::query_lsp_locally::<GetImplementations>(
 8637                    lsp_store,
 8638                    server_id,
 8639                    sender_id,
 8640                    lsp_request_id,
 8641                    get_implementation,
 8642                    position,
 8643                    &mut cx,
 8644                )
 8645                .await?;
 8646            }
 8647            Request::GetDocumentDiagnostics(get_document_diagnostics) => {
 8648                let buffer_id = BufferId::new(get_document_diagnostics.buffer_id())?;
 8649                let version = deserialize_version(get_document_diagnostics.buffer_version());
 8650                let buffer = lsp_store.update(&mut cx, |this, cx| {
 8651                    this.buffer_store.read(cx).get_existing(buffer_id)
 8652                })??;
 8653                buffer
 8654                    .update(&mut cx, |buffer, _| {
 8655                        buffer.wait_for_version(version.clone())
 8656                    })?
 8657                    .await?;
 8658                lsp_store.update(&mut cx, |lsp_store, cx| {
 8659                    let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
 8660                    let key = LspKey {
 8661                        request_type: TypeId::of::<GetDocumentDiagnostics>(),
 8662                        server_queried: server_id,
 8663                    };
 8664                    if <GetDocumentDiagnostics as LspCommand>::ProtoRequest::stop_previous_requests(
 8665                    ) {
 8666                        if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
 8667                            lsp_requests.clear();
 8668                        };
 8669                    }
 8670
 8671                    let existing_queries = lsp_data.lsp_requests.entry(key).or_default();
 8672                    existing_queries.insert(
 8673                        lsp_request_id,
 8674                        cx.spawn(async move |lsp_store, cx| {
 8675                            let diagnostics_pull = lsp_store
 8676                                .update(cx, |lsp_store, cx| {
 8677                                    lsp_store.pull_diagnostics_for_buffer(buffer, cx)
 8678                                })
 8679                                .ok();
 8680                            if let Some(diagnostics_pull) = diagnostics_pull {
 8681                                match diagnostics_pull.await {
 8682                                    Ok(()) => {}
 8683                                    Err(e) => log::error!("Failed to pull diagnostics: {e:#}"),
 8684                                };
 8685                            }
 8686                        }),
 8687                    );
 8688                })?;
 8689            }
 8690            Request::InlayHints(inlay_hints) => {
 8691                let query_start = inlay_hints
 8692                    .start
 8693                    .clone()
 8694                    .and_then(deserialize_anchor)
 8695                    .context("invalid inlay hints range start")?;
 8696                let query_end = inlay_hints
 8697                    .end
 8698                    .clone()
 8699                    .and_then(deserialize_anchor)
 8700                    .context("invalid inlay hints range end")?;
 8701                Self::deduplicate_range_based_lsp_requests::<InlayHints>(
 8702                    &lsp_store,
 8703                    server_id,
 8704                    lsp_request_id,
 8705                    &inlay_hints,
 8706                    query_start..query_end,
 8707                    &mut cx,
 8708                )
 8709                .await
 8710                .context("preparing inlay hints request")?;
 8711                Self::query_lsp_locally::<InlayHints>(
 8712                    lsp_store,
 8713                    server_id,
 8714                    sender_id,
 8715                    lsp_request_id,
 8716                    inlay_hints,
 8717                    None,
 8718                    &mut cx,
 8719                )
 8720                .await
 8721                .context("querying for inlay hints")?
 8722            }
 8723        }
 8724        Ok(proto::Ack {})
 8725    }
 8726
 8727    async fn handle_lsp_query_response(
 8728        lsp_store: Entity<Self>,
 8729        envelope: TypedEnvelope<proto::LspQueryResponse>,
 8730        cx: AsyncApp,
 8731    ) -> Result<()> {
 8732        lsp_store.read_with(&cx, |lsp_store, _| {
 8733            if let Some((upstream_client, _)) = lsp_store.upstream_client() {
 8734                upstream_client.handle_lsp_response(envelope.clone());
 8735            }
 8736        })?;
 8737        Ok(())
 8738    }
 8739
 8740    async fn handle_apply_code_action(
 8741        this: Entity<Self>,
 8742        envelope: TypedEnvelope<proto::ApplyCodeAction>,
 8743        mut cx: AsyncApp,
 8744    ) -> Result<proto::ApplyCodeActionResponse> {
 8745        let sender_id = envelope.original_sender_id().unwrap_or_default();
 8746        let action =
 8747            Self::deserialize_code_action(envelope.payload.action.context("invalid action")?)?;
 8748        let apply_code_action = this.update(&mut cx, |this, cx| {
 8749            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8750            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 8751            anyhow::Ok(this.apply_code_action(buffer, action, false, cx))
 8752        })??;
 8753
 8754        let project_transaction = apply_code_action.await?;
 8755        let project_transaction = this.update(&mut cx, |this, cx| {
 8756            this.buffer_store.update(cx, |buffer_store, cx| {
 8757                buffer_store.serialize_project_transaction_for_peer(
 8758                    project_transaction,
 8759                    sender_id,
 8760                    cx,
 8761                )
 8762            })
 8763        })?;
 8764        Ok(proto::ApplyCodeActionResponse {
 8765            transaction: Some(project_transaction),
 8766        })
 8767    }
 8768
 8769    async fn handle_register_buffer_with_language_servers(
 8770        this: Entity<Self>,
 8771        envelope: TypedEnvelope<proto::RegisterBufferWithLanguageServers>,
 8772        mut cx: AsyncApp,
 8773    ) -> Result<proto::Ack> {
 8774        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 8775        let peer_id = envelope.original_sender_id.unwrap_or(envelope.sender_id);
 8776        this.update(&mut cx, |this, cx| {
 8777            if let Some((upstream_client, upstream_project_id)) = this.upstream_client() {
 8778                return upstream_client.send(proto::RegisterBufferWithLanguageServers {
 8779                    project_id: upstream_project_id,
 8780                    buffer_id: buffer_id.to_proto(),
 8781                    only_servers: envelope.payload.only_servers,
 8782                });
 8783            }
 8784
 8785            let Some(buffer) = this.buffer_store().read(cx).get(buffer_id) else {
 8786                anyhow::bail!("buffer is not open");
 8787            };
 8788
 8789            let handle = this.register_buffer_with_language_servers(
 8790                &buffer,
 8791                envelope
 8792                    .payload
 8793                    .only_servers
 8794                    .into_iter()
 8795                    .filter_map(|selector| {
 8796                        Some(match selector.selector? {
 8797                            proto::language_server_selector::Selector::ServerId(server_id) => {
 8798                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
 8799                            }
 8800                            proto::language_server_selector::Selector::Name(name) => {
 8801                                LanguageServerSelector::Name(LanguageServerName(
 8802                                    SharedString::from(name),
 8803                                ))
 8804                            }
 8805                        })
 8806                    })
 8807                    .collect(),
 8808                false,
 8809                cx,
 8810            );
 8811            this.buffer_store().update(cx, |buffer_store, _| {
 8812                buffer_store.register_shared_lsp_handle(peer_id, buffer_id, handle);
 8813            });
 8814
 8815            Ok(())
 8816        })??;
 8817        Ok(proto::Ack {})
 8818    }
 8819
 8820    async fn handle_rename_project_entry(
 8821        this: Entity<Self>,
 8822        envelope: TypedEnvelope<proto::RenameProjectEntry>,
 8823        mut cx: AsyncApp,
 8824    ) -> Result<proto::ProjectEntryResponse> {
 8825        let entry_id = ProjectEntryId::from_proto(envelope.payload.entry_id);
 8826        let new_worktree_id = WorktreeId::from_proto(envelope.payload.new_worktree_id);
 8827        let new_path =
 8828            RelPath::from_proto(&envelope.payload.new_path).context("invalid relative path")?;
 8829
 8830        let (worktree_store, old_worktree, new_worktree, old_entry) = this
 8831            .update(&mut cx, |this, cx| {
 8832                let (worktree, entry) = this
 8833                    .worktree_store
 8834                    .read(cx)
 8835                    .worktree_and_entry_for_id(entry_id, cx)?;
 8836                let new_worktree = this
 8837                    .worktree_store
 8838                    .read(cx)
 8839                    .worktree_for_id(new_worktree_id, cx)?;
 8840                Some((
 8841                    this.worktree_store.clone(),
 8842                    worktree,
 8843                    new_worktree,
 8844                    entry.clone(),
 8845                ))
 8846            })?
 8847            .context("worktree not found")?;
 8848        let (old_abs_path, old_worktree_id) = old_worktree.read_with(&cx, |worktree, _| {
 8849            (worktree.absolutize(&old_entry.path), worktree.id())
 8850        })?;
 8851        let new_abs_path =
 8852            new_worktree.read_with(&cx, |worktree, _| worktree.absolutize(&new_path))?;
 8853
 8854        let _transaction = Self::will_rename_entry(
 8855            this.downgrade(),
 8856            old_worktree_id,
 8857            &old_abs_path,
 8858            &new_abs_path,
 8859            old_entry.is_dir(),
 8860            cx.clone(),
 8861        )
 8862        .await;
 8863        let response = WorktreeStore::handle_rename_project_entry(
 8864            worktree_store,
 8865            envelope.payload,
 8866            cx.clone(),
 8867        )
 8868        .await;
 8869        this.read_with(&cx, |this, _| {
 8870            this.did_rename_entry(
 8871                old_worktree_id,
 8872                &old_abs_path,
 8873                &new_abs_path,
 8874                old_entry.is_dir(),
 8875            );
 8876        })
 8877        .ok();
 8878        response
 8879    }
 8880
 8881    async fn handle_update_diagnostic_summary(
 8882        this: Entity<Self>,
 8883        envelope: TypedEnvelope<proto::UpdateDiagnosticSummary>,
 8884        mut cx: AsyncApp,
 8885    ) -> Result<()> {
 8886        this.update(&mut cx, |lsp_store, cx| {
 8887            let worktree_id = WorktreeId::from_proto(envelope.payload.worktree_id);
 8888            let mut updated_diagnostics_paths = HashMap::default();
 8889            let mut diagnostics_summary = None::<proto::UpdateDiagnosticSummary>;
 8890            for message_summary in envelope
 8891                .payload
 8892                .summary
 8893                .into_iter()
 8894                .chain(envelope.payload.more_summaries)
 8895            {
 8896                let project_path = ProjectPath {
 8897                    worktree_id,
 8898                    path: RelPath::from_proto(&message_summary.path).context("invalid path")?,
 8899                };
 8900                let path = project_path.path.clone();
 8901                let server_id = LanguageServerId(message_summary.language_server_id as usize);
 8902                let summary = DiagnosticSummary {
 8903                    error_count: message_summary.error_count as usize,
 8904                    warning_count: message_summary.warning_count as usize,
 8905                };
 8906
 8907                if summary.is_empty() {
 8908                    if let Some(worktree_summaries) =
 8909                        lsp_store.diagnostic_summaries.get_mut(&worktree_id)
 8910                        && let Some(summaries) = worktree_summaries.get_mut(&path)
 8911                    {
 8912                        summaries.remove(&server_id);
 8913                        if summaries.is_empty() {
 8914                            worktree_summaries.remove(&path);
 8915                        }
 8916                    }
 8917                } else {
 8918                    lsp_store
 8919                        .diagnostic_summaries
 8920                        .entry(worktree_id)
 8921                        .or_default()
 8922                        .entry(path)
 8923                        .or_default()
 8924                        .insert(server_id, summary);
 8925                }
 8926
 8927                if let Some((_, project_id)) = &lsp_store.downstream_client {
 8928                    match &mut diagnostics_summary {
 8929                        Some(diagnostics_summary) => {
 8930                            diagnostics_summary
 8931                                .more_summaries
 8932                                .push(proto::DiagnosticSummary {
 8933                                    path: project_path.path.as_ref().to_proto(),
 8934                                    language_server_id: server_id.0 as u64,
 8935                                    error_count: summary.error_count as u32,
 8936                                    warning_count: summary.warning_count as u32,
 8937                                })
 8938                        }
 8939                        None => {
 8940                            diagnostics_summary = Some(proto::UpdateDiagnosticSummary {
 8941                                project_id: *project_id,
 8942                                worktree_id: worktree_id.to_proto(),
 8943                                summary: Some(proto::DiagnosticSummary {
 8944                                    path: project_path.path.as_ref().to_proto(),
 8945                                    language_server_id: server_id.0 as u64,
 8946                                    error_count: summary.error_count as u32,
 8947                                    warning_count: summary.warning_count as u32,
 8948                                }),
 8949                                more_summaries: Vec::new(),
 8950                            })
 8951                        }
 8952                    }
 8953                }
 8954                updated_diagnostics_paths
 8955                    .entry(server_id)
 8956                    .or_insert_with(Vec::new)
 8957                    .push(project_path);
 8958            }
 8959
 8960            if let Some((diagnostics_summary, (downstream_client, _))) =
 8961                diagnostics_summary.zip(lsp_store.downstream_client.as_ref())
 8962            {
 8963                downstream_client.send(diagnostics_summary).log_err();
 8964            }
 8965            for (server_id, paths) in updated_diagnostics_paths {
 8966                cx.emit(LspStoreEvent::DiagnosticsUpdated { server_id, paths });
 8967            }
 8968            Ok(())
 8969        })?
 8970    }
 8971
 8972    async fn handle_start_language_server(
 8973        lsp_store: Entity<Self>,
 8974        envelope: TypedEnvelope<proto::StartLanguageServer>,
 8975        mut cx: AsyncApp,
 8976    ) -> Result<()> {
 8977        let server = envelope.payload.server.context("invalid server")?;
 8978        let server_capabilities =
 8979            serde_json::from_str::<lsp::ServerCapabilities>(&envelope.payload.capabilities)
 8980                .with_context(|| {
 8981                    format!(
 8982                        "incorrect server capabilities {}",
 8983                        envelope.payload.capabilities
 8984                    )
 8985                })?;
 8986        lsp_store.update(&mut cx, |lsp_store, cx| {
 8987            let server_id = LanguageServerId(server.id as usize);
 8988            let server_name = LanguageServerName::from_proto(server.name.clone());
 8989            lsp_store
 8990                .lsp_server_capabilities
 8991                .insert(server_id, server_capabilities);
 8992            lsp_store.language_server_statuses.insert(
 8993                server_id,
 8994                LanguageServerStatus {
 8995                    name: server_name.clone(),
 8996                    pending_work: Default::default(),
 8997                    has_pending_diagnostic_updates: false,
 8998                    progress_tokens: Default::default(),
 8999                    worktree: server.worktree_id.map(WorktreeId::from_proto),
 9000                },
 9001            );
 9002            cx.emit(LspStoreEvent::LanguageServerAdded(
 9003                server_id,
 9004                server_name,
 9005                server.worktree_id.map(WorktreeId::from_proto),
 9006            ));
 9007            cx.notify();
 9008        })?;
 9009        Ok(())
 9010    }
 9011
 9012    async fn handle_update_language_server(
 9013        lsp_store: Entity<Self>,
 9014        envelope: TypedEnvelope<proto::UpdateLanguageServer>,
 9015        mut cx: AsyncApp,
 9016    ) -> Result<()> {
 9017        lsp_store.update(&mut cx, |lsp_store, cx| {
 9018            let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9019
 9020            match envelope.payload.variant.context("invalid variant")? {
 9021                proto::update_language_server::Variant::WorkStart(payload) => {
 9022                    lsp_store.on_lsp_work_start(
 9023                        language_server_id,
 9024                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9025                            .context("invalid progress token value")?,
 9026                        LanguageServerProgress {
 9027                            title: payload.title,
 9028                            is_disk_based_diagnostics_progress: false,
 9029                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9030                            message: payload.message,
 9031                            percentage: payload.percentage.map(|p| p as usize),
 9032                            last_update_at: cx.background_executor().now(),
 9033                        },
 9034                        cx,
 9035                    );
 9036                }
 9037                proto::update_language_server::Variant::WorkProgress(payload) => {
 9038                    lsp_store.on_lsp_work_progress(
 9039                        language_server_id,
 9040                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9041                            .context("invalid progress token value")?,
 9042                        LanguageServerProgress {
 9043                            title: None,
 9044                            is_disk_based_diagnostics_progress: false,
 9045                            is_cancellable: payload.is_cancellable.unwrap_or(false),
 9046                            message: payload.message,
 9047                            percentage: payload.percentage.map(|p| p as usize),
 9048                            last_update_at: cx.background_executor().now(),
 9049                        },
 9050                        cx,
 9051                    );
 9052                }
 9053
 9054                proto::update_language_server::Variant::WorkEnd(payload) => {
 9055                    lsp_store.on_lsp_work_end(
 9056                        language_server_id,
 9057                        ProgressToken::from_proto(payload.token.context("missing progress token")?)
 9058                            .context("invalid progress token value")?,
 9059                        cx,
 9060                    );
 9061                }
 9062
 9063                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => {
 9064                    lsp_store.disk_based_diagnostics_started(language_server_id, cx);
 9065                }
 9066
 9067                proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => {
 9068                    lsp_store.disk_based_diagnostics_finished(language_server_id, cx)
 9069                }
 9070
 9071                non_lsp @ proto::update_language_server::Variant::StatusUpdate(_)
 9072                | non_lsp @ proto::update_language_server::Variant::RegisteredForBuffer(_)
 9073                | non_lsp @ proto::update_language_server::Variant::MetadataUpdated(_) => {
 9074                    cx.emit(LspStoreEvent::LanguageServerUpdate {
 9075                        language_server_id,
 9076                        name: envelope
 9077                            .payload
 9078                            .server_name
 9079                            .map(SharedString::new)
 9080                            .map(LanguageServerName),
 9081                        message: non_lsp,
 9082                    });
 9083                }
 9084            }
 9085
 9086            Ok(())
 9087        })?
 9088    }
 9089
 9090    async fn handle_language_server_log(
 9091        this: Entity<Self>,
 9092        envelope: TypedEnvelope<proto::LanguageServerLog>,
 9093        mut cx: AsyncApp,
 9094    ) -> Result<()> {
 9095        let language_server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9096        let log_type = envelope
 9097            .payload
 9098            .log_type
 9099            .map(LanguageServerLogType::from_proto)
 9100            .context("invalid language server log type")?;
 9101
 9102        let message = envelope.payload.message;
 9103
 9104        this.update(&mut cx, |_, cx| {
 9105            cx.emit(LspStoreEvent::LanguageServerLog(
 9106                language_server_id,
 9107                log_type,
 9108                message,
 9109            ));
 9110        })
 9111    }
 9112
 9113    async fn handle_lsp_ext_cancel_flycheck(
 9114        lsp_store: Entity<Self>,
 9115        envelope: TypedEnvelope<proto::LspExtCancelFlycheck>,
 9116        cx: AsyncApp,
 9117    ) -> Result<proto::Ack> {
 9118        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9119        let task = lsp_store.read_with(&cx, |lsp_store, _| {
 9120            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9121                Some(server.notify::<lsp_store::lsp_ext_command::LspExtCancelFlycheck>(()))
 9122            } else {
 9123                None
 9124            }
 9125        })?;
 9126        if let Some(task) = task {
 9127            task.context("handling lsp ext cancel flycheck")?;
 9128        }
 9129
 9130        Ok(proto::Ack {})
 9131    }
 9132
 9133    async fn handle_lsp_ext_run_flycheck(
 9134        lsp_store: Entity<Self>,
 9135        envelope: TypedEnvelope<proto::LspExtRunFlycheck>,
 9136        mut cx: AsyncApp,
 9137    ) -> Result<proto::Ack> {
 9138        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9139        lsp_store.update(&mut cx, |lsp_store, cx| {
 9140            if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9141                let text_document = if envelope.payload.current_file_only {
 9142                    let buffer_id = envelope
 9143                        .payload
 9144                        .buffer_id
 9145                        .map(|id| BufferId::new(id))
 9146                        .transpose()?;
 9147                    buffer_id
 9148                        .and_then(|buffer_id| {
 9149                            lsp_store
 9150                                .buffer_store()
 9151                                .read(cx)
 9152                                .get(buffer_id)
 9153                                .and_then(|buffer| {
 9154                                    Some(buffer.read(cx).file()?.as_local()?.abs_path(cx))
 9155                                })
 9156                                .map(|path| make_text_document_identifier(&path))
 9157                        })
 9158                        .transpose()?
 9159                } else {
 9160                    None
 9161                };
 9162                server.notify::<lsp_store::lsp_ext_command::LspExtRunFlycheck>(
 9163                    lsp_store::lsp_ext_command::RunFlycheckParams { text_document },
 9164                )?;
 9165            }
 9166            anyhow::Ok(())
 9167        })??;
 9168
 9169        Ok(proto::Ack {})
 9170    }
 9171
 9172    async fn handle_lsp_ext_clear_flycheck(
 9173        lsp_store: Entity<Self>,
 9174        envelope: TypedEnvelope<proto::LspExtClearFlycheck>,
 9175        cx: AsyncApp,
 9176    ) -> Result<proto::Ack> {
 9177        let server_id = LanguageServerId(envelope.payload.language_server_id as usize);
 9178        lsp_store
 9179            .read_with(&cx, |lsp_store, _| {
 9180                if let Some(server) = lsp_store.language_server_for_id(server_id) {
 9181                    Some(server.notify::<lsp_store::lsp_ext_command::LspExtClearFlycheck>(()))
 9182                } else {
 9183                    None
 9184                }
 9185            })
 9186            .context("handling lsp ext clear flycheck")?;
 9187
 9188        Ok(proto::Ack {})
 9189    }
 9190
 9191    pub fn disk_based_diagnostics_started(
 9192        &mut self,
 9193        language_server_id: LanguageServerId,
 9194        cx: &mut Context<Self>,
 9195    ) {
 9196        if let Some(language_server_status) =
 9197            self.language_server_statuses.get_mut(&language_server_id)
 9198        {
 9199            language_server_status.has_pending_diagnostic_updates = true;
 9200        }
 9201
 9202        cx.emit(LspStoreEvent::DiskBasedDiagnosticsStarted { language_server_id });
 9203        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9204            language_server_id,
 9205            name: self
 9206                .language_server_adapter_for_id(language_server_id)
 9207                .map(|adapter| adapter.name()),
 9208            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(
 9209                Default::default(),
 9210            ),
 9211        })
 9212    }
 9213
 9214    pub fn disk_based_diagnostics_finished(
 9215        &mut self,
 9216        language_server_id: LanguageServerId,
 9217        cx: &mut Context<Self>,
 9218    ) {
 9219        if let Some(language_server_status) =
 9220            self.language_server_statuses.get_mut(&language_server_id)
 9221        {
 9222            language_server_status.has_pending_diagnostic_updates = false;
 9223        }
 9224
 9225        cx.emit(LspStoreEvent::DiskBasedDiagnosticsFinished { language_server_id });
 9226        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9227            language_server_id,
 9228            name: self
 9229                .language_server_adapter_for_id(language_server_id)
 9230                .map(|adapter| adapter.name()),
 9231            message: proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(
 9232                Default::default(),
 9233            ),
 9234        })
 9235    }
 9236
 9237    // After saving a buffer using a language server that doesn't provide a disk-based progress token,
 9238    // kick off a timer that will reset every time the buffer is saved. If the timer eventually fires,
 9239    // simulate disk-based diagnostics being finished so that other pieces of UI (e.g., project
 9240    // diagnostics view, diagnostic status bar) can update. We don't emit an event right away because
 9241    // the language server might take some time to publish diagnostics.
 9242    fn simulate_disk_based_diagnostics_events_if_needed(
 9243        &mut self,
 9244        language_server_id: LanguageServerId,
 9245        cx: &mut Context<Self>,
 9246    ) {
 9247        const DISK_BASED_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_secs(1);
 9248
 9249        let Some(LanguageServerState::Running {
 9250            simulate_disk_based_diagnostics_completion,
 9251            adapter,
 9252            ..
 9253        }) = self
 9254            .as_local_mut()
 9255            .and_then(|local_store| local_store.language_servers.get_mut(&language_server_id))
 9256        else {
 9257            return;
 9258        };
 9259
 9260        if adapter.disk_based_diagnostics_progress_token.is_some() {
 9261            return;
 9262        }
 9263
 9264        let prev_task =
 9265            simulate_disk_based_diagnostics_completion.replace(cx.spawn(async move |this, cx| {
 9266                cx.background_executor()
 9267                    .timer(DISK_BASED_DIAGNOSTICS_DEBOUNCE)
 9268                    .await;
 9269
 9270                this.update(cx, |this, cx| {
 9271                    this.disk_based_diagnostics_finished(language_server_id, cx);
 9272
 9273                    if let Some(LanguageServerState::Running {
 9274                        simulate_disk_based_diagnostics_completion,
 9275                        ..
 9276                    }) = this.as_local_mut().and_then(|local_store| {
 9277                        local_store.language_servers.get_mut(&language_server_id)
 9278                    }) {
 9279                        *simulate_disk_based_diagnostics_completion = None;
 9280                    }
 9281                })
 9282                .ok();
 9283            }));
 9284
 9285        if prev_task.is_none() {
 9286            self.disk_based_diagnostics_started(language_server_id, cx);
 9287        }
 9288    }
 9289
 9290    pub fn language_server_statuses(
 9291        &self,
 9292    ) -> impl DoubleEndedIterator<Item = (LanguageServerId, &LanguageServerStatus)> {
 9293        self.language_server_statuses
 9294            .iter()
 9295            .map(|(key, value)| (*key, value))
 9296    }
 9297
 9298    pub(super) fn did_rename_entry(
 9299        &self,
 9300        worktree_id: WorktreeId,
 9301        old_path: &Path,
 9302        new_path: &Path,
 9303        is_dir: bool,
 9304    ) {
 9305        maybe!({
 9306            let local_store = self.as_local()?;
 9307
 9308            let old_uri = lsp::Uri::from_file_path(old_path)
 9309                .ok()
 9310                .map(|uri| uri.to_string())?;
 9311            let new_uri = lsp::Uri::from_file_path(new_path)
 9312                .ok()
 9313                .map(|uri| uri.to_string())?;
 9314
 9315            for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9316                let Some(filter) = local_store
 9317                    .language_server_paths_watched_for_rename
 9318                    .get(&language_server.server_id())
 9319                else {
 9320                    continue;
 9321                };
 9322
 9323                if filter.should_send_did_rename(&old_uri, is_dir) {
 9324                    language_server
 9325                        .notify::<DidRenameFiles>(RenameFilesParams {
 9326                            files: vec![FileRename {
 9327                                old_uri: old_uri.clone(),
 9328                                new_uri: new_uri.clone(),
 9329                            }],
 9330                        })
 9331                        .ok();
 9332                }
 9333            }
 9334            Some(())
 9335        });
 9336    }
 9337
 9338    pub(super) fn will_rename_entry(
 9339        this: WeakEntity<Self>,
 9340        worktree_id: WorktreeId,
 9341        old_path: &Path,
 9342        new_path: &Path,
 9343        is_dir: bool,
 9344        cx: AsyncApp,
 9345    ) -> Task<ProjectTransaction> {
 9346        let old_uri = lsp::Uri::from_file_path(old_path)
 9347            .ok()
 9348            .map(|uri| uri.to_string());
 9349        let new_uri = lsp::Uri::from_file_path(new_path)
 9350            .ok()
 9351            .map(|uri| uri.to_string());
 9352        cx.spawn(async move |cx| {
 9353            let mut tasks = vec![];
 9354            this.update(cx, |this, cx| {
 9355                let local_store = this.as_local()?;
 9356                let old_uri = old_uri?;
 9357                let new_uri = new_uri?;
 9358                for language_server in local_store.language_servers_for_worktree(worktree_id) {
 9359                    let Some(filter) = local_store
 9360                        .language_server_paths_watched_for_rename
 9361                        .get(&language_server.server_id())
 9362                    else {
 9363                        continue;
 9364                    };
 9365
 9366                    if filter.should_send_will_rename(&old_uri, is_dir) {
 9367                        let apply_edit = cx.spawn({
 9368                            let old_uri = old_uri.clone();
 9369                            let new_uri = new_uri.clone();
 9370                            let language_server = language_server.clone();
 9371                            async move |this, cx| {
 9372                                let edit = language_server
 9373                                    .request::<WillRenameFiles>(RenameFilesParams {
 9374                                        files: vec![FileRename { old_uri, new_uri }],
 9375                                    })
 9376                                    .await
 9377                                    .into_response()
 9378                                    .context("will rename files")
 9379                                    .log_err()
 9380                                    .flatten()?;
 9381
 9382                                let transaction = LocalLspStore::deserialize_workspace_edit(
 9383                                    this.upgrade()?,
 9384                                    edit,
 9385                                    false,
 9386                                    language_server.clone(),
 9387                                    cx,
 9388                                )
 9389                                .await
 9390                                .ok()?;
 9391                                Some(transaction)
 9392                            }
 9393                        });
 9394                        tasks.push(apply_edit);
 9395                    }
 9396                }
 9397                Some(())
 9398            })
 9399            .ok()
 9400            .flatten();
 9401            let mut merged_transaction = ProjectTransaction::default();
 9402            for task in tasks {
 9403                // Await on tasks sequentially so that the order of application of edits is deterministic
 9404                // (at least with regards to the order of registration of language servers)
 9405                if let Some(transaction) = task.await {
 9406                    for (buffer, buffer_transaction) in transaction.0 {
 9407                        merged_transaction.0.insert(buffer, buffer_transaction);
 9408                    }
 9409                }
 9410            }
 9411            merged_transaction
 9412        })
 9413    }
 9414
 9415    fn lsp_notify_abs_paths_changed(
 9416        &mut self,
 9417        server_id: LanguageServerId,
 9418        changes: Vec<PathEvent>,
 9419    ) {
 9420        maybe!({
 9421            let server = self.language_server_for_id(server_id)?;
 9422            let changes = changes
 9423                .into_iter()
 9424                .filter_map(|event| {
 9425                    let typ = match event.kind? {
 9426                        PathEventKind::Created => lsp::FileChangeType::CREATED,
 9427                        PathEventKind::Removed => lsp::FileChangeType::DELETED,
 9428                        PathEventKind::Changed => lsp::FileChangeType::CHANGED,
 9429                    };
 9430                    Some(lsp::FileEvent {
 9431                        uri: file_path_to_lsp_url(&event.path).log_err()?,
 9432                        typ,
 9433                    })
 9434                })
 9435                .collect::<Vec<_>>();
 9436            if !changes.is_empty() {
 9437                server
 9438                    .notify::<lsp::notification::DidChangeWatchedFiles>(
 9439                        lsp::DidChangeWatchedFilesParams { changes },
 9440                    )
 9441                    .ok();
 9442            }
 9443            Some(())
 9444        });
 9445    }
 9446
 9447    pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
 9448        self.as_local()?.language_server_for_id(id)
 9449    }
 9450
 9451    fn on_lsp_progress(
 9452        &mut self,
 9453        progress_params: lsp::ProgressParams,
 9454        language_server_id: LanguageServerId,
 9455        disk_based_diagnostics_progress_token: Option<String>,
 9456        cx: &mut Context<Self>,
 9457    ) {
 9458        match progress_params.value {
 9459            lsp::ProgressParamsValue::WorkDone(progress) => {
 9460                self.handle_work_done_progress(
 9461                    progress,
 9462                    language_server_id,
 9463                    disk_based_diagnostics_progress_token,
 9464                    ProgressToken::from_lsp(progress_params.token),
 9465                    cx,
 9466                );
 9467            }
 9468            lsp::ProgressParamsValue::WorkspaceDiagnostic(report) => {
 9469                let identifier = match progress_params.token {
 9470                    lsp::NumberOrString::Number(_) => None,
 9471                    lsp::NumberOrString::String(token) => token
 9472                        .split_once(WORKSPACE_DIAGNOSTICS_TOKEN_START)
 9473                        .map(|(_, id)| id.to_owned()),
 9474                };
 9475                if let Some(LanguageServerState::Running {
 9476                    workspace_diagnostics_refresh_tasks,
 9477                    ..
 9478                }) = self
 9479                    .as_local_mut()
 9480                    .and_then(|local| local.language_servers.get_mut(&language_server_id))
 9481                    && let Some(workspace_diagnostics) =
 9482                        workspace_diagnostics_refresh_tasks.get_mut(&identifier)
 9483                {
 9484                    workspace_diagnostics.progress_tx.try_send(()).ok();
 9485                    self.apply_workspace_diagnostic_report(language_server_id, report, cx)
 9486                }
 9487            }
 9488        }
 9489    }
 9490
 9491    fn handle_work_done_progress(
 9492        &mut self,
 9493        progress: lsp::WorkDoneProgress,
 9494        language_server_id: LanguageServerId,
 9495        disk_based_diagnostics_progress_token: Option<String>,
 9496        token: ProgressToken,
 9497        cx: &mut Context<Self>,
 9498    ) {
 9499        let language_server_status =
 9500            if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9501                status
 9502            } else {
 9503                return;
 9504            };
 9505
 9506        if !language_server_status.progress_tokens.contains(&token) {
 9507            return;
 9508        }
 9509
 9510        let is_disk_based_diagnostics_progress =
 9511            if let (Some(disk_based_token), ProgressToken::String(token)) =
 9512                (&disk_based_diagnostics_progress_token, &token)
 9513            {
 9514                token.starts_with(disk_based_token)
 9515            } else {
 9516                false
 9517            };
 9518
 9519        match progress {
 9520            lsp::WorkDoneProgress::Begin(report) => {
 9521                if is_disk_based_diagnostics_progress {
 9522                    self.disk_based_diagnostics_started(language_server_id, cx);
 9523                }
 9524                self.on_lsp_work_start(
 9525                    language_server_id,
 9526                    token.clone(),
 9527                    LanguageServerProgress {
 9528                        title: Some(report.title),
 9529                        is_disk_based_diagnostics_progress,
 9530                        is_cancellable: report.cancellable.unwrap_or(false),
 9531                        message: report.message.clone(),
 9532                        percentage: report.percentage.map(|p| p as usize),
 9533                        last_update_at: cx.background_executor().now(),
 9534                    },
 9535                    cx,
 9536                );
 9537            }
 9538            lsp::WorkDoneProgress::Report(report) => self.on_lsp_work_progress(
 9539                language_server_id,
 9540                token,
 9541                LanguageServerProgress {
 9542                    title: None,
 9543                    is_disk_based_diagnostics_progress,
 9544                    is_cancellable: report.cancellable.unwrap_or(false),
 9545                    message: report.message,
 9546                    percentage: report.percentage.map(|p| p as usize),
 9547                    last_update_at: cx.background_executor().now(),
 9548                },
 9549                cx,
 9550            ),
 9551            lsp::WorkDoneProgress::End(_) => {
 9552                language_server_status.progress_tokens.remove(&token);
 9553                self.on_lsp_work_end(language_server_id, token.clone(), cx);
 9554                if is_disk_based_diagnostics_progress {
 9555                    self.disk_based_diagnostics_finished(language_server_id, cx);
 9556                }
 9557            }
 9558        }
 9559    }
 9560
 9561    fn on_lsp_work_start(
 9562        &mut self,
 9563        language_server_id: LanguageServerId,
 9564        token: ProgressToken,
 9565        progress: LanguageServerProgress,
 9566        cx: &mut Context<Self>,
 9567    ) {
 9568        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9569            status.pending_work.insert(token.clone(), progress.clone());
 9570            cx.notify();
 9571        }
 9572        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9573            language_server_id,
 9574            name: self
 9575                .language_server_adapter_for_id(language_server_id)
 9576                .map(|adapter| adapter.name()),
 9577            message: proto::update_language_server::Variant::WorkStart(proto::LspWorkStart {
 9578                token: Some(token.to_proto()),
 9579                title: progress.title,
 9580                message: progress.message,
 9581                percentage: progress.percentage.map(|p| p as u32),
 9582                is_cancellable: Some(progress.is_cancellable),
 9583            }),
 9584        })
 9585    }
 9586
 9587    fn on_lsp_work_progress(
 9588        &mut self,
 9589        language_server_id: LanguageServerId,
 9590        token: ProgressToken,
 9591        progress: LanguageServerProgress,
 9592        cx: &mut Context<Self>,
 9593    ) {
 9594        let mut did_update = false;
 9595        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9596            match status.pending_work.entry(token.clone()) {
 9597                btree_map::Entry::Vacant(entry) => {
 9598                    entry.insert(progress.clone());
 9599                    did_update = true;
 9600                }
 9601                btree_map::Entry::Occupied(mut entry) => {
 9602                    let entry = entry.get_mut();
 9603                    if (progress.last_update_at - entry.last_update_at)
 9604                        >= SERVER_PROGRESS_THROTTLE_TIMEOUT
 9605                    {
 9606                        entry.last_update_at = progress.last_update_at;
 9607                        if progress.message.is_some() {
 9608                            entry.message = progress.message.clone();
 9609                        }
 9610                        if progress.percentage.is_some() {
 9611                            entry.percentage = progress.percentage;
 9612                        }
 9613                        if progress.is_cancellable != entry.is_cancellable {
 9614                            entry.is_cancellable = progress.is_cancellable;
 9615                        }
 9616                        did_update = true;
 9617                    }
 9618                }
 9619            }
 9620        }
 9621
 9622        if did_update {
 9623            cx.emit(LspStoreEvent::LanguageServerUpdate {
 9624                language_server_id,
 9625                name: self
 9626                    .language_server_adapter_for_id(language_server_id)
 9627                    .map(|adapter| adapter.name()),
 9628                message: proto::update_language_server::Variant::WorkProgress(
 9629                    proto::LspWorkProgress {
 9630                        token: Some(token.to_proto()),
 9631                        message: progress.message,
 9632                        percentage: progress.percentage.map(|p| p as u32),
 9633                        is_cancellable: Some(progress.is_cancellable),
 9634                    },
 9635                ),
 9636            })
 9637        }
 9638    }
 9639
 9640    fn on_lsp_work_end(
 9641        &mut self,
 9642        language_server_id: LanguageServerId,
 9643        token: ProgressToken,
 9644        cx: &mut Context<Self>,
 9645    ) {
 9646        if let Some(status) = self.language_server_statuses.get_mut(&language_server_id) {
 9647            if let Some(work) = status.pending_work.remove(&token)
 9648                && !work.is_disk_based_diagnostics_progress
 9649            {
 9650                cx.emit(LspStoreEvent::RefreshInlayHints {
 9651                    server_id: language_server_id,
 9652                    request_id: None,
 9653                });
 9654            }
 9655            cx.notify();
 9656        }
 9657
 9658        cx.emit(LspStoreEvent::LanguageServerUpdate {
 9659            language_server_id,
 9660            name: self
 9661                .language_server_adapter_for_id(language_server_id)
 9662                .map(|adapter| adapter.name()),
 9663            message: proto::update_language_server::Variant::WorkEnd(proto::LspWorkEnd {
 9664                token: Some(token.to_proto()),
 9665            }),
 9666        })
 9667    }
 9668
 9669    pub async fn handle_resolve_completion_documentation(
 9670        this: Entity<Self>,
 9671        envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
 9672        mut cx: AsyncApp,
 9673    ) -> Result<proto::ResolveCompletionDocumentationResponse> {
 9674        let lsp_completion = serde_json::from_slice(&envelope.payload.lsp_completion)?;
 9675
 9676        let completion = this
 9677            .read_with(&cx, |this, cx| {
 9678                let id = LanguageServerId(envelope.payload.language_server_id as usize);
 9679                let server = this
 9680                    .language_server_for_id(id)
 9681                    .with_context(|| format!("No language server {id}"))?;
 9682
 9683                anyhow::Ok(cx.background_spawn(async move {
 9684                    let can_resolve = server
 9685                        .capabilities()
 9686                        .completion_provider
 9687                        .as_ref()
 9688                        .and_then(|options| options.resolve_provider)
 9689                        .unwrap_or(false);
 9690                    if can_resolve {
 9691                        server
 9692                            .request::<lsp::request::ResolveCompletionItem>(lsp_completion)
 9693                            .await
 9694                            .into_response()
 9695                            .context("resolve completion item")
 9696                    } else {
 9697                        anyhow::Ok(lsp_completion)
 9698                    }
 9699                }))
 9700            })??
 9701            .await?;
 9702
 9703        let mut documentation_is_markdown = false;
 9704        let lsp_completion = serde_json::to_string(&completion)?.into_bytes();
 9705        let documentation = match completion.documentation {
 9706            Some(lsp::Documentation::String(text)) => text,
 9707
 9708            Some(lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value })) => {
 9709                documentation_is_markdown = kind == lsp::MarkupKind::Markdown;
 9710                value
 9711            }
 9712
 9713            _ => String::new(),
 9714        };
 9715
 9716        // If we have a new buffer_id, that means we're talking to a new client
 9717        // and want to check for new text_edits in the completion too.
 9718        let mut old_replace_start = None;
 9719        let mut old_replace_end = None;
 9720        let mut old_insert_start = None;
 9721        let mut old_insert_end = None;
 9722        let mut new_text = String::default();
 9723        if let Ok(buffer_id) = BufferId::new(envelope.payload.buffer_id) {
 9724            let buffer_snapshot = this.update(&mut cx, |this, cx| {
 9725                let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9726                anyhow::Ok(buffer.read(cx).snapshot())
 9727            })??;
 9728
 9729            if let Some(text_edit) = completion.text_edit.as_ref() {
 9730                let edit = parse_completion_text_edit(text_edit, &buffer_snapshot);
 9731
 9732                if let Some(mut edit) = edit {
 9733                    LineEnding::normalize(&mut edit.new_text);
 9734
 9735                    new_text = edit.new_text;
 9736                    old_replace_start = Some(serialize_anchor(&edit.replace_range.start));
 9737                    old_replace_end = Some(serialize_anchor(&edit.replace_range.end));
 9738                    if let Some(insert_range) = edit.insert_range {
 9739                        old_insert_start = Some(serialize_anchor(&insert_range.start));
 9740                        old_insert_end = Some(serialize_anchor(&insert_range.end));
 9741                    }
 9742                }
 9743            }
 9744        }
 9745
 9746        Ok(proto::ResolveCompletionDocumentationResponse {
 9747            documentation,
 9748            documentation_is_markdown,
 9749            old_replace_start,
 9750            old_replace_end,
 9751            new_text,
 9752            lsp_completion,
 9753            old_insert_start,
 9754            old_insert_end,
 9755        })
 9756    }
 9757
 9758    async fn handle_on_type_formatting(
 9759        this: Entity<Self>,
 9760        envelope: TypedEnvelope<proto::OnTypeFormatting>,
 9761        mut cx: AsyncApp,
 9762    ) -> Result<proto::OnTypeFormattingResponse> {
 9763        let on_type_formatting = this.update(&mut cx, |this, cx| {
 9764            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9765            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
 9766            let position = envelope
 9767                .payload
 9768                .position
 9769                .and_then(deserialize_anchor)
 9770                .context("invalid position")?;
 9771            anyhow::Ok(this.apply_on_type_formatting(
 9772                buffer,
 9773                position,
 9774                envelope.payload.trigger.clone(),
 9775                cx,
 9776            ))
 9777        })??;
 9778
 9779        let transaction = on_type_formatting
 9780            .await?
 9781            .as_ref()
 9782            .map(language::proto::serialize_transaction);
 9783        Ok(proto::OnTypeFormattingResponse { transaction })
 9784    }
 9785
 9786    async fn handle_refresh_inlay_hints(
 9787        lsp_store: Entity<Self>,
 9788        envelope: TypedEnvelope<proto::RefreshInlayHints>,
 9789        mut cx: AsyncApp,
 9790    ) -> Result<proto::Ack> {
 9791        lsp_store.update(&mut cx, |_, cx| {
 9792            cx.emit(LspStoreEvent::RefreshInlayHints {
 9793                server_id: LanguageServerId::from_proto(envelope.payload.server_id),
 9794                request_id: envelope.payload.request_id.map(|id| id as usize),
 9795            });
 9796        })?;
 9797        Ok(proto::Ack {})
 9798    }
 9799
 9800    async fn handle_pull_workspace_diagnostics(
 9801        lsp_store: Entity<Self>,
 9802        envelope: TypedEnvelope<proto::PullWorkspaceDiagnostics>,
 9803        mut cx: AsyncApp,
 9804    ) -> Result<proto::Ack> {
 9805        let server_id = LanguageServerId::from_proto(envelope.payload.server_id);
 9806        lsp_store.update(&mut cx, |lsp_store, _| {
 9807            lsp_store.pull_workspace_diagnostics(server_id);
 9808        })?;
 9809        Ok(proto::Ack {})
 9810    }
 9811
 9812    async fn handle_get_color_presentation(
 9813        lsp_store: Entity<Self>,
 9814        envelope: TypedEnvelope<proto::GetColorPresentation>,
 9815        mut cx: AsyncApp,
 9816    ) -> Result<proto::GetColorPresentationResponse> {
 9817        let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9818        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9819            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9820        })??;
 9821
 9822        let color = envelope
 9823            .payload
 9824            .color
 9825            .context("invalid color resolve request")?;
 9826        let start = color
 9827            .lsp_range_start
 9828            .context("invalid color resolve request")?;
 9829        let end = color
 9830            .lsp_range_end
 9831            .context("invalid color resolve request")?;
 9832
 9833        let color = DocumentColor {
 9834            lsp_range: lsp::Range {
 9835                start: point_to_lsp(PointUtf16::new(start.row, start.column)),
 9836                end: point_to_lsp(PointUtf16::new(end.row, end.column)),
 9837            },
 9838            color: lsp::Color {
 9839                red: color.red,
 9840                green: color.green,
 9841                blue: color.blue,
 9842                alpha: color.alpha,
 9843            },
 9844            resolved: false,
 9845            color_presentations: Vec::new(),
 9846        };
 9847        let resolved_color = lsp_store
 9848            .update(&mut cx, |lsp_store, cx| {
 9849                lsp_store.resolve_color_presentation(
 9850                    color,
 9851                    buffer.clone(),
 9852                    LanguageServerId(envelope.payload.server_id as usize),
 9853                    cx,
 9854                )
 9855            })?
 9856            .await
 9857            .context("resolving color presentation")?;
 9858
 9859        Ok(proto::GetColorPresentationResponse {
 9860            presentations: resolved_color
 9861                .color_presentations
 9862                .into_iter()
 9863                .map(|presentation| proto::ColorPresentation {
 9864                    label: presentation.label.to_string(),
 9865                    text_edit: presentation.text_edit.map(serialize_lsp_edit),
 9866                    additional_text_edits: presentation
 9867                        .additional_text_edits
 9868                        .into_iter()
 9869                        .map(serialize_lsp_edit)
 9870                        .collect(),
 9871                })
 9872                .collect(),
 9873        })
 9874    }
 9875
 9876    async fn handle_resolve_inlay_hint(
 9877        lsp_store: Entity<Self>,
 9878        envelope: TypedEnvelope<proto::ResolveInlayHint>,
 9879        mut cx: AsyncApp,
 9880    ) -> Result<proto::ResolveInlayHintResponse> {
 9881        let proto_hint = envelope
 9882            .payload
 9883            .hint
 9884            .expect("incorrect protobuf resolve inlay hint message: missing the inlay hint");
 9885        let hint = InlayHints::proto_to_project_hint(proto_hint)
 9886            .context("resolved proto inlay hint conversion")?;
 9887        let buffer = lsp_store.update(&mut cx, |lsp_store, cx| {
 9888            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
 9889            lsp_store.buffer_store.read(cx).get_existing(buffer_id)
 9890        })??;
 9891        let response_hint = lsp_store
 9892            .update(&mut cx, |lsp_store, cx| {
 9893                lsp_store.resolve_inlay_hint(
 9894                    hint,
 9895                    buffer,
 9896                    LanguageServerId(envelope.payload.language_server_id as usize),
 9897                    cx,
 9898                )
 9899            })?
 9900            .await
 9901            .context("inlay hints fetch")?;
 9902        Ok(proto::ResolveInlayHintResponse {
 9903            hint: Some(InlayHints::project_to_proto_hint(response_hint)),
 9904        })
 9905    }
 9906
 9907    async fn handle_refresh_code_lens(
 9908        this: Entity<Self>,
 9909        _: TypedEnvelope<proto::RefreshCodeLens>,
 9910        mut cx: AsyncApp,
 9911    ) -> Result<proto::Ack> {
 9912        this.update(&mut cx, |_, cx| {
 9913            cx.emit(LspStoreEvent::RefreshCodeLens);
 9914        })?;
 9915        Ok(proto::Ack {})
 9916    }
 9917
 9918    async fn handle_open_buffer_for_symbol(
 9919        this: Entity<Self>,
 9920        envelope: TypedEnvelope<proto::OpenBufferForSymbol>,
 9921        mut cx: AsyncApp,
 9922    ) -> Result<proto::OpenBufferForSymbolResponse> {
 9923        let peer_id = envelope.original_sender_id().unwrap_or_default();
 9924        let symbol = envelope.payload.symbol.context("invalid symbol")?;
 9925        let symbol = Self::deserialize_symbol(symbol)?;
 9926        this.read_with(&cx, |this, _| {
 9927            if let SymbolLocation::OutsideProject {
 9928                abs_path,
 9929                signature,
 9930            } = &symbol.path
 9931            {
 9932                let new_signature = this.symbol_signature(&abs_path);
 9933                anyhow::ensure!(&new_signature == signature, "invalid symbol signature");
 9934            }
 9935            Ok(())
 9936        })??;
 9937        let buffer = this
 9938            .update(&mut cx, |this, cx| {
 9939                this.open_buffer_for_symbol(
 9940                    &Symbol {
 9941                        language_server_name: symbol.language_server_name,
 9942                        source_worktree_id: symbol.source_worktree_id,
 9943                        source_language_server_id: symbol.source_language_server_id,
 9944                        path: symbol.path,
 9945                        name: symbol.name,
 9946                        kind: symbol.kind,
 9947                        range: symbol.range,
 9948                        label: CodeLabel::default(),
 9949                    },
 9950                    cx,
 9951                )
 9952            })?
 9953            .await?;
 9954
 9955        this.update(&mut cx, |this, cx| {
 9956            let is_private = buffer
 9957                .read(cx)
 9958                .file()
 9959                .map(|f| f.is_private())
 9960                .unwrap_or_default();
 9961            if is_private {
 9962                Err(anyhow!(rpc::ErrorCode::UnsharedItem))
 9963            } else {
 9964                this.buffer_store
 9965                    .update(cx, |buffer_store, cx| {
 9966                        buffer_store.create_buffer_for_peer(&buffer, peer_id, cx)
 9967                    })
 9968                    .detach_and_log_err(cx);
 9969                let buffer_id = buffer.read(cx).remote_id().to_proto();
 9970                Ok(proto::OpenBufferForSymbolResponse { buffer_id })
 9971            }
 9972        })?
 9973    }
 9974
 9975    fn symbol_signature(&self, abs_path: &Path) -> [u8; 32] {
 9976        let mut hasher = Sha256::new();
 9977        hasher.update(abs_path.to_string_lossy().as_bytes());
 9978        hasher.update(self.nonce.to_be_bytes());
 9979        hasher.finalize().as_slice().try_into().unwrap()
 9980    }
 9981
 9982    pub async fn handle_get_project_symbols(
 9983        this: Entity<Self>,
 9984        envelope: TypedEnvelope<proto::GetProjectSymbols>,
 9985        mut cx: AsyncApp,
 9986    ) -> Result<proto::GetProjectSymbolsResponse> {
 9987        let symbols = this
 9988            .update(&mut cx, |this, cx| {
 9989                this.symbols(&envelope.payload.query, cx)
 9990            })?
 9991            .await?;
 9992
 9993        Ok(proto::GetProjectSymbolsResponse {
 9994            symbols: symbols.iter().map(Self::serialize_symbol).collect(),
 9995        })
 9996    }
 9997
 9998    pub async fn handle_restart_language_servers(
 9999        this: Entity<Self>,
10000        envelope: TypedEnvelope<proto::RestartLanguageServers>,
10001        mut cx: AsyncApp,
10002    ) -> Result<proto::Ack> {
10003        this.update(&mut cx, |lsp_store, cx| {
10004            let buffers =
10005                lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10006            lsp_store.restart_language_servers_for_buffers(
10007                buffers,
10008                envelope
10009                    .payload
10010                    .only_servers
10011                    .into_iter()
10012                    .filter_map(|selector| {
10013                        Some(match selector.selector? {
10014                            proto::language_server_selector::Selector::ServerId(server_id) => {
10015                                LanguageServerSelector::Id(LanguageServerId::from_proto(server_id))
10016                            }
10017                            proto::language_server_selector::Selector::Name(name) => {
10018                                LanguageServerSelector::Name(LanguageServerName(
10019                                    SharedString::from(name),
10020                                ))
10021                            }
10022                        })
10023                    })
10024                    .collect(),
10025                cx,
10026            );
10027        })?;
10028
10029        Ok(proto::Ack {})
10030    }
10031
10032    pub async fn handle_stop_language_servers(
10033        lsp_store: Entity<Self>,
10034        envelope: TypedEnvelope<proto::StopLanguageServers>,
10035        mut cx: AsyncApp,
10036    ) -> Result<proto::Ack> {
10037        lsp_store.update(&mut cx, |lsp_store, cx| {
10038            if envelope.payload.all
10039                && envelope.payload.also_servers.is_empty()
10040                && envelope.payload.buffer_ids.is_empty()
10041            {
10042                lsp_store.stop_all_language_servers(cx);
10043            } else {
10044                let buffers =
10045                    lsp_store.buffer_ids_to_buffers(envelope.payload.buffer_ids.into_iter(), cx);
10046                lsp_store
10047                    .stop_language_servers_for_buffers(
10048                        buffers,
10049                        envelope
10050                            .payload
10051                            .also_servers
10052                            .into_iter()
10053                            .filter_map(|selector| {
10054                                Some(match selector.selector? {
10055                                    proto::language_server_selector::Selector::ServerId(
10056                                        server_id,
10057                                    ) => LanguageServerSelector::Id(LanguageServerId::from_proto(
10058                                        server_id,
10059                                    )),
10060                                    proto::language_server_selector::Selector::Name(name) => {
10061                                        LanguageServerSelector::Name(LanguageServerName(
10062                                            SharedString::from(name),
10063                                        ))
10064                                    }
10065                                })
10066                            })
10067                            .collect(),
10068                        cx,
10069                    )
10070                    .detach_and_log_err(cx);
10071            }
10072        })?;
10073
10074        Ok(proto::Ack {})
10075    }
10076
10077    pub async fn handle_cancel_language_server_work(
10078        lsp_store: Entity<Self>,
10079        envelope: TypedEnvelope<proto::CancelLanguageServerWork>,
10080        mut cx: AsyncApp,
10081    ) -> Result<proto::Ack> {
10082        lsp_store.update(&mut cx, |lsp_store, cx| {
10083            if let Some(work) = envelope.payload.work {
10084                match work {
10085                    proto::cancel_language_server_work::Work::Buffers(buffers) => {
10086                        let buffers =
10087                            lsp_store.buffer_ids_to_buffers(buffers.buffer_ids.into_iter(), cx);
10088                        lsp_store.cancel_language_server_work_for_buffers(buffers, cx);
10089                    }
10090                    proto::cancel_language_server_work::Work::LanguageServerWork(work) => {
10091                        let server_id = LanguageServerId::from_proto(work.language_server_id);
10092                        let token = work
10093                            .token
10094                            .map(|token| {
10095                                ProgressToken::from_proto(token)
10096                                    .context("invalid work progress token")
10097                            })
10098                            .transpose()?;
10099                        lsp_store.cancel_language_server_work(server_id, token, cx);
10100                    }
10101                }
10102            }
10103            anyhow::Ok(())
10104        })??;
10105
10106        Ok(proto::Ack {})
10107    }
10108
10109    fn buffer_ids_to_buffers(
10110        &mut self,
10111        buffer_ids: impl Iterator<Item = u64>,
10112        cx: &mut Context<Self>,
10113    ) -> Vec<Entity<Buffer>> {
10114        buffer_ids
10115            .into_iter()
10116            .flat_map(|buffer_id| {
10117                self.buffer_store
10118                    .read(cx)
10119                    .get(BufferId::new(buffer_id).log_err()?)
10120            })
10121            .collect::<Vec<_>>()
10122    }
10123
10124    async fn handle_apply_additional_edits_for_completion(
10125        this: Entity<Self>,
10126        envelope: TypedEnvelope<proto::ApplyCompletionAdditionalEdits>,
10127        mut cx: AsyncApp,
10128    ) -> Result<proto::ApplyCompletionAdditionalEditsResponse> {
10129        let (buffer, completion) = this.update(&mut cx, |this, cx| {
10130            let buffer_id = BufferId::new(envelope.payload.buffer_id)?;
10131            let buffer = this.buffer_store.read(cx).get_existing(buffer_id)?;
10132            let completion = Self::deserialize_completion(
10133                envelope.payload.completion.context("invalid completion")?,
10134            )?;
10135            anyhow::Ok((buffer, completion))
10136        })??;
10137
10138        let apply_additional_edits = this.update(&mut cx, |this, cx| {
10139            this.apply_additional_edits_for_completion(
10140                buffer,
10141                Rc::new(RefCell::new(Box::new([Completion {
10142                    replace_range: completion.replace_range,
10143                    new_text: completion.new_text,
10144                    source: completion.source,
10145                    documentation: None,
10146                    label: CodeLabel::default(),
10147                    insert_text_mode: None,
10148                    icon_path: None,
10149                    confirm: None,
10150                }]))),
10151                0,
10152                false,
10153                cx,
10154            )
10155        })?;
10156
10157        Ok(proto::ApplyCompletionAdditionalEditsResponse {
10158            transaction: apply_additional_edits
10159                .await?
10160                .as_ref()
10161                .map(language::proto::serialize_transaction),
10162        })
10163    }
10164
10165    pub fn last_formatting_failure(&self) -> Option<&str> {
10166        self.last_formatting_failure.as_deref()
10167    }
10168
10169    pub fn reset_last_formatting_failure(&mut self) {
10170        self.last_formatting_failure = None;
10171    }
10172
10173    pub fn environment_for_buffer(
10174        &self,
10175        buffer: &Entity<Buffer>,
10176        cx: &mut Context<Self>,
10177    ) -> Shared<Task<Option<HashMap<String, String>>>> {
10178        if let Some(environment) = &self.as_local().map(|local| local.environment.clone()) {
10179            environment.update(cx, |env, cx| {
10180                env.buffer_environment(buffer, &self.worktree_store, cx)
10181            })
10182        } else {
10183            Task::ready(None).shared()
10184        }
10185    }
10186
10187    pub fn format(
10188        &mut self,
10189        buffers: HashSet<Entity<Buffer>>,
10190        target: LspFormatTarget,
10191        push_to_history: bool,
10192        trigger: FormatTrigger,
10193        cx: &mut Context<Self>,
10194    ) -> Task<anyhow::Result<ProjectTransaction>> {
10195        let logger = zlog::scoped!("format");
10196        if self.as_local().is_some() {
10197            zlog::trace!(logger => "Formatting locally");
10198            let logger = zlog::scoped!(logger => "local");
10199            let buffers = buffers
10200                .into_iter()
10201                .map(|buffer_handle| {
10202                    let buffer = buffer_handle.read(cx);
10203                    let buffer_abs_path = File::from_dyn(buffer.file())
10204                        .and_then(|file| file.as_local().map(|f| f.abs_path(cx)));
10205
10206                    (buffer_handle, buffer_abs_path, buffer.remote_id())
10207                })
10208                .collect::<Vec<_>>();
10209
10210            cx.spawn(async move |lsp_store, cx| {
10211                let mut formattable_buffers = Vec::with_capacity(buffers.len());
10212
10213                for (handle, abs_path, id) in buffers {
10214                    let env = lsp_store
10215                        .update(cx, |lsp_store, cx| {
10216                            lsp_store.environment_for_buffer(&handle, cx)
10217                        })?
10218                        .await;
10219
10220                    let ranges = match &target {
10221                        LspFormatTarget::Buffers => None,
10222                        LspFormatTarget::Ranges(ranges) => {
10223                            Some(ranges.get(&id).context("No format ranges provided for buffer")?.clone())
10224                        }
10225                    };
10226
10227                    formattable_buffers.push(FormattableBuffer {
10228                        handle,
10229                        abs_path,
10230                        env,
10231                        ranges,
10232                    });
10233                }
10234                zlog::trace!(logger => "Formatting {:?} buffers", formattable_buffers.len());
10235
10236                let format_timer = zlog::time!(logger => "Formatting buffers");
10237                let result = LocalLspStore::format_locally(
10238                    lsp_store.clone(),
10239                    formattable_buffers,
10240                    push_to_history,
10241                    trigger,
10242                    logger,
10243                    cx,
10244                )
10245                .await;
10246                format_timer.end();
10247
10248                zlog::trace!(logger => "Formatting completed with result {:?}", result.as_ref().map(|_| "<project-transaction>"));
10249
10250                lsp_store.update(cx, |lsp_store, _| {
10251                    lsp_store.update_last_formatting_failure(&result);
10252                })?;
10253
10254                result
10255            })
10256        } else if let Some((client, project_id)) = self.upstream_client() {
10257            zlog::trace!(logger => "Formatting remotely");
10258            let logger = zlog::scoped!(logger => "remote");
10259            // Don't support formatting ranges via remote
10260            match target {
10261                LspFormatTarget::Buffers => {}
10262                LspFormatTarget::Ranges(_) => {
10263                    zlog::trace!(logger => "Ignoring unsupported remote range formatting request");
10264                    return Task::ready(Ok(ProjectTransaction::default()));
10265                }
10266            }
10267
10268            let buffer_store = self.buffer_store();
10269            cx.spawn(async move |lsp_store, cx| {
10270                zlog::trace!(logger => "Sending remote format request");
10271                let request_timer = zlog::time!(logger => "remote format request");
10272                let result = client
10273                    .request(proto::FormatBuffers {
10274                        project_id,
10275                        trigger: trigger as i32,
10276                        buffer_ids: buffers
10277                            .iter()
10278                            .map(|buffer| buffer.read_with(cx, |buffer, _| buffer.remote_id().into()))
10279                            .collect::<Result<_>>()?,
10280                    })
10281                    .await
10282                    .and_then(|result| result.transaction.context("missing transaction"));
10283                request_timer.end();
10284
10285                zlog::trace!(logger => "Remote format request resolved to {:?}", result.as_ref().map(|_| "<project_transaction>"));
10286
10287                lsp_store.update(cx, |lsp_store, _| {
10288                    lsp_store.update_last_formatting_failure(&result);
10289                })?;
10290
10291                let transaction_response = result?;
10292                let _timer = zlog::time!(logger => "deserializing project transaction");
10293                buffer_store
10294                    .update(cx, |buffer_store, cx| {
10295                        buffer_store.deserialize_project_transaction(
10296                            transaction_response,
10297                            push_to_history,
10298                            cx,
10299                        )
10300                    })?
10301                    .await
10302            })
10303        } else {
10304            zlog::trace!(logger => "Not formatting");
10305            Task::ready(Ok(ProjectTransaction::default()))
10306        }
10307    }
10308
10309    async fn handle_format_buffers(
10310        this: Entity<Self>,
10311        envelope: TypedEnvelope<proto::FormatBuffers>,
10312        mut cx: AsyncApp,
10313    ) -> Result<proto::FormatBuffersResponse> {
10314        let sender_id = envelope.original_sender_id().unwrap_or_default();
10315        let format = this.update(&mut cx, |this, cx| {
10316            let mut buffers = HashSet::default();
10317            for buffer_id in &envelope.payload.buffer_ids {
10318                let buffer_id = BufferId::new(*buffer_id)?;
10319                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10320            }
10321            let trigger = FormatTrigger::from_proto(envelope.payload.trigger);
10322            anyhow::Ok(this.format(buffers, LspFormatTarget::Buffers, false, trigger, cx))
10323        })??;
10324
10325        let project_transaction = format.await?;
10326        let project_transaction = this.update(&mut cx, |this, cx| {
10327            this.buffer_store.update(cx, |buffer_store, cx| {
10328                buffer_store.serialize_project_transaction_for_peer(
10329                    project_transaction,
10330                    sender_id,
10331                    cx,
10332                )
10333            })
10334        })?;
10335        Ok(proto::FormatBuffersResponse {
10336            transaction: Some(project_transaction),
10337        })
10338    }
10339
10340    async fn handle_apply_code_action_kind(
10341        this: Entity<Self>,
10342        envelope: TypedEnvelope<proto::ApplyCodeActionKind>,
10343        mut cx: AsyncApp,
10344    ) -> Result<proto::ApplyCodeActionKindResponse> {
10345        let sender_id = envelope.original_sender_id().unwrap_or_default();
10346        let format = this.update(&mut cx, |this, cx| {
10347            let mut buffers = HashSet::default();
10348            for buffer_id in &envelope.payload.buffer_ids {
10349                let buffer_id = BufferId::new(*buffer_id)?;
10350                buffers.insert(this.buffer_store.read(cx).get_existing(buffer_id)?);
10351            }
10352            let kind = match envelope.payload.kind.as_str() {
10353                "" => CodeActionKind::EMPTY,
10354                "quickfix" => CodeActionKind::QUICKFIX,
10355                "refactor" => CodeActionKind::REFACTOR,
10356                "refactor.extract" => CodeActionKind::REFACTOR_EXTRACT,
10357                "refactor.inline" => CodeActionKind::REFACTOR_INLINE,
10358                "refactor.rewrite" => CodeActionKind::REFACTOR_REWRITE,
10359                "source" => CodeActionKind::SOURCE,
10360                "source.organizeImports" => CodeActionKind::SOURCE_ORGANIZE_IMPORTS,
10361                "source.fixAll" => CodeActionKind::SOURCE_FIX_ALL,
10362                _ => anyhow::bail!(
10363                    "Invalid code action kind {}",
10364                    envelope.payload.kind.as_str()
10365                ),
10366            };
10367            anyhow::Ok(this.apply_code_action_kind(buffers, kind, false, cx))
10368        })??;
10369
10370        let project_transaction = format.await?;
10371        let project_transaction = this.update(&mut cx, |this, cx| {
10372            this.buffer_store.update(cx, |buffer_store, cx| {
10373                buffer_store.serialize_project_transaction_for_peer(
10374                    project_transaction,
10375                    sender_id,
10376                    cx,
10377                )
10378            })
10379        })?;
10380        Ok(proto::ApplyCodeActionKindResponse {
10381            transaction: Some(project_transaction),
10382        })
10383    }
10384
10385    async fn shutdown_language_server(
10386        server_state: Option<LanguageServerState>,
10387        name: LanguageServerName,
10388        cx: &mut AsyncApp,
10389    ) {
10390        let server = match server_state {
10391            Some(LanguageServerState::Starting { startup, .. }) => {
10392                let mut timer = cx
10393                    .background_executor()
10394                    .timer(SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT)
10395                    .fuse();
10396
10397                select! {
10398                    server = startup.fuse() => server,
10399                    () = timer => {
10400                        log::info!("timeout waiting for language server {name} to finish launching before stopping");
10401                        None
10402                    },
10403                }
10404            }
10405
10406            Some(LanguageServerState::Running { server, .. }) => Some(server),
10407
10408            None => None,
10409        };
10410
10411        if let Some(server) = server
10412            && let Some(shutdown) = server.shutdown()
10413        {
10414            shutdown.await;
10415        }
10416    }
10417
10418    // Returns a list of all of the worktrees which no longer have a language server and the root path
10419    // for the stopped server
10420    fn stop_local_language_server(
10421        &mut self,
10422        server_id: LanguageServerId,
10423        cx: &mut Context<Self>,
10424    ) -> Task<()> {
10425        let local = match &mut self.mode {
10426            LspStoreMode::Local(local) => local,
10427            _ => {
10428                return Task::ready(());
10429            }
10430        };
10431
10432        // Remove this server ID from all entries in the given worktree.
10433        local
10434            .language_server_ids
10435            .retain(|_, state| state.id != server_id);
10436        self.buffer_store.update(cx, |buffer_store, cx| {
10437            for buffer in buffer_store.buffers() {
10438                buffer.update(cx, |buffer, cx| {
10439                    buffer.update_diagnostics(server_id, DiagnosticSet::new([], buffer), cx);
10440                    buffer.set_completion_triggers(server_id, Default::default(), cx);
10441                });
10442            }
10443        });
10444
10445        for (worktree_id, summaries) in self.diagnostic_summaries.iter_mut() {
10446            summaries.retain(|path, summaries_by_server_id| {
10447                if summaries_by_server_id.remove(&server_id).is_some() {
10448                    if let Some((client, project_id)) = self.downstream_client.clone() {
10449                        client
10450                            .send(proto::UpdateDiagnosticSummary {
10451                                project_id,
10452                                worktree_id: worktree_id.to_proto(),
10453                                summary: Some(proto::DiagnosticSummary {
10454                                    path: path.as_ref().to_proto(),
10455                                    language_server_id: server_id.0 as u64,
10456                                    error_count: 0,
10457                                    warning_count: 0,
10458                                }),
10459                                more_summaries: Vec::new(),
10460                            })
10461                            .log_err();
10462                    }
10463                    !summaries_by_server_id.is_empty()
10464                } else {
10465                    true
10466                }
10467            });
10468        }
10469
10470        let local = self.as_local_mut().unwrap();
10471        for diagnostics in local.diagnostics.values_mut() {
10472            diagnostics.retain(|_, diagnostics_by_server_id| {
10473                if let Ok(ix) = diagnostics_by_server_id.binary_search_by_key(&server_id, |e| e.0) {
10474                    diagnostics_by_server_id.remove(ix);
10475                    !diagnostics_by_server_id.is_empty()
10476                } else {
10477                    true
10478                }
10479            });
10480        }
10481        local.language_server_watched_paths.remove(&server_id);
10482
10483        let server_state = local.language_servers.remove(&server_id);
10484        self.cleanup_lsp_data(server_id);
10485        let name = self
10486            .language_server_statuses
10487            .remove(&server_id)
10488            .map(|status| status.name)
10489            .or_else(|| {
10490                if let Some(LanguageServerState::Running { adapter, .. }) = server_state.as_ref() {
10491                    Some(adapter.name())
10492                } else {
10493                    None
10494                }
10495            });
10496
10497        if let Some(name) = name {
10498            log::info!("stopping language server {name}");
10499            self.languages
10500                .update_lsp_binary_status(name.clone(), BinaryStatus::Stopping);
10501            cx.notify();
10502
10503            return cx.spawn(async move |lsp_store, cx| {
10504                Self::shutdown_language_server(server_state, name.clone(), cx).await;
10505                lsp_store
10506                    .update(cx, |lsp_store, cx| {
10507                        lsp_store
10508                            .languages
10509                            .update_lsp_binary_status(name, BinaryStatus::Stopped);
10510                        cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10511                        cx.notify();
10512                    })
10513                    .ok();
10514            });
10515        }
10516
10517        if server_state.is_some() {
10518            cx.emit(LspStoreEvent::LanguageServerRemoved(server_id));
10519        }
10520        Task::ready(())
10521    }
10522
10523    pub fn stop_all_language_servers(&mut self, cx: &mut Context<Self>) {
10524        if let Some((client, project_id)) = self.upstream_client() {
10525            let request = client.request(proto::StopLanguageServers {
10526                project_id,
10527                buffer_ids: Vec::new(),
10528                also_servers: Vec::new(),
10529                all: true,
10530            });
10531            cx.background_spawn(request).detach_and_log_err(cx);
10532        } else {
10533            let Some(local) = self.as_local_mut() else {
10534                return;
10535            };
10536            let language_servers_to_stop = local
10537                .language_server_ids
10538                .values()
10539                .map(|state| state.id)
10540                .collect();
10541            local.lsp_tree.remove_nodes(&language_servers_to_stop);
10542            let tasks = language_servers_to_stop
10543                .into_iter()
10544                .map(|server| self.stop_local_language_server(server, cx))
10545                .collect::<Vec<_>>();
10546            cx.background_spawn(async move {
10547                futures::future::join_all(tasks).await;
10548            })
10549            .detach();
10550        }
10551    }
10552
10553    pub fn restart_language_servers_for_buffers(
10554        &mut self,
10555        buffers: Vec<Entity<Buffer>>,
10556        only_restart_servers: HashSet<LanguageServerSelector>,
10557        cx: &mut Context<Self>,
10558    ) {
10559        if let Some((client, project_id)) = self.upstream_client() {
10560            let request = client.request(proto::RestartLanguageServers {
10561                project_id,
10562                buffer_ids: buffers
10563                    .into_iter()
10564                    .map(|b| b.read(cx).remote_id().to_proto())
10565                    .collect(),
10566                only_servers: only_restart_servers
10567                    .into_iter()
10568                    .map(|selector| {
10569                        let selector = match selector {
10570                            LanguageServerSelector::Id(language_server_id) => {
10571                                proto::language_server_selector::Selector::ServerId(
10572                                    language_server_id.to_proto(),
10573                                )
10574                            }
10575                            LanguageServerSelector::Name(language_server_name) => {
10576                                proto::language_server_selector::Selector::Name(
10577                                    language_server_name.to_string(),
10578                                )
10579                            }
10580                        };
10581                        proto::LanguageServerSelector {
10582                            selector: Some(selector),
10583                        }
10584                    })
10585                    .collect(),
10586                all: false,
10587            });
10588            cx.background_spawn(request).detach_and_log_err(cx);
10589        } else {
10590            let stop_task = if only_restart_servers.is_empty() {
10591                self.stop_local_language_servers_for_buffers(&buffers, HashSet::default(), cx)
10592            } else {
10593                self.stop_local_language_servers_for_buffers(&[], only_restart_servers.clone(), cx)
10594            };
10595            cx.spawn(async move |lsp_store, cx| {
10596                stop_task.await;
10597                lsp_store
10598                    .update(cx, |lsp_store, cx| {
10599                        for buffer in buffers {
10600                            lsp_store.register_buffer_with_language_servers(
10601                                &buffer,
10602                                only_restart_servers.clone(),
10603                                true,
10604                                cx,
10605                            );
10606                        }
10607                    })
10608                    .ok()
10609            })
10610            .detach();
10611        }
10612    }
10613
10614    pub fn stop_language_servers_for_buffers(
10615        &mut self,
10616        buffers: Vec<Entity<Buffer>>,
10617        also_stop_servers: HashSet<LanguageServerSelector>,
10618        cx: &mut Context<Self>,
10619    ) -> Task<Result<()>> {
10620        if let Some((client, project_id)) = self.upstream_client() {
10621            let request = client.request(proto::StopLanguageServers {
10622                project_id,
10623                buffer_ids: buffers
10624                    .into_iter()
10625                    .map(|b| b.read(cx).remote_id().to_proto())
10626                    .collect(),
10627                also_servers: also_stop_servers
10628                    .into_iter()
10629                    .map(|selector| {
10630                        let selector = match selector {
10631                            LanguageServerSelector::Id(language_server_id) => {
10632                                proto::language_server_selector::Selector::ServerId(
10633                                    language_server_id.to_proto(),
10634                                )
10635                            }
10636                            LanguageServerSelector::Name(language_server_name) => {
10637                                proto::language_server_selector::Selector::Name(
10638                                    language_server_name.to_string(),
10639                                )
10640                            }
10641                        };
10642                        proto::LanguageServerSelector {
10643                            selector: Some(selector),
10644                        }
10645                    })
10646                    .collect(),
10647                all: false,
10648            });
10649            cx.background_spawn(async move {
10650                let _ = request.await?;
10651                Ok(())
10652            })
10653        } else {
10654            let task =
10655                self.stop_local_language_servers_for_buffers(&buffers, also_stop_servers, cx);
10656            cx.background_spawn(async move {
10657                task.await;
10658                Ok(())
10659            })
10660        }
10661    }
10662
10663    fn stop_local_language_servers_for_buffers(
10664        &mut self,
10665        buffers: &[Entity<Buffer>],
10666        also_stop_servers: HashSet<LanguageServerSelector>,
10667        cx: &mut Context<Self>,
10668    ) -> Task<()> {
10669        let Some(local) = self.as_local_mut() else {
10670            return Task::ready(());
10671        };
10672        let mut language_server_names_to_stop = BTreeSet::default();
10673        let mut language_servers_to_stop = also_stop_servers
10674            .into_iter()
10675            .flat_map(|selector| match selector {
10676                LanguageServerSelector::Id(id) => Some(id),
10677                LanguageServerSelector::Name(name) => {
10678                    language_server_names_to_stop.insert(name);
10679                    None
10680                }
10681            })
10682            .collect::<BTreeSet<_>>();
10683
10684        let mut covered_worktrees = HashSet::default();
10685        for buffer in buffers {
10686            buffer.update(cx, |buffer, cx| {
10687                language_servers_to_stop.extend(local.language_server_ids_for_buffer(buffer, cx));
10688                if let Some(worktree_id) = buffer.file().map(|f| f.worktree_id(cx))
10689                    && covered_worktrees.insert(worktree_id)
10690                {
10691                    language_server_names_to_stop.retain(|name| {
10692                        let old_ids_count = language_servers_to_stop.len();
10693                        let all_language_servers_with_this_name = local
10694                            .language_server_ids
10695                            .iter()
10696                            .filter_map(|(seed, state)| seed.name.eq(name).then(|| state.id));
10697                        language_servers_to_stop.extend(all_language_servers_with_this_name);
10698                        old_ids_count == language_servers_to_stop.len()
10699                    });
10700                }
10701            });
10702        }
10703        for name in language_server_names_to_stop {
10704            language_servers_to_stop.extend(
10705                local
10706                    .language_server_ids
10707                    .iter()
10708                    .filter_map(|(seed, v)| seed.name.eq(&name).then(|| v.id)),
10709            );
10710        }
10711
10712        local.lsp_tree.remove_nodes(&language_servers_to_stop);
10713        let tasks = language_servers_to_stop
10714            .into_iter()
10715            .map(|server| self.stop_local_language_server(server, cx))
10716            .collect::<Vec<_>>();
10717
10718        cx.background_spawn(futures::future::join_all(tasks).map(|_| ()))
10719    }
10720
10721    fn get_buffer<'a>(&self, abs_path: &Path, cx: &'a App) -> Option<&'a Buffer> {
10722        let (worktree, relative_path) =
10723            self.worktree_store.read(cx).find_worktree(&abs_path, cx)?;
10724
10725        let project_path = ProjectPath {
10726            worktree_id: worktree.read(cx).id(),
10727            path: relative_path,
10728        };
10729
10730        Some(
10731            self.buffer_store()
10732                .read(cx)
10733                .get_by_path(&project_path)?
10734                .read(cx),
10735        )
10736    }
10737
10738    #[cfg(any(test, feature = "test-support"))]
10739    pub fn update_diagnostics(
10740        &mut self,
10741        server_id: LanguageServerId,
10742        diagnostics: lsp::PublishDiagnosticsParams,
10743        result_id: Option<String>,
10744        source_kind: DiagnosticSourceKind,
10745        disk_based_sources: &[String],
10746        cx: &mut Context<Self>,
10747    ) -> Result<()> {
10748        self.merge_lsp_diagnostics(
10749            source_kind,
10750            vec![DocumentDiagnosticsUpdate {
10751                diagnostics,
10752                result_id,
10753                server_id,
10754                disk_based_sources: Cow::Borrowed(disk_based_sources),
10755            }],
10756            |_, _, _| false,
10757            cx,
10758        )
10759    }
10760
10761    pub fn merge_lsp_diagnostics(
10762        &mut self,
10763        source_kind: DiagnosticSourceKind,
10764        lsp_diagnostics: Vec<DocumentDiagnosticsUpdate<lsp::PublishDiagnosticsParams>>,
10765        merge: impl Fn(&Buffer, &Diagnostic, &App) -> bool + Clone,
10766        cx: &mut Context<Self>,
10767    ) -> Result<()> {
10768        anyhow::ensure!(self.mode.is_local(), "called update_diagnostics on remote");
10769        let updates = lsp_diagnostics
10770            .into_iter()
10771            .filter_map(|update| {
10772                let abs_path = update.diagnostics.uri.to_file_path().ok()?;
10773                Some(DocumentDiagnosticsUpdate {
10774                    diagnostics: self.lsp_to_document_diagnostics(
10775                        abs_path,
10776                        source_kind,
10777                        update.server_id,
10778                        update.diagnostics,
10779                        &update.disk_based_sources,
10780                    ),
10781                    result_id: update.result_id,
10782                    server_id: update.server_id,
10783                    disk_based_sources: update.disk_based_sources,
10784                })
10785            })
10786            .collect();
10787        self.merge_diagnostic_entries(updates, merge, cx)?;
10788        Ok(())
10789    }
10790
10791    fn lsp_to_document_diagnostics(
10792        &mut self,
10793        document_abs_path: PathBuf,
10794        source_kind: DiagnosticSourceKind,
10795        server_id: LanguageServerId,
10796        mut lsp_diagnostics: lsp::PublishDiagnosticsParams,
10797        disk_based_sources: &[String],
10798    ) -> DocumentDiagnostics {
10799        let mut diagnostics = Vec::default();
10800        let mut primary_diagnostic_group_ids = HashMap::default();
10801        let mut sources_by_group_id = HashMap::default();
10802        let mut supporting_diagnostics = HashMap::default();
10803
10804        let adapter = self.language_server_adapter_for_id(server_id);
10805
10806        // Ensure that primary diagnostics are always the most severe
10807        lsp_diagnostics
10808            .diagnostics
10809            .sort_by_key(|item| item.severity);
10810
10811        for diagnostic in &lsp_diagnostics.diagnostics {
10812            let source = diagnostic.source.as_ref();
10813            let range = range_from_lsp(diagnostic.range);
10814            let is_supporting = diagnostic
10815                .related_information
10816                .as_ref()
10817                .is_some_and(|infos| {
10818                    infos.iter().any(|info| {
10819                        primary_diagnostic_group_ids.contains_key(&(
10820                            source,
10821                            diagnostic.code.clone(),
10822                            range_from_lsp(info.location.range),
10823                        ))
10824                    })
10825                });
10826
10827            let is_unnecessary = diagnostic
10828                .tags
10829                .as_ref()
10830                .is_some_and(|tags| tags.contains(&DiagnosticTag::UNNECESSARY));
10831
10832            let underline = self
10833                .language_server_adapter_for_id(server_id)
10834                .is_none_or(|adapter| adapter.underline_diagnostic(diagnostic));
10835
10836            if is_supporting {
10837                supporting_diagnostics.insert(
10838                    (source, diagnostic.code.clone(), range),
10839                    (diagnostic.severity, is_unnecessary),
10840                );
10841            } else {
10842                let group_id = post_inc(&mut self.as_local_mut().unwrap().next_diagnostic_group_id);
10843                let is_disk_based =
10844                    source.is_some_and(|source| disk_based_sources.contains(source));
10845
10846                sources_by_group_id.insert(group_id, source);
10847                primary_diagnostic_group_ids
10848                    .insert((source, diagnostic.code.clone(), range.clone()), group_id);
10849
10850                diagnostics.push(DiagnosticEntry {
10851                    range,
10852                    diagnostic: Diagnostic {
10853                        source: diagnostic.source.clone(),
10854                        source_kind,
10855                        code: diagnostic.code.clone(),
10856                        code_description: diagnostic
10857                            .code_description
10858                            .as_ref()
10859                            .and_then(|d| d.href.clone()),
10860                        severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
10861                        markdown: adapter.as_ref().and_then(|adapter| {
10862                            adapter.diagnostic_message_to_markdown(&diagnostic.message)
10863                        }),
10864                        message: diagnostic.message.trim().to_string(),
10865                        group_id,
10866                        is_primary: true,
10867                        is_disk_based,
10868                        is_unnecessary,
10869                        underline,
10870                        data: diagnostic.data.clone(),
10871                    },
10872                });
10873                if let Some(infos) = &diagnostic.related_information {
10874                    for info in infos {
10875                        if info.location.uri == lsp_diagnostics.uri && !info.message.is_empty() {
10876                            let range = range_from_lsp(info.location.range);
10877                            diagnostics.push(DiagnosticEntry {
10878                                range,
10879                                diagnostic: Diagnostic {
10880                                    source: diagnostic.source.clone(),
10881                                    source_kind,
10882                                    code: diagnostic.code.clone(),
10883                                    code_description: diagnostic
10884                                        .code_description
10885                                        .as_ref()
10886                                        .and_then(|d| d.href.clone()),
10887                                    severity: DiagnosticSeverity::INFORMATION,
10888                                    markdown: adapter.as_ref().and_then(|adapter| {
10889                                        adapter.diagnostic_message_to_markdown(&info.message)
10890                                    }),
10891                                    message: info.message.trim().to_string(),
10892                                    group_id,
10893                                    is_primary: false,
10894                                    is_disk_based,
10895                                    is_unnecessary: false,
10896                                    underline,
10897                                    data: diagnostic.data.clone(),
10898                                },
10899                            });
10900                        }
10901                    }
10902                }
10903            }
10904        }
10905
10906        for entry in &mut diagnostics {
10907            let diagnostic = &mut entry.diagnostic;
10908            if !diagnostic.is_primary {
10909                let source = *sources_by_group_id.get(&diagnostic.group_id).unwrap();
10910                if let Some(&(severity, is_unnecessary)) = supporting_diagnostics.get(&(
10911                    source,
10912                    diagnostic.code.clone(),
10913                    entry.range.clone(),
10914                )) {
10915                    if let Some(severity) = severity {
10916                        diagnostic.severity = severity;
10917                    }
10918                    diagnostic.is_unnecessary = is_unnecessary;
10919                }
10920            }
10921        }
10922
10923        DocumentDiagnostics {
10924            diagnostics,
10925            document_abs_path,
10926            version: lsp_diagnostics.version,
10927        }
10928    }
10929
10930    fn insert_newly_running_language_server(
10931        &mut self,
10932        adapter: Arc<CachedLspAdapter>,
10933        language_server: Arc<LanguageServer>,
10934        server_id: LanguageServerId,
10935        key: LanguageServerSeed,
10936        workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
10937        cx: &mut Context<Self>,
10938    ) {
10939        let Some(local) = self.as_local_mut() else {
10940            return;
10941        };
10942        // If the language server for this key doesn't match the server id, don't store the
10943        // server. Which will cause it to be dropped, killing the process
10944        if local
10945            .language_server_ids
10946            .get(&key)
10947            .map(|state| state.id != server_id)
10948            .unwrap_or(false)
10949        {
10950            return;
10951        }
10952
10953        // Update language_servers collection with Running variant of LanguageServerState
10954        // indicating that the server is up and running and ready
10955        let workspace_folders = workspace_folders.lock().clone();
10956        language_server.set_workspace_folders(workspace_folders);
10957
10958        let workspace_diagnostics_refresh_tasks = language_server
10959            .capabilities()
10960            .diagnostic_provider
10961            .and_then(|provider| {
10962                local
10963                    .language_server_dynamic_registrations
10964                    .entry(server_id)
10965                    .or_default()
10966                    .diagnostics
10967                    .entry(None)
10968                    .or_insert(provider.clone());
10969                let workspace_refresher =
10970                    lsp_workspace_diagnostics_refresh(None, provider, language_server.clone(), cx)?;
10971
10972                Some((None, workspace_refresher))
10973            })
10974            .into_iter()
10975            .collect();
10976        local.language_servers.insert(
10977            server_id,
10978            LanguageServerState::Running {
10979                workspace_diagnostics_refresh_tasks,
10980                adapter: adapter.clone(),
10981                server: language_server.clone(),
10982                simulate_disk_based_diagnostics_completion: None,
10983            },
10984        );
10985        local
10986            .languages
10987            .update_lsp_binary_status(adapter.name(), BinaryStatus::None);
10988        if let Some(file_ops_caps) = language_server
10989            .capabilities()
10990            .workspace
10991            .as_ref()
10992            .and_then(|ws| ws.file_operations.as_ref())
10993        {
10994            let did_rename_caps = file_ops_caps.did_rename.as_ref();
10995            let will_rename_caps = file_ops_caps.will_rename.as_ref();
10996            if did_rename_caps.or(will_rename_caps).is_some() {
10997                let watcher = RenamePathsWatchedForServer::default()
10998                    .with_did_rename_patterns(did_rename_caps)
10999                    .with_will_rename_patterns(will_rename_caps);
11000                local
11001                    .language_server_paths_watched_for_rename
11002                    .insert(server_id, watcher);
11003            }
11004        }
11005
11006        self.language_server_statuses.insert(
11007            server_id,
11008            LanguageServerStatus {
11009                name: language_server.name(),
11010                pending_work: Default::default(),
11011                has_pending_diagnostic_updates: false,
11012                progress_tokens: Default::default(),
11013                worktree: Some(key.worktree_id),
11014            },
11015        );
11016
11017        cx.emit(LspStoreEvent::LanguageServerAdded(
11018            server_id,
11019            language_server.name(),
11020            Some(key.worktree_id),
11021        ));
11022
11023        let server_capabilities = language_server.capabilities();
11024        if let Some((downstream_client, project_id)) = self.downstream_client.as_ref() {
11025            downstream_client
11026                .send(proto::StartLanguageServer {
11027                    project_id: *project_id,
11028                    server: Some(proto::LanguageServer {
11029                        id: server_id.to_proto(),
11030                        name: language_server.name().to_string(),
11031                        worktree_id: Some(key.worktree_id.to_proto()),
11032                    }),
11033                    capabilities: serde_json::to_string(&server_capabilities)
11034                        .expect("serializing server LSP capabilities"),
11035                })
11036                .log_err();
11037        }
11038        self.lsp_server_capabilities
11039            .insert(server_id, server_capabilities);
11040
11041        // Tell the language server about every open buffer in the worktree that matches the language.
11042        // Also check for buffers in worktrees that reused this server
11043        let mut worktrees_using_server = vec![key.worktree_id];
11044        if let Some(local) = self.as_local() {
11045            // Find all worktrees that have this server in their language server tree
11046            for (worktree_id, servers) in &local.lsp_tree.instances {
11047                if *worktree_id != key.worktree_id {
11048                    for server_map in servers.roots.values() {
11049                        if server_map
11050                            .values()
11051                            .any(|(node, _)| node.id() == Some(server_id))
11052                        {
11053                            worktrees_using_server.push(*worktree_id);
11054                        }
11055                    }
11056                }
11057            }
11058        }
11059
11060        let mut buffer_paths_registered = Vec::new();
11061        self.buffer_store.clone().update(cx, |buffer_store, cx| {
11062            let mut lsp_adapters = HashMap::default();
11063            for buffer_handle in buffer_store.buffers() {
11064                let buffer = buffer_handle.read(cx);
11065                let file = match File::from_dyn(buffer.file()) {
11066                    Some(file) => file,
11067                    None => continue,
11068                };
11069                let language = match buffer.language() {
11070                    Some(language) => language,
11071                    None => continue,
11072                };
11073
11074                if !worktrees_using_server.contains(&file.worktree.read(cx).id())
11075                    || !lsp_adapters
11076                        .entry(language.name())
11077                        .or_insert_with(|| self.languages.lsp_adapters(&language.name()))
11078                        .iter()
11079                        .any(|a| a.name == key.name)
11080                {
11081                    continue;
11082                }
11083                // didOpen
11084                let file = match file.as_local() {
11085                    Some(file) => file,
11086                    None => continue,
11087                };
11088
11089                let local = self.as_local_mut().unwrap();
11090
11091                let buffer_id = buffer.remote_id();
11092                if local.registered_buffers.contains_key(&buffer_id) {
11093                    let versions = local
11094                        .buffer_snapshots
11095                        .entry(buffer_id)
11096                        .or_default()
11097                        .entry(server_id)
11098                        .and_modify(|_| {
11099                            assert!(
11100                            false,
11101                            "There should not be an existing snapshot for a newly inserted buffer"
11102                        )
11103                        })
11104                        .or_insert_with(|| {
11105                            vec![LspBufferSnapshot {
11106                                version: 0,
11107                                snapshot: buffer.text_snapshot(),
11108                            }]
11109                        });
11110
11111                    let snapshot = versions.last().unwrap();
11112                    let version = snapshot.version;
11113                    let initial_snapshot = &snapshot.snapshot;
11114                    let uri = lsp::Uri::from_file_path(file.abs_path(cx)).unwrap();
11115                    language_server.register_buffer(
11116                        uri,
11117                        adapter.language_id(&language.name()),
11118                        version,
11119                        initial_snapshot.text(),
11120                    );
11121                    buffer_paths_registered.push((buffer_id, file.abs_path(cx)));
11122                    local
11123                        .buffers_opened_in_servers
11124                        .entry(buffer_id)
11125                        .or_default()
11126                        .insert(server_id);
11127                }
11128                buffer_handle.update(cx, |buffer, cx| {
11129                    buffer.set_completion_triggers(
11130                        server_id,
11131                        language_server
11132                            .capabilities()
11133                            .completion_provider
11134                            .as_ref()
11135                            .and_then(|provider| {
11136                                provider
11137                                    .trigger_characters
11138                                    .as_ref()
11139                                    .map(|characters| characters.iter().cloned().collect())
11140                            })
11141                            .unwrap_or_default(),
11142                        cx,
11143                    )
11144                });
11145            }
11146        });
11147
11148        for (buffer_id, abs_path) in buffer_paths_registered {
11149            cx.emit(LspStoreEvent::LanguageServerUpdate {
11150                language_server_id: server_id,
11151                name: Some(adapter.name()),
11152                message: proto::update_language_server::Variant::RegisteredForBuffer(
11153                    proto::RegisteredForBuffer {
11154                        buffer_abs_path: abs_path.to_string_lossy().into_owned(),
11155                        buffer_id: buffer_id.to_proto(),
11156                    },
11157                ),
11158            });
11159        }
11160
11161        cx.notify();
11162    }
11163
11164    pub fn language_servers_running_disk_based_diagnostics(
11165        &self,
11166    ) -> impl Iterator<Item = LanguageServerId> + '_ {
11167        self.language_server_statuses
11168            .iter()
11169            .filter_map(|(id, status)| {
11170                if status.has_pending_diagnostic_updates {
11171                    Some(*id)
11172                } else {
11173                    None
11174                }
11175            })
11176    }
11177
11178    pub(crate) fn cancel_language_server_work_for_buffers(
11179        &mut self,
11180        buffers: impl IntoIterator<Item = Entity<Buffer>>,
11181        cx: &mut Context<Self>,
11182    ) {
11183        if let Some((client, project_id)) = self.upstream_client() {
11184            let request = client.request(proto::CancelLanguageServerWork {
11185                project_id,
11186                work: Some(proto::cancel_language_server_work::Work::Buffers(
11187                    proto::cancel_language_server_work::Buffers {
11188                        buffer_ids: buffers
11189                            .into_iter()
11190                            .map(|b| b.read(cx).remote_id().to_proto())
11191                            .collect(),
11192                    },
11193                )),
11194            });
11195            cx.background_spawn(request).detach_and_log_err(cx);
11196        } else if let Some(local) = self.as_local() {
11197            let servers = buffers
11198                .into_iter()
11199                .flat_map(|buffer| {
11200                    buffer.update(cx, |buffer, cx| {
11201                        local.language_server_ids_for_buffer(buffer, cx).into_iter()
11202                    })
11203                })
11204                .collect::<HashSet<_>>();
11205            for server_id in servers {
11206                self.cancel_language_server_work(server_id, None, cx);
11207            }
11208        }
11209    }
11210
11211    pub(crate) fn cancel_language_server_work(
11212        &mut self,
11213        server_id: LanguageServerId,
11214        token_to_cancel: Option<ProgressToken>,
11215        cx: &mut Context<Self>,
11216    ) {
11217        if let Some(local) = self.as_local() {
11218            let status = self.language_server_statuses.get(&server_id);
11219            let server = local.language_servers.get(&server_id);
11220            if let Some((LanguageServerState::Running { server, .. }, status)) = server.zip(status)
11221            {
11222                for (token, progress) in &status.pending_work {
11223                    if let Some(token_to_cancel) = token_to_cancel.as_ref()
11224                        && token != token_to_cancel
11225                    {
11226                        continue;
11227                    }
11228                    if progress.is_cancellable {
11229                        server
11230                            .notify::<lsp::notification::WorkDoneProgressCancel>(
11231                                WorkDoneProgressCancelParams {
11232                                    token: token.to_lsp(),
11233                                },
11234                            )
11235                            .ok();
11236                    }
11237                }
11238            }
11239        } else if let Some((client, project_id)) = self.upstream_client() {
11240            let request = client.request(proto::CancelLanguageServerWork {
11241                project_id,
11242                work: Some(
11243                    proto::cancel_language_server_work::Work::LanguageServerWork(
11244                        proto::cancel_language_server_work::LanguageServerWork {
11245                            language_server_id: server_id.to_proto(),
11246                            token: token_to_cancel.map(|token| token.to_proto()),
11247                        },
11248                    ),
11249                ),
11250            });
11251            cx.background_spawn(request).detach_and_log_err(cx);
11252        }
11253    }
11254
11255    fn register_supplementary_language_server(
11256        &mut self,
11257        id: LanguageServerId,
11258        name: LanguageServerName,
11259        server: Arc<LanguageServer>,
11260        cx: &mut Context<Self>,
11261    ) {
11262        if let Some(local) = self.as_local_mut() {
11263            local
11264                .supplementary_language_servers
11265                .insert(id, (name.clone(), server));
11266            cx.emit(LspStoreEvent::LanguageServerAdded(id, name, None));
11267        }
11268    }
11269
11270    fn unregister_supplementary_language_server(
11271        &mut self,
11272        id: LanguageServerId,
11273        cx: &mut Context<Self>,
11274    ) {
11275        if let Some(local) = self.as_local_mut() {
11276            local.supplementary_language_servers.remove(&id);
11277            cx.emit(LspStoreEvent::LanguageServerRemoved(id));
11278        }
11279    }
11280
11281    pub(crate) fn supplementary_language_servers(
11282        &self,
11283    ) -> impl '_ + Iterator<Item = (LanguageServerId, LanguageServerName)> {
11284        self.as_local().into_iter().flat_map(|local| {
11285            local
11286                .supplementary_language_servers
11287                .iter()
11288                .map(|(id, (name, _))| (*id, name.clone()))
11289        })
11290    }
11291
11292    pub fn language_server_adapter_for_id(
11293        &self,
11294        id: LanguageServerId,
11295    ) -> Option<Arc<CachedLspAdapter>> {
11296        self.as_local()
11297            .and_then(|local| local.language_servers.get(&id))
11298            .and_then(|language_server_state| match language_server_state {
11299                LanguageServerState::Running { adapter, .. } => Some(adapter.clone()),
11300                _ => None,
11301            })
11302    }
11303
11304    pub(super) fn update_local_worktree_language_servers(
11305        &mut self,
11306        worktree_handle: &Entity<Worktree>,
11307        changes: &[(Arc<RelPath>, ProjectEntryId, PathChange)],
11308        cx: &mut Context<Self>,
11309    ) {
11310        if changes.is_empty() {
11311            return;
11312        }
11313
11314        let Some(local) = self.as_local() else { return };
11315
11316        local.prettier_store.update(cx, |prettier_store, cx| {
11317            prettier_store.update_prettier_settings(worktree_handle, changes, cx)
11318        });
11319
11320        let worktree_id = worktree_handle.read(cx).id();
11321        let mut language_server_ids = local
11322            .language_server_ids
11323            .iter()
11324            .filter_map(|(seed, v)| seed.worktree_id.eq(&worktree_id).then(|| v.id))
11325            .collect::<Vec<_>>();
11326        language_server_ids.sort();
11327        language_server_ids.dedup();
11328
11329        // let abs_path = worktree_handle.read(cx).abs_path();
11330        for server_id in &language_server_ids {
11331            if let Some(LanguageServerState::Running { server, .. }) =
11332                local.language_servers.get(server_id)
11333                && let Some(watched_paths) = local
11334                    .language_server_watched_paths
11335                    .get(server_id)
11336                    .and_then(|paths| paths.worktree_paths.get(&worktree_id))
11337            {
11338                let params = lsp::DidChangeWatchedFilesParams {
11339                    changes: changes
11340                        .iter()
11341                        .filter_map(|(path, _, change)| {
11342                            if !watched_paths.is_match(path.as_std_path()) {
11343                                return None;
11344                            }
11345                            let typ = match change {
11346                                PathChange::Loaded => return None,
11347                                PathChange::Added => lsp::FileChangeType::CREATED,
11348                                PathChange::Removed => lsp::FileChangeType::DELETED,
11349                                PathChange::Updated => lsp::FileChangeType::CHANGED,
11350                                PathChange::AddedOrUpdated => lsp::FileChangeType::CHANGED,
11351                            };
11352                            let uri = lsp::Uri::from_file_path(
11353                                worktree_handle.read(cx).absolutize(&path),
11354                            )
11355                            .ok()?;
11356                            Some(lsp::FileEvent { uri, typ })
11357                        })
11358                        .collect(),
11359                };
11360                if !params.changes.is_empty() {
11361                    server
11362                        .notify::<lsp::notification::DidChangeWatchedFiles>(params)
11363                        .ok();
11364                }
11365            }
11366        }
11367        for (path, _, _) in changes {
11368            if let Some(file_name) = path.file_name()
11369                && local.watched_manifest_filenames.contains(file_name)
11370            {
11371                self.request_workspace_config_refresh();
11372                break;
11373            }
11374        }
11375    }
11376
11377    pub fn wait_for_remote_buffer(
11378        &mut self,
11379        id: BufferId,
11380        cx: &mut Context<Self>,
11381    ) -> Task<Result<Entity<Buffer>>> {
11382        self.buffer_store.update(cx, |buffer_store, cx| {
11383            buffer_store.wait_for_remote_buffer(id, cx)
11384        })
11385    }
11386
11387    fn serialize_symbol(symbol: &Symbol) -> proto::Symbol {
11388        let mut result = proto::Symbol {
11389            language_server_name: symbol.language_server_name.0.to_string(),
11390            source_worktree_id: symbol.source_worktree_id.to_proto(),
11391            language_server_id: symbol.source_language_server_id.to_proto(),
11392            name: symbol.name.clone(),
11393            kind: unsafe { mem::transmute::<lsp::SymbolKind, i32>(symbol.kind) },
11394            start: Some(proto::PointUtf16 {
11395                row: symbol.range.start.0.row,
11396                column: symbol.range.start.0.column,
11397            }),
11398            end: Some(proto::PointUtf16 {
11399                row: symbol.range.end.0.row,
11400                column: symbol.range.end.0.column,
11401            }),
11402            worktree_id: Default::default(),
11403            path: Default::default(),
11404            signature: Default::default(),
11405        };
11406        match &symbol.path {
11407            SymbolLocation::InProject(path) => {
11408                result.worktree_id = path.worktree_id.to_proto();
11409                result.path = path.path.to_proto();
11410            }
11411            SymbolLocation::OutsideProject {
11412                abs_path,
11413                signature,
11414            } => {
11415                result.path = abs_path.to_string_lossy().into_owned();
11416                result.signature = signature.to_vec();
11417            }
11418        }
11419        result
11420    }
11421
11422    fn deserialize_symbol(serialized_symbol: proto::Symbol) -> Result<CoreSymbol> {
11423        let source_worktree_id = WorktreeId::from_proto(serialized_symbol.source_worktree_id);
11424        let worktree_id = WorktreeId::from_proto(serialized_symbol.worktree_id);
11425        let kind = unsafe { mem::transmute::<i32, lsp::SymbolKind>(serialized_symbol.kind) };
11426
11427        let path = if serialized_symbol.signature.is_empty() {
11428            SymbolLocation::InProject(ProjectPath {
11429                worktree_id,
11430                path: RelPath::from_proto(&serialized_symbol.path)
11431                    .context("invalid symbol path")?,
11432            })
11433        } else {
11434            SymbolLocation::OutsideProject {
11435                abs_path: Path::new(&serialized_symbol.path).into(),
11436                signature: serialized_symbol
11437                    .signature
11438                    .try_into()
11439                    .map_err(|_| anyhow!("invalid signature"))?,
11440            }
11441        };
11442
11443        let start = serialized_symbol.start.context("invalid start")?;
11444        let end = serialized_symbol.end.context("invalid end")?;
11445        Ok(CoreSymbol {
11446            language_server_name: LanguageServerName(serialized_symbol.language_server_name.into()),
11447            source_worktree_id,
11448            source_language_server_id: LanguageServerId::from_proto(
11449                serialized_symbol.language_server_id,
11450            ),
11451            path,
11452            name: serialized_symbol.name,
11453            range: Unclipped(PointUtf16::new(start.row, start.column))
11454                ..Unclipped(PointUtf16::new(end.row, end.column)),
11455            kind,
11456        })
11457    }
11458
11459    pub(crate) fn serialize_completion(completion: &CoreCompletion) -> proto::Completion {
11460        let mut serialized_completion = proto::Completion {
11461            old_replace_start: Some(serialize_anchor(&completion.replace_range.start)),
11462            old_replace_end: Some(serialize_anchor(&completion.replace_range.end)),
11463            new_text: completion.new_text.clone(),
11464            ..proto::Completion::default()
11465        };
11466        match &completion.source {
11467            CompletionSource::Lsp {
11468                insert_range,
11469                server_id,
11470                lsp_completion,
11471                lsp_defaults,
11472                resolved,
11473            } => {
11474                let (old_insert_start, old_insert_end) = insert_range
11475                    .as_ref()
11476                    .map(|range| (serialize_anchor(&range.start), serialize_anchor(&range.end)))
11477                    .unzip();
11478
11479                serialized_completion.old_insert_start = old_insert_start;
11480                serialized_completion.old_insert_end = old_insert_end;
11481                serialized_completion.source = proto::completion::Source::Lsp as i32;
11482                serialized_completion.server_id = server_id.0 as u64;
11483                serialized_completion.lsp_completion = serde_json::to_vec(lsp_completion).unwrap();
11484                serialized_completion.lsp_defaults = lsp_defaults
11485                    .as_deref()
11486                    .map(|lsp_defaults| serde_json::to_vec(lsp_defaults).unwrap());
11487                serialized_completion.resolved = *resolved;
11488            }
11489            CompletionSource::BufferWord {
11490                word_range,
11491                resolved,
11492            } => {
11493                serialized_completion.source = proto::completion::Source::BufferWord as i32;
11494                serialized_completion.buffer_word_start = Some(serialize_anchor(&word_range.start));
11495                serialized_completion.buffer_word_end = Some(serialize_anchor(&word_range.end));
11496                serialized_completion.resolved = *resolved;
11497            }
11498            CompletionSource::Custom => {
11499                serialized_completion.source = proto::completion::Source::Custom as i32;
11500                serialized_completion.resolved = true;
11501            }
11502            CompletionSource::Dap { sort_text } => {
11503                serialized_completion.source = proto::completion::Source::Dap as i32;
11504                serialized_completion.sort_text = Some(sort_text.clone());
11505            }
11506        }
11507
11508        serialized_completion
11509    }
11510
11511    pub(crate) fn deserialize_completion(completion: proto::Completion) -> Result<CoreCompletion> {
11512        let old_replace_start = completion
11513            .old_replace_start
11514            .and_then(deserialize_anchor)
11515            .context("invalid old start")?;
11516        let old_replace_end = completion
11517            .old_replace_end
11518            .and_then(deserialize_anchor)
11519            .context("invalid old end")?;
11520        let insert_range = {
11521            match completion.old_insert_start.zip(completion.old_insert_end) {
11522                Some((start, end)) => {
11523                    let start = deserialize_anchor(start).context("invalid insert old start")?;
11524                    let end = deserialize_anchor(end).context("invalid insert old end")?;
11525                    Some(start..end)
11526                }
11527                None => None,
11528            }
11529        };
11530        Ok(CoreCompletion {
11531            replace_range: old_replace_start..old_replace_end,
11532            new_text: completion.new_text,
11533            source: match proto::completion::Source::from_i32(completion.source) {
11534                Some(proto::completion::Source::Custom) => CompletionSource::Custom,
11535                Some(proto::completion::Source::Lsp) => CompletionSource::Lsp {
11536                    insert_range,
11537                    server_id: LanguageServerId::from_proto(completion.server_id),
11538                    lsp_completion: serde_json::from_slice(&completion.lsp_completion)?,
11539                    lsp_defaults: completion
11540                        .lsp_defaults
11541                        .as_deref()
11542                        .map(serde_json::from_slice)
11543                        .transpose()?,
11544                    resolved: completion.resolved,
11545                },
11546                Some(proto::completion::Source::BufferWord) => {
11547                    let word_range = completion
11548                        .buffer_word_start
11549                        .and_then(deserialize_anchor)
11550                        .context("invalid buffer word start")?
11551                        ..completion
11552                            .buffer_word_end
11553                            .and_then(deserialize_anchor)
11554                            .context("invalid buffer word end")?;
11555                    CompletionSource::BufferWord {
11556                        word_range,
11557                        resolved: completion.resolved,
11558                    }
11559                }
11560                Some(proto::completion::Source::Dap) => CompletionSource::Dap {
11561                    sort_text: completion
11562                        .sort_text
11563                        .context("expected sort text to exist")?,
11564                },
11565                _ => anyhow::bail!("Unexpected completion source {}", completion.source),
11566            },
11567        })
11568    }
11569
11570    pub(crate) fn serialize_code_action(action: &CodeAction) -> proto::CodeAction {
11571        let (kind, lsp_action) = match &action.lsp_action {
11572            LspAction::Action(code_action) => (
11573                proto::code_action::Kind::Action as i32,
11574                serde_json::to_vec(code_action).unwrap(),
11575            ),
11576            LspAction::Command(command) => (
11577                proto::code_action::Kind::Command as i32,
11578                serde_json::to_vec(command).unwrap(),
11579            ),
11580            LspAction::CodeLens(code_lens) => (
11581                proto::code_action::Kind::CodeLens as i32,
11582                serde_json::to_vec(code_lens).unwrap(),
11583            ),
11584        };
11585
11586        proto::CodeAction {
11587            server_id: action.server_id.0 as u64,
11588            start: Some(serialize_anchor(&action.range.start)),
11589            end: Some(serialize_anchor(&action.range.end)),
11590            lsp_action,
11591            kind,
11592            resolved: action.resolved,
11593        }
11594    }
11595
11596    pub(crate) fn deserialize_code_action(action: proto::CodeAction) -> Result<CodeAction> {
11597        let start = action
11598            .start
11599            .and_then(deserialize_anchor)
11600            .context("invalid start")?;
11601        let end = action
11602            .end
11603            .and_then(deserialize_anchor)
11604            .context("invalid end")?;
11605        let lsp_action = match proto::code_action::Kind::from_i32(action.kind) {
11606            Some(proto::code_action::Kind::Action) => {
11607                LspAction::Action(serde_json::from_slice(&action.lsp_action)?)
11608            }
11609            Some(proto::code_action::Kind::Command) => {
11610                LspAction::Command(serde_json::from_slice(&action.lsp_action)?)
11611            }
11612            Some(proto::code_action::Kind::CodeLens) => {
11613                LspAction::CodeLens(serde_json::from_slice(&action.lsp_action)?)
11614            }
11615            None => anyhow::bail!("Unknown action kind {}", action.kind),
11616        };
11617        Ok(CodeAction {
11618            server_id: LanguageServerId(action.server_id as usize),
11619            range: start..end,
11620            resolved: action.resolved,
11621            lsp_action,
11622        })
11623    }
11624
11625    fn update_last_formatting_failure<T>(&mut self, formatting_result: &anyhow::Result<T>) {
11626        match &formatting_result {
11627            Ok(_) => self.last_formatting_failure = None,
11628            Err(error) => {
11629                let error_string = format!("{error:#}");
11630                log::error!("Formatting failed: {error_string}");
11631                self.last_formatting_failure
11632                    .replace(error_string.lines().join(" "));
11633            }
11634        }
11635    }
11636
11637    fn cleanup_lsp_data(&mut self, for_server: LanguageServerId) {
11638        self.lsp_server_capabilities.remove(&for_server);
11639        for lsp_data in self.lsp_data.values_mut() {
11640            lsp_data.remove_server_data(for_server);
11641        }
11642        if let Some(local) = self.as_local_mut() {
11643            local.buffer_pull_diagnostics_result_ids.remove(&for_server);
11644            for buffer_servers in local.buffers_opened_in_servers.values_mut() {
11645                buffer_servers.remove(&for_server);
11646            }
11647        }
11648    }
11649
11650    pub fn result_id(
11651        &self,
11652        server_id: LanguageServerId,
11653        buffer_id: BufferId,
11654        cx: &App,
11655    ) -> Option<String> {
11656        let abs_path = self
11657            .buffer_store
11658            .read(cx)
11659            .get(buffer_id)
11660            .and_then(|b| File::from_dyn(b.read(cx).file()))
11661            .map(|f| f.abs_path(cx))?;
11662        self.as_local()?
11663            .buffer_pull_diagnostics_result_ids
11664            .get(&server_id)?
11665            .get(&abs_path)?
11666            .clone()
11667    }
11668
11669    pub fn all_result_ids(&self, server_id: LanguageServerId) -> HashMap<PathBuf, String> {
11670        let Some(local) = self.as_local() else {
11671            return HashMap::default();
11672        };
11673        local
11674            .buffer_pull_diagnostics_result_ids
11675            .get(&server_id)
11676            .into_iter()
11677            .flatten()
11678            .filter_map(|(abs_path, result_id)| Some((abs_path.clone(), result_id.clone()?)))
11679            .collect()
11680    }
11681
11682    pub fn pull_workspace_diagnostics(&mut self, server_id: LanguageServerId) {
11683        if let Some(LanguageServerState::Running {
11684            workspace_diagnostics_refresh_tasks,
11685            ..
11686        }) = self
11687            .as_local_mut()
11688            .and_then(|local| local.language_servers.get_mut(&server_id))
11689        {
11690            for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
11691                diagnostics.refresh_tx.try_send(()).ok();
11692            }
11693        }
11694    }
11695
11696    pub fn pull_workspace_diagnostics_for_buffer(&mut self, buffer_id: BufferId, cx: &mut App) {
11697        let Some(buffer) = self.buffer_store().read(cx).get_existing(buffer_id).ok() else {
11698            return;
11699        };
11700        let Some(local) = self.as_local_mut() else {
11701            return;
11702        };
11703
11704        for server_id in buffer.update(cx, |buffer, cx| {
11705            local.language_server_ids_for_buffer(buffer, cx)
11706        }) {
11707            if let Some(LanguageServerState::Running {
11708                workspace_diagnostics_refresh_tasks,
11709                ..
11710            }) = local.language_servers.get_mut(&server_id)
11711            {
11712                for diagnostics in workspace_diagnostics_refresh_tasks.values_mut() {
11713                    diagnostics.refresh_tx.try_send(()).ok();
11714                }
11715            }
11716        }
11717    }
11718
11719    fn apply_workspace_diagnostic_report(
11720        &mut self,
11721        server_id: LanguageServerId,
11722        report: lsp::WorkspaceDiagnosticReportResult,
11723        cx: &mut Context<Self>,
11724    ) {
11725        let workspace_diagnostics =
11726            GetDocumentDiagnostics::deserialize_workspace_diagnostics_report(report, server_id);
11727        let mut unchanged_buffers = HashSet::default();
11728        let mut changed_buffers = HashSet::default();
11729        let workspace_diagnostics_updates = workspace_diagnostics
11730            .into_iter()
11731            .filter_map(
11732                |workspace_diagnostics| match workspace_diagnostics.diagnostics {
11733                    LspPullDiagnostics::Response {
11734                        server_id,
11735                        uri,
11736                        diagnostics,
11737                    } => Some((server_id, uri, diagnostics, workspace_diagnostics.version)),
11738                    LspPullDiagnostics::Default => None,
11739                },
11740            )
11741            .fold(
11742                HashMap::default(),
11743                |mut acc, (server_id, uri, diagnostics, version)| {
11744                    let (result_id, diagnostics) = match diagnostics {
11745                        PulledDiagnostics::Unchanged { result_id } => {
11746                            unchanged_buffers.insert(uri.clone());
11747                            (Some(result_id), Vec::new())
11748                        }
11749                        PulledDiagnostics::Changed {
11750                            result_id,
11751                            diagnostics,
11752                        } => {
11753                            changed_buffers.insert(uri.clone());
11754                            (result_id, diagnostics)
11755                        }
11756                    };
11757                    let disk_based_sources = Cow::Owned(
11758                        self.language_server_adapter_for_id(server_id)
11759                            .as_ref()
11760                            .map(|adapter| adapter.disk_based_diagnostic_sources.as_slice())
11761                            .unwrap_or(&[])
11762                            .to_vec(),
11763                    );
11764                    acc.entry(server_id)
11765                        .or_insert_with(Vec::new)
11766                        .push(DocumentDiagnosticsUpdate {
11767                            server_id,
11768                            diagnostics: lsp::PublishDiagnosticsParams {
11769                                uri,
11770                                diagnostics,
11771                                version,
11772                            },
11773                            result_id,
11774                            disk_based_sources,
11775                        });
11776                    acc
11777                },
11778            );
11779
11780        for diagnostic_updates in workspace_diagnostics_updates.into_values() {
11781            self.merge_lsp_diagnostics(
11782                DiagnosticSourceKind::Pulled,
11783                diagnostic_updates,
11784                |buffer, old_diagnostic, cx| {
11785                    File::from_dyn(buffer.file())
11786                        .and_then(|file| {
11787                            let abs_path = file.as_local()?.abs_path(cx);
11788                            lsp::Uri::from_file_path(abs_path).ok()
11789                        })
11790                        .is_none_or(|buffer_uri| {
11791                            unchanged_buffers.contains(&buffer_uri)
11792                                || match old_diagnostic.source_kind {
11793                                    DiagnosticSourceKind::Pulled => {
11794                                        !changed_buffers.contains(&buffer_uri)
11795                                    }
11796                                    DiagnosticSourceKind::Other | DiagnosticSourceKind::Pushed => {
11797                                        true
11798                                    }
11799                                }
11800                        })
11801                },
11802                cx,
11803            )
11804            .log_err();
11805        }
11806    }
11807
11808    fn register_server_capabilities(
11809        &mut self,
11810        server_id: LanguageServerId,
11811        params: lsp::RegistrationParams,
11812        cx: &mut Context<Self>,
11813    ) -> anyhow::Result<()> {
11814        let server = self
11815            .language_server_for_id(server_id)
11816            .with_context(|| format!("no server {server_id} found"))?;
11817        for reg in params.registrations {
11818            match reg.method.as_str() {
11819                "workspace/didChangeWatchedFiles" => {
11820                    if let Some(options) = reg.register_options {
11821                        let notify = if let Some(local_lsp_store) = self.as_local_mut() {
11822                            let caps = serde_json::from_value(options)?;
11823                            local_lsp_store
11824                                .on_lsp_did_change_watched_files(server_id, &reg.id, caps, cx);
11825                            true
11826                        } else {
11827                            false
11828                        };
11829                        if notify {
11830                            notify_server_capabilities_updated(&server, cx);
11831                        }
11832                    }
11833                }
11834                "workspace/didChangeConfiguration" => {
11835                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
11836                }
11837                "workspace/didChangeWorkspaceFolders" => {
11838                    // In this case register options is an empty object, we can ignore it
11839                    let caps = lsp::WorkspaceFoldersServerCapabilities {
11840                        supported: Some(true),
11841                        change_notifications: Some(OneOf::Right(reg.id)),
11842                    };
11843                    server.update_capabilities(|capabilities| {
11844                        capabilities
11845                            .workspace
11846                            .get_or_insert_default()
11847                            .workspace_folders = Some(caps);
11848                    });
11849                    notify_server_capabilities_updated(&server, cx);
11850                }
11851                "workspace/symbol" => {
11852                    let options = parse_register_capabilities(reg)?;
11853                    server.update_capabilities(|capabilities| {
11854                        capabilities.workspace_symbol_provider = Some(options);
11855                    });
11856                    notify_server_capabilities_updated(&server, cx);
11857                }
11858                "workspace/fileOperations" => {
11859                    if let Some(options) = reg.register_options {
11860                        let caps = serde_json::from_value(options)?;
11861                        server.update_capabilities(|capabilities| {
11862                            capabilities
11863                                .workspace
11864                                .get_or_insert_default()
11865                                .file_operations = Some(caps);
11866                        });
11867                        notify_server_capabilities_updated(&server, cx);
11868                    }
11869                }
11870                "workspace/executeCommand" => {
11871                    if let Some(options) = reg.register_options {
11872                        let options = serde_json::from_value(options)?;
11873                        server.update_capabilities(|capabilities| {
11874                            capabilities.execute_command_provider = Some(options);
11875                        });
11876                        notify_server_capabilities_updated(&server, cx);
11877                    }
11878                }
11879                "textDocument/rangeFormatting" => {
11880                    let options = parse_register_capabilities(reg)?;
11881                    server.update_capabilities(|capabilities| {
11882                        capabilities.document_range_formatting_provider = Some(options);
11883                    });
11884                    notify_server_capabilities_updated(&server, cx);
11885                }
11886                "textDocument/onTypeFormatting" => {
11887                    if let Some(options) = reg
11888                        .register_options
11889                        .map(serde_json::from_value)
11890                        .transpose()?
11891                    {
11892                        server.update_capabilities(|capabilities| {
11893                            capabilities.document_on_type_formatting_provider = Some(options);
11894                        });
11895                        notify_server_capabilities_updated(&server, cx);
11896                    }
11897                }
11898                "textDocument/formatting" => {
11899                    let options = parse_register_capabilities(reg)?;
11900                    server.update_capabilities(|capabilities| {
11901                        capabilities.document_formatting_provider = Some(options);
11902                    });
11903                    notify_server_capabilities_updated(&server, cx);
11904                }
11905                "textDocument/rename" => {
11906                    let options = parse_register_capabilities(reg)?;
11907                    server.update_capabilities(|capabilities| {
11908                        capabilities.rename_provider = Some(options);
11909                    });
11910                    notify_server_capabilities_updated(&server, cx);
11911                }
11912                "textDocument/inlayHint" => {
11913                    let options = parse_register_capabilities(reg)?;
11914                    server.update_capabilities(|capabilities| {
11915                        capabilities.inlay_hint_provider = Some(options);
11916                    });
11917                    notify_server_capabilities_updated(&server, cx);
11918                }
11919                "textDocument/documentSymbol" => {
11920                    let options = parse_register_capabilities(reg)?;
11921                    server.update_capabilities(|capabilities| {
11922                        capabilities.document_symbol_provider = Some(options);
11923                    });
11924                    notify_server_capabilities_updated(&server, cx);
11925                }
11926                "textDocument/codeAction" => {
11927                    let options = parse_register_capabilities(reg)?;
11928                    let provider = match options {
11929                        OneOf::Left(value) => lsp::CodeActionProviderCapability::Simple(value),
11930                        OneOf::Right(caps) => caps,
11931                    };
11932                    server.update_capabilities(|capabilities| {
11933                        capabilities.code_action_provider = Some(provider);
11934                    });
11935                    notify_server_capabilities_updated(&server, cx);
11936                }
11937                "textDocument/definition" => {
11938                    let options = parse_register_capabilities(reg)?;
11939                    server.update_capabilities(|capabilities| {
11940                        capabilities.definition_provider = Some(options);
11941                    });
11942                    notify_server_capabilities_updated(&server, cx);
11943                }
11944                "textDocument/completion" => {
11945                    if let Some(caps) = reg
11946                        .register_options
11947                        .map(serde_json::from_value::<CompletionOptions>)
11948                        .transpose()?
11949                    {
11950                        server.update_capabilities(|capabilities| {
11951                            capabilities.completion_provider = Some(caps.clone());
11952                        });
11953
11954                        if let Some(local) = self.as_local() {
11955                            let mut buffers_with_language_server = Vec::new();
11956                            for handle in self.buffer_store.read(cx).buffers() {
11957                                let buffer_id = handle.read(cx).remote_id();
11958                                if local
11959                                    .buffers_opened_in_servers
11960                                    .get(&buffer_id)
11961                                    .filter(|s| s.contains(&server_id))
11962                                    .is_some()
11963                                {
11964                                    buffers_with_language_server.push(handle);
11965                                }
11966                            }
11967                            let triggers = caps
11968                                .trigger_characters
11969                                .unwrap_or_default()
11970                                .into_iter()
11971                                .collect::<BTreeSet<_>>();
11972                            for handle in buffers_with_language_server {
11973                                let triggers = triggers.clone();
11974                                let _ = handle.update(cx, move |buffer, cx| {
11975                                    buffer.set_completion_triggers(server_id, triggers, cx);
11976                                });
11977                            }
11978                        }
11979                        notify_server_capabilities_updated(&server, cx);
11980                    }
11981                }
11982                "textDocument/hover" => {
11983                    let options = parse_register_capabilities(reg)?;
11984                    let provider = match options {
11985                        OneOf::Left(value) => lsp::HoverProviderCapability::Simple(value),
11986                        OneOf::Right(caps) => caps,
11987                    };
11988                    server.update_capabilities(|capabilities| {
11989                        capabilities.hover_provider = Some(provider);
11990                    });
11991                    notify_server_capabilities_updated(&server, cx);
11992                }
11993                "textDocument/signatureHelp" => {
11994                    if let Some(caps) = reg
11995                        .register_options
11996                        .map(serde_json::from_value)
11997                        .transpose()?
11998                    {
11999                        server.update_capabilities(|capabilities| {
12000                            capabilities.signature_help_provider = Some(caps);
12001                        });
12002                        notify_server_capabilities_updated(&server, cx);
12003                    }
12004                }
12005                "textDocument/didChange" => {
12006                    if let Some(sync_kind) = reg
12007                        .register_options
12008                        .and_then(|opts| opts.get("syncKind").cloned())
12009                        .map(serde_json::from_value::<lsp::TextDocumentSyncKind>)
12010                        .transpose()?
12011                    {
12012                        server.update_capabilities(|capabilities| {
12013                            let mut sync_options =
12014                                Self::take_text_document_sync_options(capabilities);
12015                            sync_options.change = Some(sync_kind);
12016                            capabilities.text_document_sync =
12017                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12018                        });
12019                        notify_server_capabilities_updated(&server, cx);
12020                    }
12021                }
12022                "textDocument/didSave" => {
12023                    if let Some(include_text) = reg
12024                        .register_options
12025                        .map(|opts| {
12026                            let transpose = opts
12027                                .get("includeText")
12028                                .cloned()
12029                                .map(serde_json::from_value::<Option<bool>>)
12030                                .transpose();
12031                            match transpose {
12032                                Ok(value) => Ok(value.flatten()),
12033                                Err(e) => Err(e),
12034                            }
12035                        })
12036                        .transpose()?
12037                    {
12038                        server.update_capabilities(|capabilities| {
12039                            let mut sync_options =
12040                                Self::take_text_document_sync_options(capabilities);
12041                            sync_options.save =
12042                                Some(TextDocumentSyncSaveOptions::SaveOptions(lsp::SaveOptions {
12043                                    include_text,
12044                                }));
12045                            capabilities.text_document_sync =
12046                                Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12047                        });
12048                        notify_server_capabilities_updated(&server, cx);
12049                    }
12050                }
12051                "textDocument/codeLens" => {
12052                    if let Some(caps) = reg
12053                        .register_options
12054                        .map(serde_json::from_value)
12055                        .transpose()?
12056                    {
12057                        server.update_capabilities(|capabilities| {
12058                            capabilities.code_lens_provider = Some(caps);
12059                        });
12060                        notify_server_capabilities_updated(&server, cx);
12061                    }
12062                }
12063                "textDocument/diagnostic" => {
12064                    if let Some(caps) = reg
12065                        .register_options
12066                        .map(serde_json::from_value::<DiagnosticServerCapabilities>)
12067                        .transpose()?
12068                    {
12069                        let local = self
12070                            .as_local_mut()
12071                            .context("Expected LSP Store to be local")?;
12072                        let state = local
12073                            .language_servers
12074                            .get_mut(&server_id)
12075                            .context("Could not obtain Language Servers state")?;
12076                        local
12077                            .language_server_dynamic_registrations
12078                            .entry(server_id)
12079                            .or_default()
12080                            .diagnostics
12081                            .insert(Some(reg.id.clone()), caps.clone());
12082
12083                        if let LanguageServerState::Running {
12084                            workspace_diagnostics_refresh_tasks,
12085                            ..
12086                        } = state
12087                            && let Some(task) = lsp_workspace_diagnostics_refresh(
12088                                Some(reg.id.clone()),
12089                                caps.clone(),
12090                                server.clone(),
12091                                cx,
12092                            )
12093                        {
12094                            workspace_diagnostics_refresh_tasks.insert(Some(reg.id), task);
12095                        }
12096
12097                        let mut did_update_caps = false;
12098                        server.update_capabilities(|capabilities| {
12099                            if capabilities.diagnostic_provider.as_ref().is_none_or(
12100                                |current_caps| {
12101                                    let supports_workspace_diagnostics =
12102                                        |capabilities: &DiagnosticServerCapabilities| {
12103                                            match capabilities {
12104                                            DiagnosticServerCapabilities::Options(
12105                                                diagnostic_options,
12106                                            ) => diagnostic_options.workspace_diagnostics,
12107                                            DiagnosticServerCapabilities::RegistrationOptions(
12108                                                diagnostic_registration_options,
12109                                            ) => {
12110                                                diagnostic_registration_options
12111                                                    .diagnostic_options
12112                                                    .workspace_diagnostics
12113                                            }
12114                                        }
12115                                        };
12116                                    // We don't actually care about capabilities.diagnostic_provider, but it IS relevant for the remote peer
12117                                    // to know that there's at least one provider. Otherwise, it will never ask us to issue documentdiagnostic calls on their behalf,
12118                                    // as it'll think that they're not supported.
12119                                    // If we did not support any workspace diagnostics up to this point but now do, let's update.
12120                                    !supports_workspace_diagnostics(current_caps)
12121                                        & supports_workspace_diagnostics(&caps)
12122                                },
12123                            ) {
12124                                did_update_caps = true;
12125                                capabilities.diagnostic_provider = Some(caps);
12126                            }
12127                        });
12128                        if did_update_caps {
12129                            notify_server_capabilities_updated(&server, cx);
12130                        }
12131                    }
12132                }
12133                "textDocument/documentColor" => {
12134                    let options = parse_register_capabilities(reg)?;
12135                    let provider = match options {
12136                        OneOf::Left(value) => lsp::ColorProviderCapability::Simple(value),
12137                        OneOf::Right(caps) => caps,
12138                    };
12139                    server.update_capabilities(|capabilities| {
12140                        capabilities.color_provider = Some(provider);
12141                    });
12142                    notify_server_capabilities_updated(&server, cx);
12143                }
12144                _ => log::warn!("unhandled capability registration: {reg:?}"),
12145            }
12146        }
12147
12148        Ok(())
12149    }
12150
12151    fn unregister_server_capabilities(
12152        &mut self,
12153        server_id: LanguageServerId,
12154        params: lsp::UnregistrationParams,
12155        cx: &mut Context<Self>,
12156    ) -> anyhow::Result<()> {
12157        let server = self
12158            .language_server_for_id(server_id)
12159            .with_context(|| format!("no server {server_id} found"))?;
12160        for unreg in params.unregisterations.iter() {
12161            match unreg.method.as_str() {
12162                "workspace/didChangeWatchedFiles" => {
12163                    let notify = if let Some(local_lsp_store) = self.as_local_mut() {
12164                        local_lsp_store
12165                            .on_lsp_unregister_did_change_watched_files(server_id, &unreg.id, cx);
12166                        true
12167                    } else {
12168                        false
12169                    };
12170                    if notify {
12171                        notify_server_capabilities_updated(&server, cx);
12172                    }
12173                }
12174                "workspace/didChangeConfiguration" => {
12175                    // Ignore payload since we notify clients of setting changes unconditionally, relying on them pulling the latest settings.
12176                }
12177                "workspace/didChangeWorkspaceFolders" => {
12178                    server.update_capabilities(|capabilities| {
12179                        capabilities
12180                            .workspace
12181                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12182                                workspace_folders: None,
12183                                file_operations: None,
12184                            })
12185                            .workspace_folders = None;
12186                    });
12187                    notify_server_capabilities_updated(&server, cx);
12188                }
12189                "workspace/symbol" => {
12190                    server.update_capabilities(|capabilities| {
12191                        capabilities.workspace_symbol_provider = None
12192                    });
12193                    notify_server_capabilities_updated(&server, cx);
12194                }
12195                "workspace/fileOperations" => {
12196                    server.update_capabilities(|capabilities| {
12197                        capabilities
12198                            .workspace
12199                            .get_or_insert_with(|| lsp::WorkspaceServerCapabilities {
12200                                workspace_folders: None,
12201                                file_operations: None,
12202                            })
12203                            .file_operations = None;
12204                    });
12205                    notify_server_capabilities_updated(&server, cx);
12206                }
12207                "workspace/executeCommand" => {
12208                    server.update_capabilities(|capabilities| {
12209                        capabilities.execute_command_provider = None;
12210                    });
12211                    notify_server_capabilities_updated(&server, cx);
12212                }
12213                "textDocument/rangeFormatting" => {
12214                    server.update_capabilities(|capabilities| {
12215                        capabilities.document_range_formatting_provider = None
12216                    });
12217                    notify_server_capabilities_updated(&server, cx);
12218                }
12219                "textDocument/onTypeFormatting" => {
12220                    server.update_capabilities(|capabilities| {
12221                        capabilities.document_on_type_formatting_provider = None;
12222                    });
12223                    notify_server_capabilities_updated(&server, cx);
12224                }
12225                "textDocument/formatting" => {
12226                    server.update_capabilities(|capabilities| {
12227                        capabilities.document_formatting_provider = None;
12228                    });
12229                    notify_server_capabilities_updated(&server, cx);
12230                }
12231                "textDocument/rename" => {
12232                    server.update_capabilities(|capabilities| capabilities.rename_provider = None);
12233                    notify_server_capabilities_updated(&server, cx);
12234                }
12235                "textDocument/codeAction" => {
12236                    server.update_capabilities(|capabilities| {
12237                        capabilities.code_action_provider = None;
12238                    });
12239                    notify_server_capabilities_updated(&server, cx);
12240                }
12241                "textDocument/definition" => {
12242                    server.update_capabilities(|capabilities| {
12243                        capabilities.definition_provider = None;
12244                    });
12245                    notify_server_capabilities_updated(&server, cx);
12246                }
12247                "textDocument/completion" => {
12248                    server.update_capabilities(|capabilities| {
12249                        capabilities.completion_provider = None;
12250                    });
12251                    notify_server_capabilities_updated(&server, cx);
12252                }
12253                "textDocument/hover" => {
12254                    server.update_capabilities(|capabilities| {
12255                        capabilities.hover_provider = None;
12256                    });
12257                    notify_server_capabilities_updated(&server, cx);
12258                }
12259                "textDocument/signatureHelp" => {
12260                    server.update_capabilities(|capabilities| {
12261                        capabilities.signature_help_provider = None;
12262                    });
12263                    notify_server_capabilities_updated(&server, cx);
12264                }
12265                "textDocument/didChange" => {
12266                    server.update_capabilities(|capabilities| {
12267                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12268                        sync_options.change = None;
12269                        capabilities.text_document_sync =
12270                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12271                    });
12272                    notify_server_capabilities_updated(&server, cx);
12273                }
12274                "textDocument/didSave" => {
12275                    server.update_capabilities(|capabilities| {
12276                        let mut sync_options = Self::take_text_document_sync_options(capabilities);
12277                        sync_options.save = None;
12278                        capabilities.text_document_sync =
12279                            Some(lsp::TextDocumentSyncCapability::Options(sync_options));
12280                    });
12281                    notify_server_capabilities_updated(&server, cx);
12282                }
12283                "textDocument/codeLens" => {
12284                    server.update_capabilities(|capabilities| {
12285                        capabilities.code_lens_provider = None;
12286                    });
12287                    notify_server_capabilities_updated(&server, cx);
12288                }
12289                "textDocument/diagnostic" => {
12290                    let local = self
12291                        .as_local_mut()
12292                        .context("Expected LSP Store to be local")?;
12293
12294                    let state = local
12295                        .language_servers
12296                        .get_mut(&server_id)
12297                        .context("Could not obtain Language Servers state")?;
12298                    let options = local
12299                        .language_server_dynamic_registrations
12300                        .get_mut(&server_id)
12301                        .with_context(|| {
12302                            format!("Expected dynamic registration to exist for server {server_id}")
12303                        })?.diagnostics
12304                        .remove(&Some(unreg.id.clone()))
12305                        .with_context(|| format!(
12306                            "Attempted to unregister non-existent diagnostic registration with ID {}",
12307                            unreg.id)
12308                        )?;
12309
12310                    let mut has_any_diagnostic_providers_still = true;
12311                    if let Some(identifier) = diagnostic_identifier(&options)
12312                        && let LanguageServerState::Running {
12313                            workspace_diagnostics_refresh_tasks,
12314                            ..
12315                        } = state
12316                    {
12317                        workspace_diagnostics_refresh_tasks.remove(&identifier);
12318                        has_any_diagnostic_providers_still =
12319                            !workspace_diagnostics_refresh_tasks.is_empty();
12320                    }
12321
12322                    if !has_any_diagnostic_providers_still {
12323                        server.update_capabilities(|capabilities| {
12324                            debug_assert!(capabilities.diagnostic_provider.is_some());
12325                            capabilities.diagnostic_provider = None;
12326                        });
12327                    }
12328
12329                    notify_server_capabilities_updated(&server, cx);
12330                }
12331                "textDocument/documentColor" => {
12332                    server.update_capabilities(|capabilities| {
12333                        capabilities.color_provider = None;
12334                    });
12335                    notify_server_capabilities_updated(&server, cx);
12336                }
12337                _ => log::warn!("unhandled capability unregistration: {unreg:?}"),
12338            }
12339        }
12340
12341        Ok(())
12342    }
12343
12344    async fn deduplicate_range_based_lsp_requests<T>(
12345        lsp_store: &Entity<Self>,
12346        server_id: Option<LanguageServerId>,
12347        lsp_request_id: LspRequestId,
12348        proto_request: &T::ProtoRequest,
12349        range: Range<Anchor>,
12350        cx: &mut AsyncApp,
12351    ) -> Result<()>
12352    where
12353        T: LspCommand,
12354        T::ProtoRequest: proto::LspRequestMessage,
12355    {
12356        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12357        let version = deserialize_version(proto_request.buffer_version());
12358        let buffer = lsp_store.update(cx, |this, cx| {
12359            this.buffer_store.read(cx).get_existing(buffer_id)
12360        })??;
12361        buffer
12362            .update(cx, |buffer, _| buffer.wait_for_version(version))?
12363            .await?;
12364        lsp_store.update(cx, |lsp_store, cx| {
12365            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12366            let chunks_queried_for = lsp_data
12367                .inlay_hints
12368                .applicable_chunks(&[range])
12369                .collect::<Vec<_>>();
12370            match chunks_queried_for.as_slice() {
12371                &[chunk] => {
12372                    let key = LspKey {
12373                        request_type: TypeId::of::<T>(),
12374                        server_queried: server_id,
12375                    };
12376                    let previous_request = lsp_data
12377                        .chunk_lsp_requests
12378                        .entry(key)
12379                        .or_default()
12380                        .insert(chunk, lsp_request_id);
12381                    if let Some((previous_request, running_requests)) =
12382                        previous_request.zip(lsp_data.lsp_requests.get_mut(&key))
12383                    {
12384                        running_requests.remove(&previous_request);
12385                    }
12386                }
12387                _ambiguous_chunks => {
12388                    // Have not found a unique chunk for the query range — be lenient and let the query to be spawned,
12389                    // there, a buffer version-based check will be performed and outdated requests discarded.
12390                }
12391            }
12392            anyhow::Ok(())
12393        })??;
12394
12395        Ok(())
12396    }
12397
12398    async fn query_lsp_locally<T>(
12399        lsp_store: Entity<Self>,
12400        for_server_id: Option<LanguageServerId>,
12401        sender_id: proto::PeerId,
12402        lsp_request_id: LspRequestId,
12403        proto_request: T::ProtoRequest,
12404        position: Option<Anchor>,
12405        cx: &mut AsyncApp,
12406    ) -> Result<()>
12407    where
12408        T: LspCommand + Clone,
12409        T::ProtoRequest: proto::LspRequestMessage,
12410        <T::ProtoRequest as proto::RequestMessage>::Response:
12411            Into<<T::ProtoRequest as proto::LspRequestMessage>::Response>,
12412    {
12413        let buffer_id = BufferId::new(proto_request.buffer_id())?;
12414        let version = deserialize_version(proto_request.buffer_version());
12415        let buffer = lsp_store.update(cx, |this, cx| {
12416            this.buffer_store.read(cx).get_existing(buffer_id)
12417        })??;
12418        buffer
12419            .update(cx, |buffer, _| buffer.wait_for_version(version.clone()))?
12420            .await?;
12421        let buffer_version = buffer.read_with(cx, |buffer, _| buffer.version())?;
12422        let request =
12423            T::from_proto(proto_request, lsp_store.clone(), buffer.clone(), cx.clone()).await?;
12424        let key = LspKey {
12425            request_type: TypeId::of::<T>(),
12426            server_queried: for_server_id,
12427        };
12428        lsp_store.update(cx, |lsp_store, cx| {
12429            let request_task = match for_server_id {
12430                Some(server_id) => {
12431                    let server_task = lsp_store.request_lsp(
12432                        buffer.clone(),
12433                        LanguageServerToQuery::Other(server_id),
12434                        request.clone(),
12435                        cx,
12436                    );
12437                    cx.background_spawn(async move {
12438                        let mut responses = Vec::new();
12439                        match server_task.await {
12440                            Ok(response) => responses.push((server_id, response)),
12441                            // rust-analyzer likes to error with this when its still loading up
12442                            Err(e) if format!("{e:#}").ends_with("content modified") => (),
12443                            Err(e) => log::error!(
12444                                "Error handling response for request {request:?}: {e:#}"
12445                            ),
12446                        }
12447                        responses
12448                    })
12449                }
12450                None => lsp_store.request_multiple_lsp_locally(&buffer, position, request, cx),
12451            };
12452            let lsp_data = lsp_store.latest_lsp_data(&buffer, cx);
12453            if T::ProtoRequest::stop_previous_requests() {
12454                if let Some(lsp_requests) = lsp_data.lsp_requests.get_mut(&key) {
12455                    lsp_requests.clear();
12456                }
12457            }
12458            lsp_data.lsp_requests.entry(key).or_default().insert(
12459                lsp_request_id,
12460                cx.spawn(async move |lsp_store, cx| {
12461                    let response = request_task.await;
12462                    lsp_store
12463                        .update(cx, |lsp_store, cx| {
12464                            if let Some((client, project_id)) = lsp_store.downstream_client.clone()
12465                            {
12466                                let response = response
12467                                    .into_iter()
12468                                    .map(|(server_id, response)| {
12469                                        (
12470                                            server_id.to_proto(),
12471                                            T::response_to_proto(
12472                                                response,
12473                                                lsp_store,
12474                                                sender_id,
12475                                                &buffer_version,
12476                                                cx,
12477                                            )
12478                                            .into(),
12479                                        )
12480                                    })
12481                                    .collect::<HashMap<_, _>>();
12482                                match client.send_lsp_response::<T::ProtoRequest>(
12483                                    project_id,
12484                                    lsp_request_id,
12485                                    response,
12486                                ) {
12487                                    Ok(()) => {}
12488                                    Err(e) => {
12489                                        log::error!("Failed to send LSP response: {e:#}",)
12490                                    }
12491                                }
12492                            }
12493                        })
12494                        .ok();
12495                }),
12496            );
12497        })?;
12498        Ok(())
12499    }
12500
12501    fn take_text_document_sync_options(
12502        capabilities: &mut lsp::ServerCapabilities,
12503    ) -> lsp::TextDocumentSyncOptions {
12504        match capabilities.text_document_sync.take() {
12505            Some(lsp::TextDocumentSyncCapability::Options(sync_options)) => sync_options,
12506            Some(lsp::TextDocumentSyncCapability::Kind(sync_kind)) => {
12507                let mut sync_options = lsp::TextDocumentSyncOptions::default();
12508                sync_options.change = Some(sync_kind);
12509                sync_options
12510            }
12511            None => lsp::TextDocumentSyncOptions::default(),
12512        }
12513    }
12514
12515    #[cfg(any(test, feature = "test-support"))]
12516    pub fn forget_code_lens_task(&mut self, buffer_id: BufferId) -> Option<CodeLensTask> {
12517        Some(
12518            self.lsp_data
12519                .get_mut(&buffer_id)?
12520                .code_lens
12521                .take()?
12522                .update
12523                .take()?
12524                .1,
12525        )
12526    }
12527
12528    pub fn downstream_client(&self) -> Option<(AnyProtoClient, u64)> {
12529        self.downstream_client.clone()
12530    }
12531
12532    pub fn worktree_store(&self) -> Entity<WorktreeStore> {
12533        self.worktree_store.clone()
12534    }
12535
12536    /// Gets what's stored in the LSP data for the given buffer.
12537    pub fn current_lsp_data(&mut self, buffer_id: BufferId) -> Option<&mut BufferLspData> {
12538        self.lsp_data.get_mut(&buffer_id)
12539    }
12540
12541    /// Gets the most recent LSP data for the given buffer: if the data is absent or out of date,
12542    /// new [`BufferLspData`] will be created to replace the previous state.
12543    pub fn latest_lsp_data(&mut self, buffer: &Entity<Buffer>, cx: &mut App) -> &mut BufferLspData {
12544        let (buffer_id, buffer_version) =
12545            buffer.read_with(cx, |buffer, _| (buffer.remote_id(), buffer.version()));
12546        let lsp_data = self
12547            .lsp_data
12548            .entry(buffer_id)
12549            .or_insert_with(|| BufferLspData::new(buffer, cx));
12550        if buffer_version.changed_since(&lsp_data.buffer_version) {
12551            *lsp_data = BufferLspData::new(buffer, cx);
12552        }
12553        lsp_data
12554    }
12555}
12556
12557// Registration with registerOptions as null, should fallback to true.
12558// https://github.com/microsoft/vscode-languageserver-node/blob/d90a87f9557a0df9142cfb33e251cfa6fe27d970/client/src/common/client.ts#L2133
12559fn parse_register_capabilities<T: serde::de::DeserializeOwned>(
12560    reg: lsp::Registration,
12561) -> Result<OneOf<bool, T>> {
12562    Ok(match reg.register_options {
12563        Some(options) => OneOf::Right(serde_json::from_value::<T>(options)?),
12564        None => OneOf::Left(true),
12565    })
12566}
12567
12568fn subscribe_to_binary_statuses(
12569    languages: &Arc<LanguageRegistry>,
12570    cx: &mut Context<'_, LspStore>,
12571) -> Task<()> {
12572    let mut server_statuses = languages.language_server_binary_statuses();
12573    cx.spawn(async move |lsp_store, cx| {
12574        while let Some((server_name, binary_status)) = server_statuses.next().await {
12575            if lsp_store
12576                .update(cx, |_, cx| {
12577                    let mut message = None;
12578                    let binary_status = match binary_status {
12579                        BinaryStatus::None => proto::ServerBinaryStatus::None,
12580                        BinaryStatus::CheckingForUpdate => {
12581                            proto::ServerBinaryStatus::CheckingForUpdate
12582                        }
12583                        BinaryStatus::Downloading => proto::ServerBinaryStatus::Downloading,
12584                        BinaryStatus::Starting => proto::ServerBinaryStatus::Starting,
12585                        BinaryStatus::Stopping => proto::ServerBinaryStatus::Stopping,
12586                        BinaryStatus::Stopped => proto::ServerBinaryStatus::Stopped,
12587                        BinaryStatus::Failed { error } => {
12588                            message = Some(error);
12589                            proto::ServerBinaryStatus::Failed
12590                        }
12591                    };
12592                    cx.emit(LspStoreEvent::LanguageServerUpdate {
12593                        // Binary updates are about the binary that might not have any language server id at that point.
12594                        // Reuse `LanguageServerUpdate` for them and provide a fake id that won't be used on the receiver side.
12595                        language_server_id: LanguageServerId(0),
12596                        name: Some(server_name),
12597                        message: proto::update_language_server::Variant::StatusUpdate(
12598                            proto::StatusUpdate {
12599                                message,
12600                                status: Some(proto::status_update::Status::Binary(
12601                                    binary_status as i32,
12602                                )),
12603                            },
12604                        ),
12605                    });
12606                })
12607                .is_err()
12608            {
12609                break;
12610            }
12611        }
12612    })
12613}
12614
12615fn lsp_workspace_diagnostics_refresh(
12616    registration_id: Option<String>,
12617    options: DiagnosticServerCapabilities,
12618    server: Arc<LanguageServer>,
12619    cx: &mut Context<'_, LspStore>,
12620) -> Option<WorkspaceRefreshTask> {
12621    let identifier = diagnostic_identifier(&options)?;
12622
12623    let (progress_tx, mut progress_rx) = mpsc::channel(1);
12624    let (mut refresh_tx, mut refresh_rx) = mpsc::channel(1);
12625    refresh_tx.try_send(()).ok();
12626
12627    let workspace_query_language_server = cx.spawn(async move |lsp_store, cx| {
12628        let mut attempts = 0;
12629        let max_attempts = 50;
12630        let mut requests = 0;
12631
12632        loop {
12633            let Some(()) = refresh_rx.recv().await else {
12634                return;
12635            };
12636
12637            'request: loop {
12638                requests += 1;
12639                if attempts > max_attempts {
12640                    log::error!(
12641                        "Failed to pull workspace diagnostics {max_attempts} times, aborting"
12642                    );
12643                    return;
12644                }
12645                let backoff_millis = (50 * (1 << attempts)).clamp(30, 1000);
12646                cx.background_executor()
12647                    .timer(Duration::from_millis(backoff_millis))
12648                    .await;
12649                attempts += 1;
12650
12651                let Ok(previous_result_ids) = lsp_store.update(cx, |lsp_store, _| {
12652                    lsp_store
12653                        .all_result_ids(server.server_id())
12654                        .into_iter()
12655                        .filter_map(|(abs_path, result_id)| {
12656                            let uri = file_path_to_lsp_url(&abs_path).ok()?;
12657                            Some(lsp::PreviousResultId {
12658                                uri,
12659                                value: result_id,
12660                            })
12661                        })
12662                        .collect()
12663                }) else {
12664                    return;
12665                };
12666
12667                let token = if let Some(identifier) = &registration_id {
12668                    format!(
12669                        "workspace/diagnostic/{}/{requests}/{WORKSPACE_DIAGNOSTICS_TOKEN_START}{identifier}",
12670                        server.server_id(),
12671                    )
12672                } else {
12673                    format!("workspace/diagnostic/{}/{requests}", server.server_id())
12674                };
12675
12676                progress_rx.try_recv().ok();
12677                let timer =
12678                    LanguageServer::default_request_timer(cx.background_executor().clone()).fuse();
12679                let progress = pin!(progress_rx.recv().fuse());
12680                let response_result = server
12681                    .request_with_timer::<lsp::WorkspaceDiagnosticRequest, _>(
12682                        lsp::WorkspaceDiagnosticParams {
12683                            previous_result_ids,
12684                            identifier: identifier.clone(),
12685                            work_done_progress_params: Default::default(),
12686                            partial_result_params: lsp::PartialResultParams {
12687                                partial_result_token: Some(lsp::ProgressToken::String(token)),
12688                            },
12689                        },
12690                        select(timer, progress).then(|either| match either {
12691                            Either::Left((message, ..)) => ready(message).left_future(),
12692                            Either::Right(..) => pending::<String>().right_future(),
12693                        }),
12694                    )
12695                    .await;
12696
12697                // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic_refresh
12698                // >  If a server closes a workspace diagnostic pull request the client should re-trigger the request.
12699                match response_result {
12700                    ConnectionResult::Timeout => {
12701                        log::error!("Timeout during workspace diagnostics pull");
12702                        continue 'request;
12703                    }
12704                    ConnectionResult::ConnectionReset => {
12705                        log::error!("Server closed a workspace diagnostics pull request");
12706                        continue 'request;
12707                    }
12708                    ConnectionResult::Result(Err(e)) => {
12709                        log::error!("Error during workspace diagnostics pull: {e:#}");
12710                        break 'request;
12711                    }
12712                    ConnectionResult::Result(Ok(pulled_diagnostics)) => {
12713                        attempts = 0;
12714                        if lsp_store
12715                            .update(cx, |lsp_store, cx| {
12716                                lsp_store.apply_workspace_diagnostic_report(
12717                                    server.server_id(),
12718                                    pulled_diagnostics,
12719                                    cx,
12720                                )
12721                            })
12722                            .is_err()
12723                        {
12724                            return;
12725                        }
12726                        break 'request;
12727                    }
12728                }
12729            }
12730        }
12731    });
12732
12733    Some(WorkspaceRefreshTask {
12734        refresh_tx,
12735        progress_tx,
12736        task: workspace_query_language_server,
12737    })
12738}
12739
12740fn diagnostic_identifier(options: &DiagnosticServerCapabilities) -> Option<Option<String>> {
12741    match &options {
12742        lsp::DiagnosticServerCapabilities::Options(diagnostic_options) => {
12743            if !diagnostic_options.workspace_diagnostics {
12744                return None;
12745            }
12746            Some(diagnostic_options.identifier.clone())
12747        }
12748        lsp::DiagnosticServerCapabilities::RegistrationOptions(registration_options) => {
12749            let diagnostic_options = &registration_options.diagnostic_options;
12750            if !diagnostic_options.workspace_diagnostics {
12751                return None;
12752            }
12753            Some(diagnostic_options.identifier.clone())
12754        }
12755    }
12756}
12757
12758fn resolve_word_completion(snapshot: &BufferSnapshot, completion: &mut Completion) {
12759    let CompletionSource::BufferWord {
12760        word_range,
12761        resolved,
12762    } = &mut completion.source
12763    else {
12764        return;
12765    };
12766    if *resolved {
12767        return;
12768    }
12769
12770    if completion.new_text
12771        != snapshot
12772            .text_for_range(word_range.clone())
12773            .collect::<String>()
12774    {
12775        return;
12776    }
12777
12778    let mut offset = 0;
12779    for chunk in snapshot.chunks(word_range.clone(), true) {
12780        let end_offset = offset + chunk.text.len();
12781        if let Some(highlight_id) = chunk.syntax_highlight_id {
12782            completion
12783                .label
12784                .runs
12785                .push((offset..end_offset, highlight_id));
12786        }
12787        offset = end_offset;
12788    }
12789    *resolved = true;
12790}
12791
12792impl EventEmitter<LspStoreEvent> for LspStore {}
12793
12794fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
12795    hover
12796        .contents
12797        .retain(|hover_block| !hover_block.text.trim().is_empty());
12798    if hover.contents.is_empty() {
12799        None
12800    } else {
12801        Some(hover)
12802    }
12803}
12804
12805async fn populate_labels_for_completions(
12806    new_completions: Vec<CoreCompletion>,
12807    language: Option<Arc<Language>>,
12808    lsp_adapter: Option<Arc<CachedLspAdapter>>,
12809) -> Vec<Completion> {
12810    let lsp_completions = new_completions
12811        .iter()
12812        .filter_map(|new_completion| {
12813            new_completion
12814                .source
12815                .lsp_completion(true)
12816                .map(|lsp_completion| lsp_completion.into_owned())
12817        })
12818        .collect::<Vec<_>>();
12819
12820    let mut labels = if let Some((language, lsp_adapter)) = language.as_ref().zip(lsp_adapter) {
12821        lsp_adapter
12822            .labels_for_completions(&lsp_completions, language)
12823            .await
12824            .log_err()
12825            .unwrap_or_default()
12826    } else {
12827        Vec::new()
12828    }
12829    .into_iter()
12830    .fuse();
12831
12832    let mut completions = Vec::new();
12833    for completion in new_completions {
12834        match completion.source.lsp_completion(true) {
12835            Some(lsp_completion) => {
12836                let documentation = lsp_completion.documentation.clone().map(|docs| docs.into());
12837
12838                let mut label = labels.next().flatten().unwrap_or_else(|| {
12839                    CodeLabel::fallback_for_completion(&lsp_completion, language.as_deref())
12840                });
12841                ensure_uniform_list_compatible_label(&mut label);
12842                completions.push(Completion {
12843                    label,
12844                    documentation,
12845                    replace_range: completion.replace_range,
12846                    new_text: completion.new_text,
12847                    insert_text_mode: lsp_completion.insert_text_mode,
12848                    source: completion.source,
12849                    icon_path: None,
12850                    confirm: None,
12851                });
12852            }
12853            None => {
12854                let mut label = CodeLabel::plain(completion.new_text.clone(), None);
12855                ensure_uniform_list_compatible_label(&mut label);
12856                completions.push(Completion {
12857                    label,
12858                    documentation: None,
12859                    replace_range: completion.replace_range,
12860                    new_text: completion.new_text,
12861                    source: completion.source,
12862                    insert_text_mode: None,
12863                    icon_path: None,
12864                    confirm: None,
12865                });
12866            }
12867        }
12868    }
12869    completions
12870}
12871
12872#[derive(Debug)]
12873pub enum LanguageServerToQuery {
12874    /// Query language servers in order of users preference, up until one capable of handling the request is found.
12875    FirstCapable,
12876    /// Query a specific language server.
12877    Other(LanguageServerId),
12878}
12879
12880#[derive(Default)]
12881struct RenamePathsWatchedForServer {
12882    did_rename: Vec<RenameActionPredicate>,
12883    will_rename: Vec<RenameActionPredicate>,
12884}
12885
12886impl RenamePathsWatchedForServer {
12887    fn with_did_rename_patterns(
12888        mut self,
12889        did_rename: Option<&FileOperationRegistrationOptions>,
12890    ) -> Self {
12891        if let Some(did_rename) = did_rename {
12892            self.did_rename = did_rename
12893                .filters
12894                .iter()
12895                .filter_map(|filter| filter.try_into().log_err())
12896                .collect();
12897        }
12898        self
12899    }
12900    fn with_will_rename_patterns(
12901        mut self,
12902        will_rename: Option<&FileOperationRegistrationOptions>,
12903    ) -> Self {
12904        if let Some(will_rename) = will_rename {
12905            self.will_rename = will_rename
12906                .filters
12907                .iter()
12908                .filter_map(|filter| filter.try_into().log_err())
12909                .collect();
12910        }
12911        self
12912    }
12913
12914    fn should_send_did_rename(&self, path: &str, is_dir: bool) -> bool {
12915        self.did_rename.iter().any(|pred| pred.eval(path, is_dir))
12916    }
12917    fn should_send_will_rename(&self, path: &str, is_dir: bool) -> bool {
12918        self.will_rename.iter().any(|pred| pred.eval(path, is_dir))
12919    }
12920}
12921
12922impl TryFrom<&FileOperationFilter> for RenameActionPredicate {
12923    type Error = globset::Error;
12924    fn try_from(ops: &FileOperationFilter) -> Result<Self, globset::Error> {
12925        Ok(Self {
12926            kind: ops.pattern.matches.clone(),
12927            glob: GlobBuilder::new(&ops.pattern.glob)
12928                .case_insensitive(
12929                    ops.pattern
12930                        .options
12931                        .as_ref()
12932                        .is_some_and(|ops| ops.ignore_case.unwrap_or(false)),
12933                )
12934                .build()?
12935                .compile_matcher(),
12936        })
12937    }
12938}
12939struct RenameActionPredicate {
12940    glob: GlobMatcher,
12941    kind: Option<FileOperationPatternKind>,
12942}
12943
12944impl RenameActionPredicate {
12945    // Returns true if language server should be notified
12946    fn eval(&self, path: &str, is_dir: bool) -> bool {
12947        self.kind.as_ref().is_none_or(|kind| {
12948            let expected_kind = if is_dir {
12949                FileOperationPatternKind::Folder
12950            } else {
12951                FileOperationPatternKind::File
12952            };
12953            kind == &expected_kind
12954        }) && self.glob.is_match(path)
12955    }
12956}
12957
12958#[derive(Default)]
12959struct LanguageServerWatchedPaths {
12960    worktree_paths: HashMap<WorktreeId, GlobSet>,
12961    abs_paths: HashMap<Arc<Path>, (GlobSet, Task<()>)>,
12962}
12963
12964#[derive(Default)]
12965struct LanguageServerWatchedPathsBuilder {
12966    worktree_paths: HashMap<WorktreeId, GlobSet>,
12967    abs_paths: HashMap<Arc<Path>, GlobSet>,
12968}
12969
12970impl LanguageServerWatchedPathsBuilder {
12971    fn watch_worktree(&mut self, worktree_id: WorktreeId, glob_set: GlobSet) {
12972        self.worktree_paths.insert(worktree_id, glob_set);
12973    }
12974    fn watch_abs_path(&mut self, path: Arc<Path>, glob_set: GlobSet) {
12975        self.abs_paths.insert(path, glob_set);
12976    }
12977    fn build(
12978        self,
12979        fs: Arc<dyn Fs>,
12980        language_server_id: LanguageServerId,
12981        cx: &mut Context<LspStore>,
12982    ) -> LanguageServerWatchedPaths {
12983        let lsp_store = cx.weak_entity();
12984
12985        const LSP_ABS_PATH_OBSERVE: Duration = Duration::from_millis(100);
12986        let abs_paths = self
12987            .abs_paths
12988            .into_iter()
12989            .map(|(abs_path, globset)| {
12990                let task = cx.spawn({
12991                    let abs_path = abs_path.clone();
12992                    let fs = fs.clone();
12993
12994                    let lsp_store = lsp_store.clone();
12995                    async move |_, cx| {
12996                        maybe!(async move {
12997                            let mut push_updates = fs.watch(&abs_path, LSP_ABS_PATH_OBSERVE).await;
12998                            while let Some(update) = push_updates.0.next().await {
12999                                let action = lsp_store
13000                                    .update(cx, |this, _| {
13001                                        let Some(local) = this.as_local() else {
13002                                            return ControlFlow::Break(());
13003                                        };
13004                                        let Some(watcher) = local
13005                                            .language_server_watched_paths
13006                                            .get(&language_server_id)
13007                                        else {
13008                                            return ControlFlow::Break(());
13009                                        };
13010                                        let (globs, _) = watcher.abs_paths.get(&abs_path).expect(
13011                                            "Watched abs path is not registered with a watcher",
13012                                        );
13013                                        let matching_entries = update
13014                                            .into_iter()
13015                                            .filter(|event| globs.is_match(&event.path))
13016                                            .collect::<Vec<_>>();
13017                                        this.lsp_notify_abs_paths_changed(
13018                                            language_server_id,
13019                                            matching_entries,
13020                                        );
13021                                        ControlFlow::Continue(())
13022                                    })
13023                                    .ok()?;
13024
13025                                if action.is_break() {
13026                                    break;
13027                                }
13028                            }
13029                            Some(())
13030                        })
13031                        .await;
13032                    }
13033                });
13034                (abs_path, (globset, task))
13035            })
13036            .collect();
13037        LanguageServerWatchedPaths {
13038            worktree_paths: self.worktree_paths,
13039            abs_paths,
13040        }
13041    }
13042}
13043
13044struct LspBufferSnapshot {
13045    version: i32,
13046    snapshot: TextBufferSnapshot,
13047}
13048
13049/// A prompt requested by LSP server.
13050#[derive(Clone, Debug)]
13051pub struct LanguageServerPromptRequest {
13052    pub level: PromptLevel,
13053    pub message: String,
13054    pub actions: Vec<MessageActionItem>,
13055    pub lsp_name: String,
13056    pub(crate) response_channel: Sender<MessageActionItem>,
13057}
13058
13059impl LanguageServerPromptRequest {
13060    pub async fn respond(self, index: usize) -> Option<()> {
13061        if let Some(response) = self.actions.into_iter().nth(index) {
13062            self.response_channel.send(response).await.ok()
13063        } else {
13064            None
13065        }
13066    }
13067}
13068impl PartialEq for LanguageServerPromptRequest {
13069    fn eq(&self, other: &Self) -> bool {
13070        self.message == other.message && self.actions == other.actions
13071    }
13072}
13073
13074#[derive(Clone, Debug, PartialEq)]
13075pub enum LanguageServerLogType {
13076    Log(MessageType),
13077    Trace { verbose_info: Option<String> },
13078    Rpc { received: bool },
13079}
13080
13081impl LanguageServerLogType {
13082    pub fn to_proto(&self) -> proto::language_server_log::LogType {
13083        match self {
13084            Self::Log(log_type) => {
13085                use proto::log_message::LogLevel;
13086                let level = match *log_type {
13087                    MessageType::ERROR => LogLevel::Error,
13088                    MessageType::WARNING => LogLevel::Warning,
13089                    MessageType::INFO => LogLevel::Info,
13090                    MessageType::LOG => LogLevel::Log,
13091                    other => {
13092                        log::warn!("Unknown lsp log message type: {other:?}");
13093                        LogLevel::Log
13094                    }
13095                };
13096                proto::language_server_log::LogType::Log(proto::LogMessage {
13097                    level: level as i32,
13098                })
13099            }
13100            Self::Trace { verbose_info } => {
13101                proto::language_server_log::LogType::Trace(proto::TraceMessage {
13102                    verbose_info: verbose_info.to_owned(),
13103                })
13104            }
13105            Self::Rpc { received } => {
13106                let kind = if *received {
13107                    proto::rpc_message::Kind::Received
13108                } else {
13109                    proto::rpc_message::Kind::Sent
13110                };
13111                let kind = kind as i32;
13112                proto::language_server_log::LogType::Rpc(proto::RpcMessage { kind })
13113            }
13114        }
13115    }
13116
13117    pub fn from_proto(log_type: proto::language_server_log::LogType) -> Self {
13118        use proto::log_message::LogLevel;
13119        use proto::rpc_message;
13120        match log_type {
13121            proto::language_server_log::LogType::Log(message_type) => Self::Log(
13122                match LogLevel::from_i32(message_type.level).unwrap_or(LogLevel::Log) {
13123                    LogLevel::Error => MessageType::ERROR,
13124                    LogLevel::Warning => MessageType::WARNING,
13125                    LogLevel::Info => MessageType::INFO,
13126                    LogLevel::Log => MessageType::LOG,
13127                },
13128            ),
13129            proto::language_server_log::LogType::Trace(trace_message) => Self::Trace {
13130                verbose_info: trace_message.verbose_info,
13131            },
13132            proto::language_server_log::LogType::Rpc(message) => Self::Rpc {
13133                received: match rpc_message::Kind::from_i32(message.kind)
13134                    .unwrap_or(rpc_message::Kind::Received)
13135                {
13136                    rpc_message::Kind::Received => true,
13137                    rpc_message::Kind::Sent => false,
13138                },
13139            },
13140        }
13141    }
13142}
13143
13144pub struct WorkspaceRefreshTask {
13145    refresh_tx: mpsc::Sender<()>,
13146    progress_tx: mpsc::Sender<()>,
13147    #[allow(dead_code)]
13148    task: Task<()>,
13149}
13150
13151pub enum LanguageServerState {
13152    Starting {
13153        startup: Task<Option<Arc<LanguageServer>>>,
13154        /// List of language servers that will be added to the workspace once it's initialization completes.
13155        pending_workspace_folders: Arc<Mutex<BTreeSet<Uri>>>,
13156    },
13157
13158    Running {
13159        adapter: Arc<CachedLspAdapter>,
13160        server: Arc<LanguageServer>,
13161        simulate_disk_based_diagnostics_completion: Option<Task<()>>,
13162        workspace_diagnostics_refresh_tasks: HashMap<Option<String>, WorkspaceRefreshTask>,
13163    },
13164}
13165
13166impl LanguageServerState {
13167    fn add_workspace_folder(&self, uri: Uri) {
13168        match self {
13169            LanguageServerState::Starting {
13170                pending_workspace_folders,
13171                ..
13172            } => {
13173                pending_workspace_folders.lock().insert(uri);
13174            }
13175            LanguageServerState::Running { server, .. } => {
13176                server.add_workspace_folder(uri);
13177            }
13178        }
13179    }
13180    fn _remove_workspace_folder(&self, uri: Uri) {
13181        match self {
13182            LanguageServerState::Starting {
13183                pending_workspace_folders,
13184                ..
13185            } => {
13186                pending_workspace_folders.lock().remove(&uri);
13187            }
13188            LanguageServerState::Running { server, .. } => server.remove_workspace_folder(uri),
13189        }
13190    }
13191}
13192
13193impl std::fmt::Debug for LanguageServerState {
13194    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13195        match self {
13196            LanguageServerState::Starting { .. } => {
13197                f.debug_struct("LanguageServerState::Starting").finish()
13198            }
13199            LanguageServerState::Running { .. } => {
13200                f.debug_struct("LanguageServerState::Running").finish()
13201            }
13202        }
13203    }
13204}
13205
13206#[derive(Clone, Debug, Serialize)]
13207pub struct LanguageServerProgress {
13208    pub is_disk_based_diagnostics_progress: bool,
13209    pub is_cancellable: bool,
13210    pub title: Option<String>,
13211    pub message: Option<String>,
13212    pub percentage: Option<usize>,
13213    #[serde(skip_serializing)]
13214    pub last_update_at: Instant,
13215}
13216
13217#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize)]
13218pub struct DiagnosticSummary {
13219    pub error_count: usize,
13220    pub warning_count: usize,
13221}
13222
13223impl DiagnosticSummary {
13224    pub fn new<'a, T: 'a>(diagnostics: impl IntoIterator<Item = &'a DiagnosticEntry<T>>) -> Self {
13225        let mut this = Self {
13226            error_count: 0,
13227            warning_count: 0,
13228        };
13229
13230        for entry in diagnostics {
13231            if entry.diagnostic.is_primary {
13232                match entry.diagnostic.severity {
13233                    DiagnosticSeverity::ERROR => this.error_count += 1,
13234                    DiagnosticSeverity::WARNING => this.warning_count += 1,
13235                    _ => {}
13236                }
13237            }
13238        }
13239
13240        this
13241    }
13242
13243    pub fn is_empty(&self) -> bool {
13244        self.error_count == 0 && self.warning_count == 0
13245    }
13246
13247    pub fn to_proto(
13248        self,
13249        language_server_id: LanguageServerId,
13250        path: &RelPath,
13251    ) -> proto::DiagnosticSummary {
13252        proto::DiagnosticSummary {
13253            path: path.to_proto(),
13254            language_server_id: language_server_id.0 as u64,
13255            error_count: self.error_count as u32,
13256            warning_count: self.warning_count as u32,
13257        }
13258    }
13259}
13260
13261#[derive(Clone, Debug)]
13262pub enum CompletionDocumentation {
13263    /// There is no documentation for this completion.
13264    Undocumented,
13265    /// A single line of documentation.
13266    SingleLine(SharedString),
13267    /// Multiple lines of plain text documentation.
13268    MultiLinePlainText(SharedString),
13269    /// Markdown documentation.
13270    MultiLineMarkdown(SharedString),
13271    /// Both single line and multiple lines of plain text documentation.
13272    SingleLineAndMultiLinePlainText {
13273        single_line: SharedString,
13274        plain_text: Option<SharedString>,
13275    },
13276}
13277
13278impl CompletionDocumentation {
13279    #[cfg(any(test, feature = "test-support"))]
13280    pub fn text(&self) -> SharedString {
13281        match self {
13282            CompletionDocumentation::Undocumented => "".into(),
13283            CompletionDocumentation::SingleLine(s) => s.clone(),
13284            CompletionDocumentation::MultiLinePlainText(s) => s.clone(),
13285            CompletionDocumentation::MultiLineMarkdown(s) => s.clone(),
13286            CompletionDocumentation::SingleLineAndMultiLinePlainText { single_line, .. } => {
13287                single_line.clone()
13288            }
13289        }
13290    }
13291}
13292
13293impl From<lsp::Documentation> for CompletionDocumentation {
13294    fn from(docs: lsp::Documentation) -> Self {
13295        match docs {
13296            lsp::Documentation::String(text) => {
13297                if text.lines().count() <= 1 {
13298                    CompletionDocumentation::SingleLine(text.into())
13299                } else {
13300                    CompletionDocumentation::MultiLinePlainText(text.into())
13301                }
13302            }
13303
13304            lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
13305                lsp::MarkupKind::PlainText => {
13306                    if value.lines().count() <= 1 {
13307                        CompletionDocumentation::SingleLine(value.into())
13308                    } else {
13309                        CompletionDocumentation::MultiLinePlainText(value.into())
13310                    }
13311                }
13312
13313                lsp::MarkupKind::Markdown => {
13314                    CompletionDocumentation::MultiLineMarkdown(value.into())
13315                }
13316            },
13317        }
13318    }
13319}
13320
13321pub enum ResolvedHint {
13322    Resolved(InlayHint),
13323    Resolving(Shared<Task<()>>),
13324}
13325
13326fn glob_literal_prefix(glob: &Path) -> PathBuf {
13327    glob.components()
13328        .take_while(|component| match component {
13329            path::Component::Normal(part) => !part.to_string_lossy().contains(['*', '?', '{', '}']),
13330            _ => true,
13331        })
13332        .collect()
13333}
13334
13335pub struct SshLspAdapter {
13336    name: LanguageServerName,
13337    binary: LanguageServerBinary,
13338    initialization_options: Option<String>,
13339    code_action_kinds: Option<Vec<CodeActionKind>>,
13340}
13341
13342impl SshLspAdapter {
13343    pub fn new(
13344        name: LanguageServerName,
13345        binary: LanguageServerBinary,
13346        initialization_options: Option<String>,
13347        code_action_kinds: Option<String>,
13348    ) -> Self {
13349        Self {
13350            name,
13351            binary,
13352            initialization_options,
13353            code_action_kinds: code_action_kinds
13354                .as_ref()
13355                .and_then(|c| serde_json::from_str(c).ok()),
13356        }
13357    }
13358}
13359
13360impl LspInstaller for SshLspAdapter {
13361    type BinaryVersion = ();
13362    async fn check_if_user_installed(
13363        &self,
13364        _: &dyn LspAdapterDelegate,
13365        _: Option<Toolchain>,
13366        _: &AsyncApp,
13367    ) -> Option<LanguageServerBinary> {
13368        Some(self.binary.clone())
13369    }
13370
13371    async fn cached_server_binary(
13372        &self,
13373        _: PathBuf,
13374        _: &dyn LspAdapterDelegate,
13375    ) -> Option<LanguageServerBinary> {
13376        None
13377    }
13378
13379    async fn fetch_latest_server_version(
13380        &self,
13381        _: &dyn LspAdapterDelegate,
13382        _: bool,
13383        _: &mut AsyncApp,
13384    ) -> Result<()> {
13385        anyhow::bail!("SshLspAdapter does not support fetch_latest_server_version")
13386    }
13387
13388    async fn fetch_server_binary(
13389        &self,
13390        _: (),
13391        _: PathBuf,
13392        _: &dyn LspAdapterDelegate,
13393    ) -> Result<LanguageServerBinary> {
13394        anyhow::bail!("SshLspAdapter does not support fetch_server_binary")
13395    }
13396}
13397
13398#[async_trait(?Send)]
13399impl LspAdapter for SshLspAdapter {
13400    fn name(&self) -> LanguageServerName {
13401        self.name.clone()
13402    }
13403
13404    async fn initialization_options(
13405        self: Arc<Self>,
13406        _: &Arc<dyn LspAdapterDelegate>,
13407    ) -> Result<Option<serde_json::Value>> {
13408        let Some(options) = &self.initialization_options else {
13409            return Ok(None);
13410        };
13411        let result = serde_json::from_str(options)?;
13412        Ok(result)
13413    }
13414
13415    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
13416        self.code_action_kinds.clone()
13417    }
13418}
13419
13420pub fn language_server_settings<'a>(
13421    delegate: &'a dyn LspAdapterDelegate,
13422    language: &LanguageServerName,
13423    cx: &'a App,
13424) -> Option<&'a LspSettings> {
13425    language_server_settings_for(
13426        SettingsLocation {
13427            worktree_id: delegate.worktree_id(),
13428            path: RelPath::empty(),
13429        },
13430        language,
13431        cx,
13432    )
13433}
13434
13435pub(crate) fn language_server_settings_for<'a>(
13436    location: SettingsLocation<'a>,
13437    language: &LanguageServerName,
13438    cx: &'a App,
13439) -> Option<&'a LspSettings> {
13440    ProjectSettings::get(Some(location), cx).lsp.get(language)
13441}
13442
13443pub struct LocalLspAdapterDelegate {
13444    lsp_store: WeakEntity<LspStore>,
13445    worktree: worktree::Snapshot,
13446    fs: Arc<dyn Fs>,
13447    http_client: Arc<dyn HttpClient>,
13448    language_registry: Arc<LanguageRegistry>,
13449    load_shell_env_task: Shared<Task<Option<HashMap<String, String>>>>,
13450}
13451
13452impl LocalLspAdapterDelegate {
13453    pub fn new(
13454        language_registry: Arc<LanguageRegistry>,
13455        environment: &Entity<ProjectEnvironment>,
13456        lsp_store: WeakEntity<LspStore>,
13457        worktree: &Entity<Worktree>,
13458        http_client: Arc<dyn HttpClient>,
13459        fs: Arc<dyn Fs>,
13460        cx: &mut App,
13461    ) -> Arc<Self> {
13462        let load_shell_env_task =
13463            environment.update(cx, |env, cx| env.worktree_environment(worktree.clone(), cx));
13464
13465        Arc::new(Self {
13466            lsp_store,
13467            worktree: worktree.read(cx).snapshot(),
13468            fs,
13469            http_client,
13470            language_registry,
13471            load_shell_env_task,
13472        })
13473    }
13474
13475    fn from_local_lsp(
13476        local: &LocalLspStore,
13477        worktree: &Entity<Worktree>,
13478        cx: &mut App,
13479    ) -> Arc<Self> {
13480        Self::new(
13481            local.languages.clone(),
13482            &local.environment,
13483            local.weak.clone(),
13484            worktree,
13485            local.http_client.clone(),
13486            local.fs.clone(),
13487            cx,
13488        )
13489    }
13490}
13491
13492#[async_trait]
13493impl LspAdapterDelegate for LocalLspAdapterDelegate {
13494    fn show_notification(&self, message: &str, cx: &mut App) {
13495        self.lsp_store
13496            .update(cx, |_, cx| {
13497                cx.emit(LspStoreEvent::Notification(message.to_owned()))
13498            })
13499            .ok();
13500    }
13501
13502    fn http_client(&self) -> Arc<dyn HttpClient> {
13503        self.http_client.clone()
13504    }
13505
13506    fn worktree_id(&self) -> WorktreeId {
13507        self.worktree.id()
13508    }
13509
13510    fn worktree_root_path(&self) -> &Path {
13511        self.worktree.abs_path().as_ref()
13512    }
13513
13514    async fn shell_env(&self) -> HashMap<String, String> {
13515        let task = self.load_shell_env_task.clone();
13516        task.await.unwrap_or_default()
13517    }
13518
13519    async fn npm_package_installed_version(
13520        &self,
13521        package_name: &str,
13522    ) -> Result<Option<(PathBuf, String)>> {
13523        let local_package_directory = self.worktree_root_path();
13524        let node_modules_directory = local_package_directory.join("node_modules");
13525
13526        if let Some(version) =
13527            read_package_installed_version(node_modules_directory.clone(), package_name).await?
13528        {
13529            return Ok(Some((node_modules_directory, version)));
13530        }
13531        let Some(npm) = self.which("npm".as_ref()).await else {
13532            log::warn!(
13533                "Failed to find npm executable for {:?}",
13534                local_package_directory
13535            );
13536            return Ok(None);
13537        };
13538
13539        let env = self.shell_env().await;
13540        let output = util::command::new_smol_command(&npm)
13541            .args(["root", "-g"])
13542            .envs(env)
13543            .current_dir(local_package_directory)
13544            .output()
13545            .await?;
13546        let global_node_modules =
13547            PathBuf::from(String::from_utf8_lossy(&output.stdout).to_string());
13548
13549        if let Some(version) =
13550            read_package_installed_version(global_node_modules.clone(), package_name).await?
13551        {
13552            return Ok(Some((global_node_modules, version)));
13553        }
13554        return Ok(None);
13555    }
13556
13557    async fn which(&self, command: &OsStr) -> Option<PathBuf> {
13558        let mut worktree_abs_path = self.worktree_root_path().to_path_buf();
13559        if self.fs.is_file(&worktree_abs_path).await {
13560            worktree_abs_path.pop();
13561        }
13562
13563        let env = self.shell_env().await;
13564
13565        let shell_path = env.get("PATH").cloned();
13566
13567        which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok()
13568    }
13569
13570    async fn try_exec(&self, command: LanguageServerBinary) -> Result<()> {
13571        let mut working_dir = self.worktree_root_path().to_path_buf();
13572        if self.fs.is_file(&working_dir).await {
13573            working_dir.pop();
13574        }
13575        let output = util::command::new_smol_command(&command.path)
13576            .args(command.arguments)
13577            .envs(command.env.clone().unwrap_or_default())
13578            .current_dir(working_dir)
13579            .output()
13580            .await?;
13581
13582        anyhow::ensure!(
13583            output.status.success(),
13584            "{}, stdout: {:?}, stderr: {:?}",
13585            output.status,
13586            String::from_utf8_lossy(&output.stdout),
13587            String::from_utf8_lossy(&output.stderr)
13588        );
13589        Ok(())
13590    }
13591
13592    fn update_status(&self, server_name: LanguageServerName, status: language::BinaryStatus) {
13593        self.language_registry
13594            .update_lsp_binary_status(server_name, status);
13595    }
13596
13597    fn registered_lsp_adapters(&self) -> Vec<Arc<dyn LspAdapter>> {
13598        self.language_registry
13599            .all_lsp_adapters()
13600            .into_iter()
13601            .map(|adapter| adapter.adapter.clone() as Arc<dyn LspAdapter>)
13602            .collect()
13603    }
13604
13605    async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>> {
13606        let dir = self.language_registry.language_server_download_dir(name)?;
13607
13608        if !dir.exists() {
13609            smol::fs::create_dir_all(&dir)
13610                .await
13611                .context("failed to create container directory")
13612                .log_err()?;
13613        }
13614
13615        Some(dir)
13616    }
13617
13618    async fn read_text_file(&self, path: &RelPath) -> Result<String> {
13619        let entry = self
13620            .worktree
13621            .entry_for_path(path)
13622            .with_context(|| format!("no worktree entry for path {path:?}"))?;
13623        let abs_path = self.worktree.absolutize(&entry.path);
13624        self.fs.load(&abs_path).await
13625    }
13626}
13627
13628async fn populate_labels_for_symbols(
13629    symbols: Vec<CoreSymbol>,
13630    language_registry: &Arc<LanguageRegistry>,
13631    lsp_adapter: Option<Arc<CachedLspAdapter>>,
13632    output: &mut Vec<Symbol>,
13633) {
13634    #[allow(clippy::mutable_key_type)]
13635    let mut symbols_by_language = HashMap::<Option<Arc<Language>>, Vec<CoreSymbol>>::default();
13636
13637    let mut unknown_paths = BTreeSet::<Arc<str>>::new();
13638    for symbol in symbols {
13639        let Some(file_name) = symbol.path.file_name() else {
13640            continue;
13641        };
13642        let language = language_registry
13643            .load_language_for_file_path(Path::new(file_name))
13644            .await
13645            .ok()
13646            .or_else(|| {
13647                unknown_paths.insert(file_name.into());
13648                None
13649            });
13650        symbols_by_language
13651            .entry(language)
13652            .or_default()
13653            .push(symbol);
13654    }
13655
13656    for unknown_path in unknown_paths {
13657        log::info!("no language found for symbol in file {unknown_path:?}");
13658    }
13659
13660    let mut label_params = Vec::new();
13661    for (language, mut symbols) in symbols_by_language {
13662        label_params.clear();
13663        label_params.extend(
13664            symbols
13665                .iter_mut()
13666                .map(|symbol| (mem::take(&mut symbol.name), symbol.kind)),
13667        );
13668
13669        let mut labels = Vec::new();
13670        if let Some(language) = language {
13671            let lsp_adapter = lsp_adapter.clone().or_else(|| {
13672                language_registry
13673                    .lsp_adapters(&language.name())
13674                    .first()
13675                    .cloned()
13676            });
13677            if let Some(lsp_adapter) = lsp_adapter {
13678                labels = lsp_adapter
13679                    .labels_for_symbols(&label_params, &language)
13680                    .await
13681                    .log_err()
13682                    .unwrap_or_default();
13683            }
13684        }
13685
13686        for ((symbol, (name, _)), label) in symbols
13687            .into_iter()
13688            .zip(label_params.drain(..))
13689            .zip(labels.into_iter().chain(iter::repeat(None)))
13690        {
13691            output.push(Symbol {
13692                language_server_name: symbol.language_server_name,
13693                source_worktree_id: symbol.source_worktree_id,
13694                source_language_server_id: symbol.source_language_server_id,
13695                path: symbol.path,
13696                label: label.unwrap_or_else(|| CodeLabel::plain(name.clone(), None)),
13697                name,
13698                kind: symbol.kind,
13699                range: symbol.range,
13700            });
13701        }
13702    }
13703}
13704
13705fn include_text(server: &lsp::LanguageServer) -> Option<bool> {
13706    match server.capabilities().text_document_sync.as_ref()? {
13707        lsp::TextDocumentSyncCapability::Options(opts) => match opts.save.as_ref()? {
13708            // Server wants didSave but didn't specify includeText.
13709            lsp::TextDocumentSyncSaveOptions::Supported(true) => Some(false),
13710            // Server doesn't want didSave at all.
13711            lsp::TextDocumentSyncSaveOptions::Supported(false) => None,
13712            // Server provided SaveOptions.
13713            lsp::TextDocumentSyncSaveOptions::SaveOptions(save_options) => {
13714                Some(save_options.include_text.unwrap_or(false))
13715            }
13716        },
13717        // We do not have any save info. Kind affects didChange only.
13718        lsp::TextDocumentSyncCapability::Kind(_) => None,
13719    }
13720}
13721
13722/// Completion items are displayed in a `UniformList`.
13723/// Usually, those items are single-line strings, but in LSP responses,
13724/// completion items `label`, `detail` and `label_details.description` may contain newlines or long spaces.
13725/// Many language plugins construct these items by joining these parts together, and we may use `CodeLabel::fallback_for_completion` that uses `label` at least.
13726/// 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,
13727/// breaking the completions menu presentation.
13728///
13729/// 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.
13730fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
13731    let mut new_text = String::with_capacity(label.text.len());
13732    let mut offset_map = vec![0; label.text.len() + 1];
13733    let mut last_char_was_space = false;
13734    let mut new_idx = 0;
13735    let chars = label.text.char_indices().fuse();
13736    let mut newlines_removed = false;
13737
13738    for (idx, c) in chars {
13739        offset_map[idx] = new_idx;
13740
13741        match c {
13742            '\n' if last_char_was_space => {
13743                newlines_removed = true;
13744            }
13745            '\t' | ' ' if last_char_was_space => {}
13746            '\n' if !last_char_was_space => {
13747                new_text.push(' ');
13748                new_idx += 1;
13749                last_char_was_space = true;
13750                newlines_removed = true;
13751            }
13752            ' ' | '\t' => {
13753                new_text.push(' ');
13754                new_idx += 1;
13755                last_char_was_space = true;
13756            }
13757            _ => {
13758                new_text.push(c);
13759                new_idx += c.len_utf8();
13760                last_char_was_space = false;
13761            }
13762        }
13763    }
13764    offset_map[label.text.len()] = new_idx;
13765
13766    // Only modify the label if newlines were removed.
13767    if !newlines_removed {
13768        return;
13769    }
13770
13771    let last_index = new_idx;
13772    let mut run_ranges_errors = Vec::new();
13773    label.runs.retain_mut(|(range, _)| {
13774        match offset_map.get(range.start) {
13775            Some(&start) => range.start = start,
13776            None => {
13777                run_ranges_errors.push(range.clone());
13778                return false;
13779            }
13780        }
13781
13782        match offset_map.get(range.end) {
13783            Some(&end) => range.end = end,
13784            None => {
13785                run_ranges_errors.push(range.clone());
13786                range.end = last_index;
13787            }
13788        }
13789        true
13790    });
13791    if !run_ranges_errors.is_empty() {
13792        log::error!(
13793            "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
13794            label.text
13795        );
13796    }
13797
13798    let mut wrong_filter_range = None;
13799    if label.filter_range == (0..label.text.len()) {
13800        label.filter_range = 0..new_text.len();
13801    } else {
13802        let mut original_filter_range = Some(label.filter_range.clone());
13803        match offset_map.get(label.filter_range.start) {
13804            Some(&start) => label.filter_range.start = start,
13805            None => {
13806                wrong_filter_range = original_filter_range.take();
13807                label.filter_range.start = last_index;
13808            }
13809        }
13810
13811        match offset_map.get(label.filter_range.end) {
13812            Some(&end) => label.filter_range.end = end,
13813            None => {
13814                wrong_filter_range = original_filter_range.take();
13815                label.filter_range.end = last_index;
13816            }
13817        }
13818    }
13819    if let Some(wrong_filter_range) = wrong_filter_range {
13820        log::error!(
13821            "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
13822            label.text
13823        );
13824    }
13825
13826    label.text = new_text;
13827}
13828
13829#[cfg(test)]
13830mod tests {
13831    use language::HighlightId;
13832
13833    use super::*;
13834
13835    #[test]
13836    fn test_glob_literal_prefix() {
13837        assert_eq!(glob_literal_prefix(Path::new("**/*.js")), Path::new(""));
13838        assert_eq!(
13839            glob_literal_prefix(Path::new("node_modules/**/*.js")),
13840            Path::new("node_modules")
13841        );
13842        assert_eq!(
13843            glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13844            Path::new("foo")
13845        );
13846        assert_eq!(
13847            glob_literal_prefix(Path::new("foo/bar/baz.js")),
13848            Path::new("foo/bar/baz.js")
13849        );
13850
13851        #[cfg(target_os = "windows")]
13852        {
13853            assert_eq!(glob_literal_prefix(Path::new("**\\*.js")), Path::new(""));
13854            assert_eq!(
13855                glob_literal_prefix(Path::new("node_modules\\**/*.js")),
13856                Path::new("node_modules")
13857            );
13858            assert_eq!(
13859                glob_literal_prefix(Path::new("foo/{bar,baz}.js")),
13860                Path::new("foo")
13861            );
13862            assert_eq!(
13863                glob_literal_prefix(Path::new("foo\\bar\\baz.js")),
13864                Path::new("foo/bar/baz.js")
13865            );
13866        }
13867    }
13868
13869    #[test]
13870    fn test_multi_len_chars_normalization() {
13871        let mut label = CodeLabel::new(
13872            "myElˇ (parameter) myElˇ: {\n    foo: string;\n}".to_string(),
13873            0..6,
13874            vec![(0..6, HighlightId(1))],
13875        );
13876        ensure_uniform_list_compatible_label(&mut label);
13877        assert_eq!(
13878            label,
13879            CodeLabel::new(
13880                "myElˇ (parameter) myElˇ: { foo: string; }".to_string(),
13881                0..6,
13882                vec![(0..6, HighlightId(1))],
13883            )
13884        );
13885    }
13886}